Vue高仿饿了吗学习笔记

VUE高仿饿了么app

本项目github地址:https://github.com/motysla/eleme.git

VUE 搭建简介

刚学习了VUE高仿饿了么app课,记录课的要点,巩固知识。

VUE 优势

Vue.js 是一个用于创建 web 交互界面的。其特点是


    
    
  1. 简洁 HTML 模板 + JSON 数据,再创建一个 Vue 实例,就这么简单。
  2. 数据驱动 自动追踪依赖的模板表达式和计算属性。
  3. 组件化 用解耦、可复用的组件来构造界面。
  4. 轻量 ~24kb min+gzip,无依赖。
  5. 快速 精确有效的异步批量 DOM 更新。
  6. 模块友好 通过 NPM 或 Bower 安装,无缝融入你的工作流。

VUE 搭建工具

借用express + data 构建拟后台


    
    
  1. vue 1 . 0
  2. express
  3. vue .router
  4. vue .rescrouse
  5. better-scroll
  6. less

CSS 使用的要点

1像素边框制作

设备上像素 = 样式像素 * 设备缩放比例


    
    
  1. 屏幕宽度 320 px 480 px 640 px
  2. 缩放比例 1 1 .5 2

当样式像素一定时,因手机有320px,640px等.各自的缩放比差异,所以设备显示像素就会有1Npx,2Npx.为保设计稿还原度,解决就是用media + scale.


    
    
  1. .border(@borderColor){
  2. position: relative;
  3. &::after{
  4. content: "";
  5. position: absolute;
  6. bottom: 0;
  7. left: 0;
  8. width: 100%;
  9. border-top: 1px solid @borderColor;
  10. }
  11. }
  12. @media (min-device-pixel-ratio: 1.5) {
  13. .border{
  14. &::after{
  15. transform: scaleY(0.7);
  16. }
  17. }
  18. }
  19. @media (min-device-pixel-ratio: 2) {
  20. .border{
  21. &::after{
  22. transform: scaleY(0.5);
  23. }
  24. }
  25. }

通过查询它的缩放比,在媒体宽为1.5倍时, round(1px 1.5 / 0.7) = 1px 在媒体宽为2倍时, round(1px 2 / 0.5) = 1px.

自适应宽

在商品路由中,导航宽度固定80px的,因为手机分辨率大小不一,所以食物详情自适应.解决就是flex布局.


css


    
    
  1. <style type="text/less">
  2. .food {
  3. display: flex ;
  4. width: 100% ;
  5. .nav{
  6. flex : 0 0 80px ;
  7. width: 80px ;
  8. }
  9. .foodList {
  10. flex: 1 ;
  11. }
  12. }
  13. </style>

html


    
    
  1. <div class= "food">
  2. <section class= "nav"></section>
  3. <section class= "foodList"></section>
  4. </div>

在父元素设弹性布局,导航里设弹性为0,定宽为80px.商品食物详情弹性为1.就适应宽度变化.

Sticky footer

做商家弹出页时,信息高度是无法预定的,有可能溢出window高度,也可能少于window高度,但底部按钮,当信息高度少于window高度,要固定在底部40px.解决就是用sticky footer布局


css


    
    
  1. <style type="text/less">
  2. .showDetil {
  3. position: absolute ;
  4. width: 100% ;
  5. height: 100% ;
  6. .sellerDetil{
  7. width : 100% ;
  8. min-height: 100% ;
  9. padding-bottom: 40px ;
  10. }
  11. .btn {
  12. position: relative ;
  13. top: -40px ;
  14. height: 40px ;
  15. }
  16. }
  17. </style>

html


    
    
  1. <div class= "showDetil">
  2. <section class= "sellerDetil"></section>
  3. <section class= "btn"></section>
  4. </div>

父元素高相同window高,信息最小高就相同window高,按钮这时就溢出了.
再设置底的填充,底内边距高就是按钮的高. 按钮在用相对定位,定在信息的底填充里.
因信息最少高度是100%,所按钮要不钉在底部了.要不溢出.

自适相等宽高

在食物弹出页.设计图食物图的宽高是相等,每张图的宽高比例有可能有区别,但也要做自适应.解决就是用padding边距.


css


    
    
  1. <style type="text/less">
  2. .imgs {
  3. width: 100% ;
  4. height: 0 ;
  5. position: relative ;
  6. padding-top: 100% ;
  7. .image{
  8. position : absolute ;
  9. top: 0 ;
  10. width: 100% ;
  11. height: 100% ;
  12. left: 0 ;
  13. }
  14. }
  15. </style>

html


    
    
  1. <div class= "imgs">
  2. <img src= "..." class= "image">
  3. </div>

在父元素,边距的长是取决去宽的,所其宽度与边距的长是相等的.
在把高设为0,宽为100%,上边距100%,上边据就盒子的高.盒子是为正形.
子元素设宽与高为100%,那也是正形.

VUE要点

小图标的编选

根据后台输出的数据,判定显示那个的图标.这vue典型的数据.驱动.解决是使用:class困绑数据


html


    
    
  1. <template>
  2. <ul>
  3. <li v-for="date in goods">
  4. <span :class="classmap[date.type]"> </span>
  5. </li>
  6. </ul>
  7. </template>

js


    
    
  1. <script type="text/javascript">
  2. export default {
  3. data() {
  4. return {
  5. classmap: [ 'decrease' , 'discount' , 'guarantee' , 'invoice' , 'special' ]
  6. };
  7. }
  8. }
  9. </script>

