能让你首次加载更快的路由懒加载,怎么能忘?
路由懒加载能够让咱们的包不须要一次把所有的页面的加载进来,只加载以后页面的路由组件就行。
举个🌰,如果这样写,加载的时候会全副都加载进来。
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>
$attr 和 $listeners 让你封装组件蛟龙得水!
$attr 和 $listeners 可能很多同学没怎么去应用,其实它们让咱们对一些组件库的组件二次封装,十分好用的。
简略介绍一下它们两个:
$attr: 如果一个组件岂但传了 prop 须要的属性,还传了 prop 之外的其余属性,那么这些属性都会被收集到 $attr 外面。
$listeners:如果一个组件传了自定义事件,但子组件没有通过 emit 触发,那么这些自定义办法都会被收集到 $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>