不可错过的vue开发技巧

【稿件】

创新互联公司网站建设提供从项目策划、软件开发,软件安全维护、网站优化(SEO)、网站分析、效果评估等整套的建站服务,主营业务为成都网站设计、成都网站建设、外贸网站建设app开发定制以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。创新互联公司深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

前言

本文主要介绍日常项目开发过程中的一些技巧,帮助大家规避错误的同时还能提高应用的性能。以下是我总结的一些平时工作中的经验。

在v-if/v-if-else/v-else中使用key

如果一组v-if 与v-else的元素类型相同,最好使用属性key。这是因为Vue2.0引入虚拟DOM,为了避免不必要的DOM操作,虚拟DOM在虚拟节点映射到视图过程中,将虚拟节点与上一次渲染视图所使用的旧虚拟节点做对比,找出真正需要更新的节点来进行DOM操作。但有时如果两个本不相同的节点被识别为相同,便会出现意料之外的问题。我们看下面的一个例子:

 
 
 
 
  1. // 这种写法会出bug 
  2.  
  3.    
  4.    
 
  •  
  •    
  •    
  •  
  • 切换  
  • 如果添加了属性key,那么在对比虚拟DOM时,则会认为它们是两个不同的节点,于是会将旧元素移除并在相同位置添加新元素,从而避免漏洞的出现。

     
     
     
     
    1. // 最佳写法 
    2.  
    3.    
    4.    
     
  •  
  •    
  •    
  •  
  • 切换 
  • v-for循环中不要使用index作为key

    我们会给列表渲染设置属性key,这个key属性主要用在虚拟DOM算法上,在对比新旧虚拟节点时辨识虚拟节点。但如果key用得不合理,就会出现bug,比如我们使用index作为key(见下面例子),核心代码如下:

     
     
     
     
    1.  
    2.   //使用index作为key 
    3.      handleDelete(key)">删除 
    4.    
    5.   添加 
    6.  
    7. ...... 
    8.   handleAdd() { 
    9.     this.list.push(key++); 
    10.   }, 
    11.   handleDelete(key) { 
    12.     const index = this.list.findIndex(k => k === key); 
    13.     this.list.splice(index, 1); 
    14.   } 

    上例中,我们想删除第二个输入框,却误删了第三个输入框,这因为当使用splice()方法删除数组的某个元素时数组的index会被重新索引,造成数组的最后一个index丢失,从而会使虚拟DOM的最后一个结点(key)丢失,造成无论删除哪个结点都会误删除最后一个结点的bug。但如果我们使用传入的key作为key,就可以避免这种问题出现。

     
     
     
     
    1.  
    2.    
    3.      handleDelete(key)">删除 
    4.    
    5.   添加 
    6.  

    简单暴力的router key

    我们在项目开发时,可能会遇到这样问题:当页面切换到同一个路由但不同参数地址时,比如/detail/1,跳转到/detail/2,页面跳转后数据竟然没更新?路由配置如下:

     
     
     
     
    1.     path: "/detail/:id", 
    2.     name:"detail", 
    3.     component: Detail 

    这是因为vue-router会识别出两个路由使用的是同一个组件从而进行复用,并不会重新创建组件,而且组件的生命周期钩子自然也不会被触发,导致跳转后数据没有更新。那我们如何解决这个问题呢? 我们可以为router-view组件添加属性key,例子如下: 

     
     
     
     
    1.  

    这种办法主要是利用虚拟DOM在渲染时候通过key来对比两个节点是否相同,如果key不相同,就会判定router-view组件是一个新节点,从而先销毁组件,然后再重新创建新组件,这样组件内的生命周期会重新触发。

    路由懒加载

    当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。 配合webpack支持的路由懒加载方法有:

     
     
     
     
    1. resolve => require([./Foo], resolve) 
     
     
     
     
    1. const Foo = () => import('./Foo') 

    接下来我们以官方文档的写法为例,对比这两种写法:

     
     
     
     
    1. // 非懒加载写法 
    2. import Vue from 'vue' 
    3. import Router from 'vue-router' 
    4. import Home from 'pages/home' 
    5. ... 
    6. ​ 
    7. Vue.use(Router) 
    8. ​ 
    9. export default new Router({ 
    10. routes: [ 
    11.   { 
    12.       path: '/', 
    13.       name: 'home', 
    14.       component: Home 
    15.   } 
    16.   ... 
    17. }) 

    推荐以下写法,路由懒加载可以帮我们在进入首屏时不用加载过多的资源,从而减少首屏加载速度。

     
     
     
     
    1. // 路由懒加载写法 
    2. import Vue from 'vue' 
    3. import Router from 'vue-router' 
    4. ​ 
    5. // 其它都不用变,就是这么简单 
    6. const Home = () => import('./home') 
    7. ... 
    8. ​ 
    9. Vue.use(Router) 
    10. ​ 
    11. export default new Router({ 
    12. routes: [ 
    13.   { 
    14.       path: '/', 
    15.       name: 'home', 
    16.       component: Home 
    17.   } 
    18.   ... 
    19. }) 

    不要在使用v-for的同一元素上使用v-if

    Vue官方文档强烈建议永远不要把 v-if 和 v-for 同时用在同一个元素上。一般我们在两种常见的情况下会倾向于这样做:

     
     
     
     
    1. // 第一种情形 反例 
      •  
      •   v-for="user in users" 
      •   v-if="user.isActive" 
      •   :key="user.id" 
      •   {{ user.name }} 
      •  
       

    当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,所以哪怕我们只渲染出一小部分用户的元素,也得在每次重渲染的时候遍历整个列表,不论活跃用户是否发生了变化。我们可通过将其更换为在如下的一个计算属性上遍历:

     
     
     
     
    1. // 好例子 
    2. computed: { 
    3. activeUsers: function () { 
    4.   return this.users.filter(function (user) { 
    5.     return user.isActive 
    6.   }) 
     
     
     
     
      •  
      •   v-for="user in activeUsers" 
      •   :key="user.id" 
      •   {{ user.name }} 
      •  
       
     
     
     
     
    1. // 第二种情形 反例 
      •  
      •   v-for="user in users" 
      •   v-if="shouldShowUsers" 
      •   :key="user.id" 
      •   {{ user.name }} 
      •  
       

    更新为:

     
     
     
     
    1. // 好例子 
    2.  
    3.   v-for="user in users" 
    4.   :key="user.id" 
    5.   {{ user.name }} 
    6.  
    7.  

    过滤器让数据处理更便利

    Vue.js 允许你自定义过滤器,它的用法其实是很简单,但是可能有些朋友没有用过,接下来我们介绍下:

    1.理解过滤器

    2.定义过滤器

    可以在一个组件的选项中定义本地的过滤器:

     
     
     
     
    1. filters: { 
    2. capitalize: function (value) { 
    3.   if (!value) return '' 
    4.   value = value.toString() 
    5.   return value.charAt(0).toUpperCase() + value.slice(1) 

    也可以在创建 Vue 实例之前全局定义过滤器:

     
     
     
     
    1. Vue.filter('capitalize', function (value) { 
    2. if (!value) return '' 
    3. value = value.toString() 
    4. return value.charAt(0).toUpperCase() + value.slice(1) 
    5. }) 

    3.使用过滤器

    使用方法也简单,即在双花括号中使用管道符(pipeline) |隔开:

     
     
     
     
    1.  
    2. {{ myData| filterName}}
       
    3. {{ myData| filterName(arg)}}
       
    4.  
    5.  

    接下来我们看个如何使用过滤器格式化日期的例子:

     
     
     
     
    1.  
    2.   

      显示格式化的日期时间

       
    3.   

      {{ date }}

       
    4.   

      {{ date | filterDate }}

       
    5.   

      年月日: {{ date | filterDate("YYYY-MM-DD") }}

       
    6.  
    7. ...... 
    8. filters: { 
    9.   filterDate(value, format = "YYYY-MM-DD HH:mm:ss") { 
    10.     console.log(this)//undefined 过滤器没有this指向的 
    11.     return moment(value).format(format); 
    12.   } 
    13. }, 
    14. data() { 
    15.   return { 
    16.     date: new Date() 
    17.   }; 

     

    能用computed的尽量用computed代替 watch

    很多时候页面会出现 watch 的滥用而导致一系列问题的产生,而通常更好的办法是使用 computed 属性,先从一张图区别它们有什么区别?

    从上面流程图中,我们可以看出它们之间的区别:

    除此之外,有点很重要的区别是:计算属性不能执行异步任务,计算属性必须同步执行。也就是说计算属性不能向服务器请求或者执行异步任务。如果遇到异步任务,就交给侦听属性。watch也可以检测computed属性。总而言之,两者的区别归纳为以下两句话:

    为啥提倡使用 computed 代替 watch,这是因为有时候可以实现同样的效果,而 computed 会更胜一筹,比如在处理多数据联动的情况下,使用 computed 会更加合理一点。

     
     
     
     
    1.  
    2. ​ 
    3.  

    化繁为简的Watchers

    如果我们需要在组件初始化以及侦听属性变化时调用同一个方法,通常的做法像下面这样:

     
     
     
     
    1. watch: { 
    2. myProperty() { 
    3.   this.doSomething(); 
    4. }, 
    5. created() { 
    6. this.doSomething(); 
    7. }, 
    8. methods: { 
    9. doSomething() { 
    10.     console.log('doing something...'); 

    尽管上面这段代码看起来没什么问题,但created钩子里面执行的方法是多余的。我们可以把所需要执行的方法放到watch里面,避免在created钩子里写重复代码,那将会在组件实例化的时候触发多一次。 那如何优化呢?代码如下:

     
     
     
     
    1. watch: { 
    2. myProperty: { 
    3.   immediate: true,//表示创建组件时立马执行一次 
    4.   handler() { 
    5.     console.log('doing something...'); // 只用一次的方法没必要在methods里面声明了 
    6.   } 

    参考文章与书籍

    作者介绍

    浪里行舟,慕课网认证作者,前端爱好者,立志往全栈工程师发展,从事前端一年多,目前技术栈有vue全家桶、ES6以及less等,乐于分享,最近一年写了五六十篇原创技术文章,得到诸多好评!

    【原创稿件,合作站点转载请注明原文作者和出处为.com】

    文章题目:不可错过的vue开发技巧
    文章起源:http://www.shufengxianlan.com/qtweb/news49/541049.html

    网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

    广告

    声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

    猜你还喜欢下面的内容

    服务器托管知识

    同城分类信息