css


    
    
  1. <style type="text/less">
  2. .bgimg ( @imgs) {
  3. background-image : url (' @imgs+".png"') 0 0 no-repeat ~'/' 100% 100% ;
  4. }
  5. .decrease {
  6. display: inline-block ;
  7. height: 12px ;
  8. width: 12px ;
  9. .bgimg('decrease_3');
  10. }
  11. .discount{
  12. display : inline-block ;
  13. height: 12px ;
  14. width: 12px ;
  15. .bgimg('discount_3');
  16. }
  17. .guarantee{
  18. display : inline-block ;
  19. height: 12px ;
  20. width: 12px ;
  21. .bgimg('guarantee_3');
  22. }
  23. .invoice{
  24. display : inline-block ;
  25. height: 12px ;
  26. width: 12px ;
  27. .bgimg('invoice_3');
  28. }
  29. .special{
  30. display : inline-block ;
  31. height: 12px ;
  32. width: 12px ;
  33. .bgimg('special_3');
  34. }
  35. </style>

通过v-for,遍历数据,所以date.type得到数据并判断类型.然后通classmap数组判定绑那个class.来加图标.

小球动画

点击加食物时,触动小球弹出的动画,小球的落点是在车的中央.但起点是根各个节点位子而又差别的.解决使用transitions + events + dispatch事件冒泡

cartcontrol子组件


html


    
    
  1. <template>
  2. <div class="cartcontrol">
  3. <section class="cart-decrease" @click.stop.prevent="decreaseCart" v-show="food.count > 0" transition="move"> </section>
  4. <section class="cart-count" v-show="food.count > 0">{{food.count}} </section>
  5. <section class="cart-add" @click.stop.prevent="addCart"> </section>
  6. </div>
  7. </template>

js


    
    
  1. <script type="text/javascript">
  2. export default {
  3. props: {
  4. food: {
  5. type: Object
  6. }
  7. },
  8. methods: {
  9. addCart(event) {
  10. if (! this .food.count) {
  11. Vue.set( this .food, 'count' , 1 );
  12. this .food.count = 1 ;
  13. } else {
  14. this .food.count++;
  15. };
  16. this .$dispatch( 'cart.add' , event.target);
  17. },
  18. decreaseCart() {
  19. if ( this .food.count) {
  20. this .food.count--;
  21. };
  22. }
  23. }
  24. };
  25. </script>

在加食物,触发了addCart事件,设用set方法给数据加属性,并使cart.add事件冒泡出去,event.target作为事件参数,即节点冒泡出去.

goods父组件


html


    
    
  1. <template>
  2. <shop v-ref:shop :delivery-price="seller.deliveryPrice" :min-price="seller.minPrice" :select-foods="selectFoods"></shop>
  3. </template>

js


    
    
  1. <script>
  2. export default {
  3. methods: {
  4. _drop(target) {
  5. this .$refs.shop.drop(target);
  6. }
  7. },
  8. events: {
  9. 'cart.add' (target) {
  10. this ._drop(target);
  11. }
  12. },
  13. components: {
  14. shop,
  15. cartcontrol,
  16. food
  17. }
  18. };
  19. </script>

在冒泡被events钩子监听,与触动_drop方法,通过接口获得购物车组建的事件,就把control组建event.target传入购物车组建的事件,及把control节点传入了shop组建.

shop组建


html


    
    
  1. <template>
  2. <div class="shopcart">
  3. <section class="ball-container">
  4. <div transition="drop" v-for="ball in balls" v-show="ball.show" class="ball">
  5. <div class="inner inner-hook"> </div>
  6. </div>
  7. </section>
  8. </div>
  9. </template>

js


    
    
  1. <script type= "text/javascript" >
  2. export default {
  3. data() {
  4. return {
  5. balls : [
  6. {
  7. show : false
  8. },
  9. {
  10. show : false
  11. },
  12. {
  13. show : false
  14. },
  15. {
  16. show : false
  17. },
  18. {
  19. show : false
  20. }],
  21. dropBalls : [],
  22. fold : true
  23. };
  24. },
  25. methods : {
  26. drop(el) {
  27. for ( var i = 0 ; i < this .balls.length; i++) {
  28. let ball = this .balls[i];
  29. if (!ball.show) {
  30. ball.show = true ;
  31. ball.el = el;
  32. this .dropBalls.push(ball);
  33. return ;
  34. };
  35. };
  36. }
  37. },
  38. transitions : {
  39. drop : {
  40. beforeEnter(el) {
  41. let count = this .balls.length;
  42. while (count--) {
  43. let ball = this .balls[count];
  44. if (ball.show) {
  45. let rect = ball.el.getBoundingClientRect();
  46. let x = rect.left - 32 ;
  47. let y = -( window .innerHeight - rect.top - 22 );
  48. el.style.display = '' ;
  49. el.style.transform = ` translate3d(0,${y}px,0) `;
  50. let inner = el.getElementsByClassName( 'inner-hook' )[ 0 ];
  51. inner.style.transform = ` translate3d(${x}px,0,0) `;
  52. }
  53. }
  54. },
  55. enter(el) {
  56. let rf = el.offsetHeight;
  57. this .$nextTick( () => {
  58. el.style.transform = 'translate3d(0,0,0)' ;
  59. let inner = el.getElementsByClassName( 'inner-hook' )[ 0 ];
  60. inner.style.transform = 'translate3d(0,0,0)' ;
  61. });
  62. },
  63. afterEnter(el) {
  64. let ball = this .dropBalls.shift();
  65. if (ball) {
  66. ball.show = false ;
  67. el.style.display = 'none' ;
  68. };
  69. }
  70. }
  71. },
  72. components : {
  73. cartcontrol
  74. }
  75. };
  76. </script>

