曾经好久好久没写过文章,上一次写应该是年前吧,可能是变懒了吧。最近都在看坑找坑,闲下来有点无聊,就想水一遍文章,打发一下工夫...

能让你首次加载更快的路由懒加载,怎么能忘?

路由懒加载能够让咱们的包不须要一次把所有的页面的加载进来,只加载以后页面的路由组件就行。

举个,如果这样写,加载的时候会全副都加载进来。

const router = new VueRouter({  routes:[    {      path: '/',      name: 'Home',      component: Home    },    {      path: '/about',      name: 'About',      component: About    }  ]})

所以,应该防止下面的写法,尽量应用懒加载

懒加载写法,联合webpack的import食用

const router = new VueRouter({  routes:[    {      path: '/',      name: 'Home',      component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')    },    {      path: '/about',      name: 'About',      component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')    }  ]})

你是否还记得有一个叫Object.freeze的办法?

应该所有同学都晓得,vue初始化的时候会将data外面的数据都搞成响应式数据吧。然而,咱们在写业务逻辑的时候会有些数据一初始化就永远不会扭转,它基本就不须要被vue做成响应式数据,因而咱们应该将这些不必扭转的数据通过Object.freeze办法解冻它,防止vue初始化的时候,做一些无用的操作。

export default {  data:()=>({    list:Object.freeze([{title:'我永远不须要扭转,我不须要响应式'}])  })}

异步组件那么强,你是不是没用过?

异步组件能够让咱们在须要一些组件时才将它加载进来,而不是一初始化就加载进来,这跟路由懒加载时一个概念。

export default {  components:{    AsyncComponent:()=>import(/* webpackChunkName: "AsyncComponent" */ './Async')  }}

首次加载的包是不蕴含改选件代码的

当点击触发某种行为引进的包是这样的

异步组件还有一种比较完善的写法

export default {  components:{    AsyncComponent:()=>({      component:import(/* webpackChunkName: "AsyncComponent" */ './Async'),      delay:200, // 提早几毫秒,默认200      timeout:3000, // 加载几毫米之后就超时,触发error组件      loading:LoadingComponent, // 组件未加载回来前显示      error:ErrorComponent // 组件超时时显示    })  }}

你是不是还在computed中应用this?

我猜还有很多同学,在computed属性中通过this.xxx去拿data外面的数据,和methods外面的办法吧,或者还会通过this.$store去拿vuex的state,和commit等,甚至,还会通过this.$route去获取路由外面的数据吧。其实,咱们能够防止这些俊俏的this,它甚至会给咱们带来看不见的性能问题。实现上,咱们通过this能拜访到的数据,在computed的第一个参数上都能构造进去。

export default {   haha({$attrs,$route,$store,$listeners,$ref}){     // 还能构造很多属性,可自行打印康康     return    }}

如何防止v-if和v-for一起应用?

为什么要防止v-if和v-for在同一个元素上同时应用呢?因为在vue的源码中有一段代码时对指令的优先级的解决,这段代码是先解决v-for再解决v-if的。所以如果咱们在同一层中一起应用两个指令,会呈现一些不必要的性能问题,比方这个列表有一百条数据,再某种状况下,它们都不须要显示,当vue还是会循环这个100条数据显示,再去判断v-if,因而,咱们应该防止这种状况的呈现。

不好的

    <h3 v-if="status" v-for="item in 100" :key="item">{{item}}</h3>

好的

    <template v-if="status" >        <h3 v-for="item in 100" :key="item">{{item}}</h3>    </template>

那么强的.sync修饰符你为什么不必?

如果你想要在父组件管制一个子组件的显示暗藏,是不是还在传一个prop和一个自定义办法,这样会很麻烦,无妨试一试sync修饰符。

 // 父组件  template>  <div>    <Toggle :show.sync = 'show'></Toggle>  </div></template>//Toggle 组件<template>  <div>    <div v-if="show">    展现和暗藏组件  </div>  <button @click="test">暗藏组件</button>  </div></template><script>export default {  props:['show'],  methods: {    test(){      this.$emit('update:show',false)    }  }}</script>

&dollar;attr和&dollar;listeners让你封装组件蛟龙得水!

&dollar;attr和&dollar;listeners可能很多同学没怎么去应用,其实它们让咱们对一些组件库的组件二次封装,十分好用的。

简略介绍一下它们两个:

&dollar;attr:如果一个组件岂但传了prop须要的属性,还传了prop之外的其余属性,那么这些属性都会被收集到&dollar;attr外面。

&dollar;listeners:如果一个组件传了自定义事件,但子组件没有通过emit触发,那么这些自定义办法都会被收集到&dollar;listeners外面。

这里举一个对ElementUI的Tabel组件简略的二次封装的

<el-table    v-bind="$attrs"   v-on="$listeners">   <template v-for="item in column">    <el-table-column v-bind="item" />   </template></el-table><script>export default {  props:{      column:{        type:Array,        required:true      }   }}<script>

v-model还有这么好的修饰符!

v-model上有3个比拟好用的修饰符不知到大家有没有用过,一个是lazy,一个是number,一个是trim。

lazy:能够将@input事件变成@blur事件

number:只能输出数字值

trim:清空两边的空格

   //lazy   <input v-model.lazy="msg" />   //number   <input v-model.number="msg" />   //trim   <input v-model.trim="msg" />

你是否晓得v-model还能自定义属性?

如果想在一个自定义的Input组件上应用v-model,那么就要在子组件,介绍一个value,和触发input事件,v-model的默认语法糖就是这两个货色的组合。

// 父组件<template>  <div>    <CustomInput v-model='msg' />  </div></template>//CustomInput<template>  <div>    <input type="text" :value="value" @input="test">  </div></template><script>export default {  props:['value'],  methods: {    test(e){      this.$emit('input',e.target.value)    }  },}</script>

然而,如果组件外面不是input,而是一个checkbox或者一个radio呢?我不想承受一个value和input事件,我想接管一个更加语义化的checked和change事件,那该怎么办?

// 父组件不需扭转...//CustomInput<template>  <div>    <input type="checkbox" :checked="checked" @change="test">  </div></template><script> props:['checked'], model:{    props:'checked',    event:'change'  },  methods: {    test(e){      this.$emit('change',e.target.checked)    }  }}</script>

你还在用浏览器的scrollTop滚动你的页面吗?

有些时候咱们在操作一下页面的滚动行为,那么咱们第一工夫就会想到scrollTop。其实咱们还有第二个抉择就是VueRouter给咱们提供的scrollBehavior钩子。

const router = new VueRouter({  routes:[...] ,  scrollBehavior(to,from,position){      // position参数可自行打印康康,点击浏览器左右箭头会触发      return{          // 这里能够返回很多参数,上面简略列就几个,详情本人康康官网          x:100,          y:100,          selector:#app,          offset:200,          //等等      }  }})

你在子组件上定义的原生事件不失效?

有时候咱们想在子组件下面监听一些事件,比方click,然而不管你怎么点,它都没反馈,为什么呢?

<template>    <div>        <Child @click="test"></Child>    </div></template><script>    methods:{        test(){}    }</script>

因为这样写vue会认为,你自定义了一个click事件,要在子组件通过$emit('click')触发才行。如果我就是要在父组件触发呢?那就要用到native修饰符了。

<template>    <div>        <Child @click.native="test"></Child>    </div></template><script>    methods:{        test(){}    }</script>

用keep-alive缓存一下你的页面状态吧!

keep-alive能够帮忙咱们在切换组件的时候,保留上一个组件不被销毁,它在治理后盾零碎中比拟罕用。

<keep-alive>    <router-view></router-view></keep-alive>