传入节点数据,过渡执行前可插入一个beforeEnter事件,通getBoundingClientRect定位.动画执行后可插入一个afterEnter,还原小球

接后台数据

与后台的配合,通过插vue.resource + express 连接得到数据

dev-server


    
    
  1. <script type="text/javascript">
  2. import express from 'express' ;
  3. var app = express();
  4. var appData = require ( '../data.json' );
  5. var seller = appData.seller;
  6. var goods = appData.goods;
  7. var ratings = appData.ratings;
  8. var apiRoutes = express.Router();
  9. apiRoutes.get( '/seller' , function (req, res) {
  10. res.json({
  11. errno: 0 ,
  12. data: seller
  13. });
  14. });
  15. apiRoutes.get( '/goods' , function (req, res) {
  16. res.json({
  17. errno: 0 ,
  18. data: goods
  19. });
  20. });
  21. apiRoutes.get( '/ratings' , function (req, res) {
  22. res.json({
  23. errno: 0 ,
  24. data: ratings
  25. });
  26. });
  27. app.use( '/api' , apiRoutes);
  28. </script>

通过与配和框架express,连到数据。并放在api里.

main.js


    
    
  1. import VueResource from 'vue-resource';
  2. Vue.use('VueResource');

引进插件和使用,在全局也可以使用.

header组建


    
    
  1. <script type= "text/javascript" >
  2. export default {
  3. created() {
  4. this .$http.get( '/api/ratings' ). then ( (response) => {
  5. var response = response.body;
  6. if (response.errno === 0 ) {
  7. this .ratings = response.data;
  8. };
  9. });
  10. }
  11. }
  12. </script>

在框架的钩子,及创建就通过http.get连到express发的数据,通参数response得到.body表示数据以json格式响应.注意接收数据是异步实现,如果出报错undefined,可用v-if判断,当获取数据后在渲染.

评分类换

用户的满意度有,推荐与吐槽再加上全部,就三个分页,分页通过按钮切换.如何制作呢?解决是使用v-show进判断.

ratingselect子组件


html


    
    
  1. <template>
  2. <div class= "ratingselect">
  3. <div class= "rating-type">
  4. <span @click= "select(2, $event)"</span></span> <span class="hljs-keyword" style="font-weight:bold;"><span class="hljs-keyword">class</span></span>=<span class="hljs-string" style="color:rgb(221,17,68);"><span class="hljs-string">"block positive"</span></span> :<span class="hljs-keyword" style="font-weight:bold;"><span class="hljs-keyword">class</span></span>=<span class="hljs-string" style="color:rgb(221,17,68);"><span class="hljs-string">"{'active':selectType === 2}"</span></span>&gt;{{desc.all}}&lt;span <span class="hljs-keyword" style="font-weight:bold;"><span class="hljs-keyword">class</span></span>=<span class="hljs-string" style="color:rgb(221,17,68);"><span class="hljs-string">"count"</span></span>&gt;{{ratings.length}}&lt;/span&gt;&lt;/span&gt;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> &lt;span @click=<span class="hljs-string" style="color:rgb(221,17,68);"><span class="hljs-string">"select(0, $event)" class= "block positive" : class= "{'active':selectType === 0}">{{desc.positive}}<span class= "count">{{positives.length}}</span></span>
  5. <span @click= "select(1, $event)" class= "block negative" : class= "{'active':selectType === 1}">{{desc.negative}}<span class= "count">{{negatives.length}}</span></span>
  6. </div>
  7. <div @click= "toggleContent" class= "switch" : class= "{'on':onlyContent}">
  8. <span class= "iconfont arre">& #xe905;</span>
  9. <span class= "text">只看有内容的评价</span>
  10. </div>
  11. </div>
  12. </template>

js


    
    
  1. <script type="text/javascript">
  2. export default {
  3. props: {
  4. ratings: {
  5. type: Array ,
  6. default () {
  7. return [];
  8. }
  9. },
  10. selectType: {
  11. type: Number ,
  12. default : 2
  13. },
  14. onlyContent: {
  15. type: Boolean ,
  16. default : true
  17. },
  18. desc: {
  19. type: Object ,
  20. default () {
  21. return {
  22. all: '全部' ,
  23. positive: '满意' ,
  24. negative: '不满意'
  25. };
  26. }
  27. }
  28. },
  29. methods: {
  30. select(type) {
  31. this .selectType = type;
  32. this .$dispatch(</span><span class="hljs-string" style="color:rgb(221,17,68);"><span class="javascript"><span class="hljs-string">'ratingtype.select'</span></span></span><span class="javascript">, type);</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="33"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> },</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="34"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> toggleContent() {</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="35"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.onlyContent = !</span><span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.onlyContent;</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="36"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.$dispatch( 'ratingtype.toggleContent' , this .onlyContent);
  33. }
  34. }
  35. };
  36. </script>

满意是为:0,不满意是为:1,全部是为:2.
    
    

因在点击切换按钮,触发方法,通过传入参数来替换数据,数据selectType赋值等于参数.参数是自义定,然而可以在参数下功夫,然用冒泡将数据分出.

food父组件
html


    
    
  1. <template>
  2. <transiton>
  3. <div class="rating">
  4. <h4 class="title">商品评价 </h4>
  5. <ratingselect :select-type="selectType" :only-content="onlyContent" :desc="desc" :ratings="food.ratings"> </ratingselect>
  6. <div class="rating-wrapper">
  7. <ul v-show="food.ratings && food.ratings.length">
  8. <li v-for="rating in food.ratings" v-show="needShow(rating.rateType,rating.text)" class="rating-item">
  9. <div class="user">
  10. <span class="name">{{rating.username}} </span>
  11. <img class="avatar" width="12" height="12" :src="rating.avatar">
  12. </div>
  13. <div class="time">{{rating.rateTime | formatDate}} </div>
  14. <p class="text">
  15. <span v-if="rating.rateType === 0" class="arrowUp iconfont">&#xe901; </span>
  16. <span v-if="rating.rateType === 1" class="arrowDown iconfont">&#xe902; </span>{{rating.text}}
  17. </p>
  18. </li>
  19. </ul>
  20. <div class="no-rating" v-show="!food.ratings || !food.ratings.length">暂无评价 </div>
  21. </div>
  22. </div>
  23. </transiton>
  24. </template>

js


    
    
  1. <script type= "text/javascript" >
  2. import Vue from 'vue' ;
  3. import ratingselect from 'components/ratings/ratingselect' ;
  4. const POSITIVE = 0 ;
  5. const NEGATIVE = 1 ;
  6. const ALL = 2 ;
  7. export default {
  8. data() {
  9. return {
  10. showFlage : false ,
  11. selectType : ALL,
  12. onlyContent : true ,
  13. desc : {
  14. all : '全部' ,
  15. positive : '推荐' ,
  16. negative : '吐槽'
  17. }
  18. };
  19. },
  20. methods : {
  21. needShow(type, text) {
  22. if ( this .onlyContent && !text) {
  23. return false ;
  24. }
  25. if ( this .selectType === ALL) {
  26. return true ;
  27. } else {
  28. return type === this .selectType;
  29. }
  30. }
  31. },
  32. events : {
  33. 'ratingtype.select' (type) {
  34. this .selectType = type;
  35. this .$nextTick(</span><span class="hljs-function"><span class="hljs-params" style="color:rgb(153,0,0);font-weight:bold;"><span class="javascript"><span class="hljs-function"><span class="hljs-params">()</span></span></span></span><span class="javascript"><span class="hljs-function"> =&gt;</span></span></span><span class="javascript"> {</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="39"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.scroll.refresh();</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="40"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> });</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="41"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> },</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="42"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-string" style="color:rgb(221,17,68);"><span class="javascript"><span class="hljs-string">'ratingtype.toggleContent'</span></span></span><span class="javascript">(onlyContent) {</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="43"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.onlyContent = onlyContent;</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="44"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.$nextTick( () => {
  36. this .scroll.refresh();
  37. });
  38. }
  39. },
  40. components : {
  41. ratingselect
  42. }
  43. };
  44. </script>

在事件钩子上,实行监听,把冒泡触发并赋值,数据就得到.在遍历数据,用v-show进行判断.

VUE杂项

过渡流程

只在v-if,v-show,v-for触动节点的变动效果

当 show 属性改变时,Vue.js 将相应地插入或删除元素,按照如下规则改变过渡的 CSS 类名:

如果 show 变为 false,Vue.js 将:

调用 beforeLeave 钩子;
添加 v-leave 类名到元素上以触发过渡;
调用 leave 钩子;
等待过渡结束(监听 transitionend 事件);
从 DOM 中删除元素并删除 v-leave 类名;
调用 afterLeave 钩子。
如果 show 变为 true,Vue.js 将:

调用 beforeEnter 钩子;
添加 v-enter 类名到元素上;
把它插入 DOM;
调用 enter 钩子;
强制一次 CSS 布局,让 v-enter 确实生效。然后删除 v-enter 类名,以触发过渡,回到元素的原始状态;
等待过渡结束;
调用 afterEnter 钩子。

better-scroll

节点溢满时,是设计稿没有滚动条的,要上下移动.解决使用better-scroll插件.


html


    
    
  1. <div class= "sellerx" v-el:seller style= "overflow: hidden;">
  2. <div class= "seller-content"></div>
  3. </div>

js


    
    
  1. <script type="text/javascript">
  2. ready() {
  3. this .$nextTick(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">if</span></span></span><span class="javascript"> (!</span><span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.scroll) {</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.scroll = </span><span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">new</span></span></span><span class="javascript"> Bscroll(</span><span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.$els.seller, {
  4. click: true
  5. });
  6. } else {
  7. this .scroll.refresh();
  8. }
  9. });
  10. },
  11. </script>

但父元素设置溢出隐藏,可用插件的移动显出子节点超的内容.要在节点放个接口,使用框架钩子,创建betterScroll事例,那藏的内容通立体相上下移.better-scroll是调用样式的translate是子节点上下引动.

less样式处理

通过引入样式,有是会错误.解决使用设置标签

<style type="text/less"></style>
    
    

处理器会识别到标签的样式类别,编译样式.

esLint

在使用eslint语法校验时,经常报错,但可以在eslintrc设置进行忽略.

no mixed spaces and tabs

是把标签缩进与空格捆和使用,解决是可用tab代替空格.

Expected indentation of 2 space characters but found 3 indent

‘indent’: 0,
‘space-before-function-paren’: 0
设置缩进空行.

defined but never use

可在前加注销
/ eslint-disable no-unused-vars /

后序

要灵活的用vue,先要处理好数据的逻辑. 然而要懂得基本的数据传递属性.


    
    
  1. 子组件传给父组件-
  2. 可以用接口 ref;也可以子组件的冒泡把数据传去,父组件用钩子events监听并接到数据.
  3. 父组件传给子组件-
  4. 可以在子组件props钩子,接收父组件的传递.也可以父组件用 ref接口调用子组件的方法,并把数据传入方法去.

实战是最重要.

VUE高仿饿了么app

本项目github地址:https://github.com/motysla/eleme.git

VUE 搭建简介

刚学习了VUE高仿饿了么app课,记录课的要点,巩固知识。

VUE 优势

Vue.js 是一个用于创建 web 交互界面的。其特点是


  
  
  1. 简洁 HTML 模板 + JSON 数据,再创建一个 Vue 实例,就这么简单。
  2. 数据驱动 自动追踪依赖的模板表达式和计算属性。
  3. 组件化 用解耦、可复用的组件来构造界面。
  4. 轻量 ~24kb min+gzip,无依赖。
  5. 快速 精确有效的异步批量 DOM 更新。
  6. 模块友好 通过 NPM 或 Bower 安装,无缝融入你的工作流。

VUE 搭建工具

借用express + data 构建拟后台


  
  
  1. vue 1 . 0
  2. express
  3. vue .router
  4. vue .rescrouse
  5. better-scroll
  6. less

CSS 使用的要点

1像素边框制作

设备上像素 = 样式像素 * 设备缩放比例


  
  
  1. 屏幕宽度 320 px 480 px 640 px
  2. 缩放比例 1 1 .5 2

当样式像素一定时,因手机有320px,640px等.各自的缩放比差异,所以设备显示像素就会有1Npx,2Npx.为保设计稿还原度,解决就是用media + scale.


  
  
  1. .border(@borderColor){
  2. position: relative;
  3. &::after{
  4. content: "";
  5. position: absolute;
  6. bottom: 0;
  7. left: 0;
  8. width: 100%;
  9. border-top: 1px solid @borderColor;
  10. }
  11. }
  12. @media (min-device-pixel-ratio: 1.5) {
  13. .border{
  14. &::after{
  15. transform: scaleY(0.7);
  16. }
  17. }
  18. }
  19. @media (min-device-pixel-ratio: 2) {
  20. .border{
  21. &::after{
  22. transform: scaleY(0.5);
  23. }
  24. }
  25. }

通过查询它的缩放比,在媒体宽为1.5倍时, round(1px 1.5 / 0.7) = 1px 在媒体宽为2倍时, round(1px 2 / 0.5) = 1px.

自适应宽

在商品路由中,导航宽度固定80px的,因为手机分辨率大小不一,所以食物详情自适应.解决就是flex布局.


css


  
  
  1. <style type="text/less">
  2. .food {
  3. display: flex ;
  4. width: 100% ;
  5. .nav{
  6. flex : 0 0 80px ;
  7. width: 80px ;
  8. }
  9. .foodList {
  10. flex: 1 ;
  11. }
  12. }
  13. </style>

html


  
  
  1. <div class= "food">
  2. <section class= "nav"></section>
  3. <section class= "foodList"></section>
  4. </div>

在父元素设弹性布局,导航里设弹性为0,定宽为80px.商品食物详情弹性为1.就适应宽度变化.

Sticky footer

做商家弹出页时,信息高度是无法预定的,有可能溢出window高度,也可能少于window高度,但底部按钮,当信息高度少于window高度,要固定在底部40px.解决就是用sticky footer布局


css


  
  
  1. <style type="text/less">
  2. .showDetil {
  3. position: absolute ;
  4. width: 100% ;
  5. height: 100% ;
  6. .sellerDetil{
  7. width : 100% ;
  8. min-height: 100% ;
  9. padding-bottom: 40px ;
  10. }
  11. .btn {
  12. position: relative ;
  13. top: -40px ;
  14. height: 40px ;
  15. }
  16. }
  17. </style>

html


  
  
  1. <div class= "showDetil">
  2. <section class= "sellerDetil"></section>
  3. <section class= "btn"></section>
  4. </div>

父元素高相同window高,信息最小高就相同window高,按钮这时就溢出了.
再设置底的填充,底内边距高就是按钮的高. 按钮在用相对定位,定在信息的底填充里.
因信息最少高度是100%,所按钮要不钉在底部了.要不溢出.

自适相等宽高

在食物弹出页.设计图食物图的宽高是相等,每张图的宽高比例有可能有区别,但也要做自适应.解决就是用padding边距.


css


  
  
  1. <style type="text/less">
  2. .imgs {
  3. width: 100% ;
  4. height: 0 ;
  5. position: relative ;
  6. padding-top: 100% ;
  7. .image{
  8. position : absolute ;
  9. top: 0 ;
  10. width: 100% ;
  11. height: 100% ;
  12. left: 0 ;
  13. }
  14. }
  15. </style>

html


  
  
  1. <div class= "imgs">
  2. <img src= "..." class= "image">
  3. </div>

在父元素,边距的长是取决去宽的,所其宽度与边距的长是相等的.
在把高设为0,宽为100%,上边距100%,上边据就盒子的高.盒子是为正形.
子元素设宽与高为100%,那也是正形.

VUE要点

小图标的编选

根据后台输出的数据,判定显示那个的图标.这vue典型的数据.驱动.解决是使用:class困绑数据


html


  
  
  1. <template>
  2. <ul>
  3. <li v-for="date in goods">
  4. <span :class="classmap[date.type]"> </span>
  5. </li>
  6. </ul>
  7. </template>

js


  
  
  1. <script type="text/javascript">
  2. export default {
  3. data() {
  4. return {
  5. classmap: [ 'decrease' , 'discount' , 'guarantee' , 'invoice' , 'special' ]
  6. };
  7. }
  8. }
  9. </script>

css


  
  
  1. <style type="text/less">
  2. .bgimg ( @imgs) {
  3. background-image : url (' @imgs+".png"') 0 0 no-repeat ~'/' 100% 100% ;
  4. }
  5. .decrease {
  6. display: inline-block ;
  7. height: 12px ;
  8. width: 12px ;
  9. .bgimg('decrease_3');
  10. }
  11. .discount{
  12. display : inline-block ;
  13. height: 12px ;
  14. width: 12px ;
  15. .bgimg('discount_3');
  16. }
  17. .guarantee{
  18. display : inline-block ;
  19. height: 12px ;
  20. width: 12px ;
  21. .bgimg('guarantee_3');
  22. }
  23. .invoice{
  24. display : inline-block ;
  25. height: 12px ;
  26. width: 12px ;
  27. .bgimg('invoice_3');
  28. }
  29. .special{
  30. display : inline-block ;
  31. height: 12px ;
  32. width: 12px ;
  33. .bgimg('special_3');
  34. }
  35. </style>

通过v-for,遍历数据,所以date.type得到数据并判断类型.然后通classmap数组判定绑那个class.来加图标.

小球动画

点击加食物时,触动小球弹出的动画,小球的落点是在车的中央.但起点是根各个节点位子而又差别的.解决使用transitions + events + dispatch事件冒泡

cartcontrol子组件


html


  
  
  1. <template>
  2. <div class="cartcontrol">
  3. <section class="cart-decrease" @click.stop.prevent="decreaseCart" v-show="food.count > 0" transition="move"> </section>
  4. <section class="cart-count" v-show="food.count > 0">{{food.count}} </section>
  5. <section class="cart-add" @click.stop.prevent="addCart"> </section>
  6. </div>
  7. </template>

js


  
  
  1. <script type="text/javascript">
  2. export default {
  3. props: {
  4. food: {
  5. type: Object
  6. }
  7. },
  8. methods: {
  9. addCart(event) {
  10. if (! this .food.count) {
  11. Vue.set( this .food, 'count' , 1 );
  12. this .food.count = 1 ;
  13. } else {
  14. this .food.count++;
  15. };
  16. this .$dispatch( 'cart.add' , event.target);
  17. },
  18. decreaseCart() {
  19. if ( this .food.count) {
  20. this .food.count--;
  21. };
  22. }
  23. }
  24. };
  25. </script>

在加食物,触发了addCart事件,设用set方法给数据加属性,并使cart.add事件冒泡出去,event.target作为事件参数,即节点冒泡出去.

goods父组件


html


  
  
  1. <template>
  2. <shop v-ref:shop :delivery-price="seller.deliveryPrice" :min-price="seller.minPrice" :select-foods="selectFoods"></shop>
  3. </template>

js


  
  
  1. <script>
  2. export default {
  3. methods: {
  4. _drop(target) {
  5. this .$refs.shop.drop(target);
  6. }
  7. },
  8. events: {
  9. 'cart.add' (target) {
  10. this ._drop(target);
  11. }
  12. },
  13. components: {
  14. shop,
  15. cartcontrol,
  16. food
  17. }
  18. };
  19. </script>

在冒泡被events钩子监听,与触动_drop方法,通过接口获得购物车组建的事件,就把control组建event.target传入购物车组建的事件,及把control节点传入了shop组建.

shop组建


html


  
  
  1. <template>
  2. <div class="shopcart">
  3. <section class="ball-container">
  4. <div transition="drop" v-for="ball in balls" v-show="ball.show" class="ball">
  5. <div class="inner inner-hook"> </div>
  6. </div>
  7. </section>
  8. </div>
  9. </template>

js


  
  
  1. <script type= "text/javascript" >
  2. export default {
  3. data() {
  4. return {
  5. balls : [
  6. {
  7. show : false
  8. },
  9. {
  10. show : false
  11. },
  12. {
  13. show : false
  14. },
  15. {
  16. show : false
  17. },
  18. {
  19. show : false
  20. }],
  21. dropBalls : [],
  22. fold : true
  23. };
  24. },
  25. methods : {
  26. drop(el) {
  27. for ( var i = 0 ; i < this .balls.length; i++) {
  28. let ball = this .balls[i];
  29. if (!ball.show) {
  30. ball.show = true ;
  31. ball.el = el;
  32. this .dropBalls.push(ball);
  33. return ;
  34. };
  35. };
  36. }
  37. },
  38. transitions : {
  39. drop : {
  40. beforeEnter(el) {
  41. let count = this .balls.length;
  42. while (count--) {
  43. let ball = this .balls[count];
  44. if (ball.show) {
  45. let rect = ball.el.getBoundingClientRect();
  46. let x = rect.left - 32 ;
  47. let y = -( window .innerHeight - rect.top - 22 );
  48. el.style.display = '' ;
  49. el.style.transform = ` translate3d(0,${y}px,0) `;
  50. let inner = el.getElementsByClassName( 'inner-hook' )[ 0 ];
  51. inner.style.transform = ` translate3d(${x}px,0,0) `;
  52. }
  53. }
  54. },
  55. enter(el) {
  56. let rf = el.offsetHeight;
  57. this .$nextTick( () => {
  58. el.style.transform = 'translate3d(0,0,0)' ;
  59. let inner = el.getElementsByClassName( 'inner-hook' )[ 0 ];
  60. inner.style.transform = 'translate3d(0,0,0)' ;
  61. });
  62. },
  63. afterEnter(el) {
  64. let ball = this .dropBalls.shift();
  65. if (ball) {
  66. ball.show = false ;
  67. el.style.display = 'none' ;
  68. };
  69. }
  70. }
  71. },
  72. components : {
  73. cartcontrol
  74. }
  75. };
  76. </script>

传入节点数据,过渡执行前可插入一个beforeEnter事件,通getBoundingClientRect定位.动画执行后可插入一个afterEnter,还原小球

接后台数据

与后台的配合,通过插vue.resource + express 连接得到数据

dev-server


  
  
  1. <script type="text/javascript">
  2. import express from 'express' ;
  3. var app = express();
  4. var appData = require ( '../data.json' );
  5. var seller = appData.seller;
  6. var goods = appData.goods;
  7. var ratings = appData.ratings;
  8. var apiRoutes = express.Router();
  9. apiRoutes.get( '/seller' , function (req, res) {
  10. res.json({
  11. errno: 0 ,
  12. data: seller
  13. });
  14. });
  15. apiRoutes.get( '/goods' , function (req, res) {
  16. res.json({
  17. errno: 0 ,
  18. data: goods
  19. });
  20. });
  21. apiRoutes.get( '/ratings' , function (req, res) {
  22. res.json({
  23. errno: 0 ,
  24. data: ratings
  25. });
  26. });
  27. app.use( '/api' , apiRoutes);
  28. </script>

通过与配和框架express,连到数据。并放在api里.

main.js


  
  
  1. import VueResource from 'vue-resource';
  2. Vue.use('VueResource');

引进插件和使用,在全局也可以使用.

header组建


  
  
  1. <script type= "text/javascript" >
  2. export default {
  3. created() {
  4. this .$http.get( '/api/ratings' ). then ( (response) => {
  5. var response = response.body;
  6. if (response.errno === 0 ) {
  7. this .ratings = response.data;
  8. };
  9. });
  10. }
  11. }
  12. </script>

在框架的钩子,及创建就通过http.get连到express发的数据,通参数response得到.body表示数据以json格式响应.注意接收数据是异步实现,如果出报错undefined,可用v-if判断,当获取数据后在渲染.

评分类换

用户的满意度有,推荐与吐槽再加上全部,就三个分页,分页通过按钮切换.如何制作呢?解决是使用v-show进判断.

ratingselect子组件


html


  
  
  1. <template>
  2. <div class= "ratingselect">
  3. <div class= "rating-type">
  4. <span @click= "select(2, $event)"</span></span> <span class="hljs-keyword" style="font-weight:bold;"><span class="hljs-keyword">class</span></span>=<span class="hljs-string" style="color:rgb(221,17,68);"><span class="hljs-string">"block positive"</span></span> :<span class="hljs-keyword" style="font-weight:bold;"><span class="hljs-keyword">class</span></span>=<span class="hljs-string" style="color:rgb(221,17,68);"><span class="hljs-string">"{'active':selectType === 2}"</span></span>&gt;{{desc.all}}&lt;span <span class="hljs-keyword" style="font-weight:bold;"><span class="hljs-keyword">class</span></span>=<span class="hljs-string" style="color:rgb(221,17,68);"><span class="hljs-string">"count"</span></span>&gt;{{ratings.length}}&lt;/span&gt;&lt;/span&gt;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> &lt;span @click=<span class="hljs-string" style="color:rgb(221,17,68);"><span class="hljs-string">"select(0, $event)" class= "block positive" : class= "{'active':selectType === 0}">{{desc.positive}}<span class= "count">{{positives.length}}</span></span>
  5. <span @click= "select(1, $event)" class= "block negative" : class= "{'active':selectType === 1}">{{desc.negative}}<span class= "count">{{negatives.length}}</span></span>
  6. </div>
  7. <div @click= "toggleContent" class= "switch" : class= "{'on':onlyContent}">
  8. <span class= "iconfont arre">& #xe905;</span>
  9. <span class= "text">只看有内容的评价</span>
  10. </div>
  11. </div>
  12. </template>

js


  
  
  1. <script type="text/javascript">
  2. export default {
  3. props: {
  4. ratings: {
  5. type: Array ,
  6. default () {
  7. return [];
  8. }
  9. },
  10. selectType: {
  11. type: Number ,
  12. default : 2
  13. },
  14. onlyContent: {
  15. type: Boolean ,
  16. default : true
  17. },
  18. desc: {
  19. type: Object ,
  20. default () {
  21. return {
  22. all: '全部' ,
  23. positive: '满意' ,
  24. negative: '不满意'
  25. };
  26. }
  27. }
  28. },
  29. methods: {
  30. select(type) {
  31. this .selectType = type;
  32. this .$dispatch(</span><span class="hljs-string" style="color:rgb(221,17,68);"><span class="javascript"><span class="hljs-string">'ratingtype.select'</span></span></span><span class="javascript">, type);</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="33"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> },</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="34"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> toggleContent() {</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="35"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.onlyContent = !</span><span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.onlyContent;</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="36"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.$dispatch( 'ratingtype.toggleContent' , this .onlyContent);
  33. }
  34. }
  35. };
  36. </script>

满意是为:0,不满意是为:1,全部是为:2.
  
  

因在点击切换按钮,触发方法,通过传入参数来替换数据,数据selectType赋值等于参数.参数是自义定,然而可以在参数下功夫,然用冒泡将数据分出.

food父组件
html


  
  
  1. <template>
  2. <transiton>
  3. <div class="rating">
  4. <h4 class="title">商品评价 </h4>
  5. <ratingselect :select-type="selectType" :only-content="onlyContent" :desc="desc" :ratings="food.ratings"> </ratingselect>
  6. <div class="rating-wrapper">
  7. <ul v-show="food.ratings && food.ratings.length">
  8. <li v-for="rating in food.ratings" v-show="needShow(rating.rateType,rating.text)" class="rating-item">
  9. <div class="user">
  10. <span class="name">{{rating.username}} </span>
  11. <img class="avatar" width="12" height="12" :src="rating.avatar">
  12. </div>
  13. <div class="time">{{rating.rateTime | formatDate}} </div>
  14. <p class="text">
  15. <span v-if="rating.rateType === 0" class="arrowUp iconfont">&#xe901; </span>
  16. <span v-if="rating.rateType === 1" class="arrowDown iconfont">&#xe902; </span>{{rating.text}}
  17. </p>
  18. </li>
  19. </ul>
  20. <div class="no-rating" v-show="!food.ratings || !food.ratings.length">暂无评价 </div>
  21. </div>
  22. </div>
  23. </transiton>
  24. </template>

js


  
  
  1. <script type= "text/javascript" >
  2. import Vue from 'vue' ;
  3. import ratingselect from 'components/ratings/ratingselect' ;
  4. const POSITIVE = 0 ;
  5. const NEGATIVE = 1 ;
  6. const ALL = 2 ;
  7. export default {
  8. data() {
  9. return {
  10. showFlage : false ,
  11. selectType : ALL,
  12. onlyContent : true ,
  13. desc : {
  14. all : '全部' ,
  15. positive : '推荐' ,
  16. negative : '吐槽'
  17. }
  18. };
  19. },
  20. methods : {
  21. needShow(type, text) {
  22. if ( this .onlyContent && !text) {
  23. return false ;
  24. }
  25. if ( this .selectType === ALL) {
  26. return true ;
  27. } else {
  28. return type === this .selectType;
  29. }
  30. }
  31. },
  32. events : {
  33. 'ratingtype.select' (type) {
  34. this .selectType = type;
  35. this .$nextTick(</span><span class="hljs-function"><span class="hljs-params" style="color:rgb(153,0,0);font-weight:bold;"><span class="javascript"><span class="hljs-function"><span class="hljs-params">()</span></span></span></span><span class="javascript"><span class="hljs-function"> =&gt;</span></span></span><span class="javascript"> {</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="39"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.scroll.refresh();</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="40"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> });</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="41"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> },</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="42"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-string" style="color:rgb(221,17,68);"><span class="javascript"><span class="hljs-string">'ratingtype.toggleContent'</span></span></span><span class="javascript">(onlyContent) {</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="43"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.onlyContent = onlyContent;</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="44"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.$nextTick( () => {
  36. this .scroll.refresh();
  37. });
  38. }
  39. },
  40. components : {
  41. ratingselect
  42. }
  43. };
  44. </script>

在事件钩子上,实行监听,把冒泡触发并赋值,数据就得到.在遍历数据,用v-show进行判断.

VUE杂项

过渡流程

只在v-if,v-show,v-for触动节点的变动效果

当 show 属性改变时,Vue.js 将相应地插入或删除元素,按照如下规则改变过渡的 CSS 类名:

如果 show 变为 false,Vue.js 将:

调用 beforeLeave 钩子;
添加 v-leave 类名到元素上以触发过渡;
调用 leave 钩子;
等待过渡结束(监听 transitionend 事件);
从 DOM 中删除元素并删除 v-leave 类名;
调用 afterLeave 钩子。
如果 show 变为 true,Vue.js 将:

调用 beforeEnter 钩子;
添加 v-enter 类名到元素上;
把它插入 DOM;
调用 enter 钩子;
强制一次 CSS 布局,让 v-enter 确实生效。然后删除 v-enter 类名,以触发过渡,回到元素的原始状态;
等待过渡结束;
调用 afterEnter 钩子。

better-scroll

节点溢满时,是设计稿没有滚动条的,要上下移动.解决使用better-scroll插件.


html


  
  
  1. <div class= "sellerx" v-el:seller style= "overflow: hidden;">
  2. <div class= "seller-content"></div>
  3. </div>

js


  
  
  1. <script type="text/javascript">
  2. ready() {
  3. this .$nextTick(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">if</span></span></span><span class="javascript"> (!</span><span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.scroll) {</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.scroll = </span><span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">new</span></span></span><span class="javascript"> Bscroll(</span><span class="hljs-keyword" style="font-weight:bold;"><span class="javascript"><span class="hljs-keyword">this</span></span></span><span class="javascript">.$els.seller, {
  4. click: true
  5. });
  6. } else {
  7. this .scroll.refresh();
  8. }
  9. });
  10. },
  11. </script>

但父元素设置溢出隐藏,可用插件的移动显出子节点超的内容.要在节点放个接口,使用框架钩子,创建betterScroll事例,那藏的内容通立体相上下移.better-scroll是调用样式的translate是子节点上下引动.

less样式处理

通过引入样式,有是会错误.解决使用设置标签

<style type="text/less"></style>
  
  

处理器会识别到标签的样式类别,编译样式.

esLint

在使用eslint语法校验时,经常报错,但可以在eslintrc设置进行忽略.

no mixed spaces and tabs

是把标签缩进与空格捆和使用,解决是可用tab代替空格.

Expected indentation of 2 space characters but found 3 indent

‘indent’: 0,
‘space-before-function-paren’: 0
设置缩进空行.

defined but never use

可在前加注销
/ eslint-disable no-unused-vars /

后序

要灵活的用vue,先要处理好数据的逻辑. 然而要懂得基本的数据传递属性.


  
  
  1. 子组件传给父组件-
  2. 可以用接口 ref;也可以子组件的冒泡把数据传去,父组件用钩子events监听并接到数据.
  3. 父组件传给子组件-
  4. 可以在子组件props钩子,接收父组件的传递.也可以父组件用 ref接口调用子组件的方法,并把数据传入方法去.

实战是最重要.

猜你喜欢

转载自blog.csdn.net/chenjuan1993/article/details/81327712