近年来,vue愈来愈火,使用它的人也愈来愈多。vue基本用法很容易上手,可是还有不少优化的写法你就不必定知道了。本文列举了一些vue经常使用的开发技巧。前端
在实际开发中,绝大部分人都是以组件化的方式进行开发。随之而来就有了许多的组件须要引入。好比如下场景:vue
import outExperInfo from "@/components/userInfo/outExperInfo";
import baseUserInfo from "@/components/userInfo/baseUserInfo";
import technicalExperInfo from "@/components/userInfo/technicalExperInfo";
import skillExperInfo from "@/components/userInfo/skillExperInfo";
components:{
outExperInfo,
baseUserInfo,
technicalExperInfo,
skillExperInfo
}
复制代码
这样写并无错,可是仔细观察发现写了不少重复的代码,这个时候利用require.context()能够写成:node
const path = require('path')
const files = require.context('@/components/userInfo', false, /\.vue$/)
const userComponents = {}
files.keys().forEach(key => {
const name = path.basename(key, '.vue')
userComponents[name] = files(key).default || files(key)
})
components:userComponents
复制代码
这样无论须要引入多少组件,均可以使用这一个方法。webpack
随着项目功能模块的增长,引入的文件数量剧增。若是不作任何处理,那么首屏加载会至关的缓慢,这个时候,路由按需加载就闪亮登场了。es6
webpack< 2.4 时
{
path:'/',
name:'home',
components:resolve=>require(['@/components/home'],resolve)
}
webpack> 2.4 时
{
path:'/',
name:'home',
components:()=>import('@/components/home')
}
复制代码
import()方法是由es6提出的,动态加载返回一个Promise对象,then方法的参数是加载到的模块。相似于Node.js的require方法,主要import()方法是异步加载的。web
场景:若是项目中有tab切换的需求,那么就会涉及到组件动态加载,通常写法以下:数组
<component v-bind:is="currentTab"></component>
复制代码
这样写也没有错,可是若是这样写的话,每次切换的时候,当前组件都会销毁而且从新加载下一个组件。会消耗大量的性能,因此 就起到了做用。性能优化
<keep-alive>
<component v-bind:is="currentTab"></component>
</keep-alive>
复制代码
有的小伙伴会说,这样切换虽然不消耗性能了,可是切换效果没有动画效果了,别着急,这时能够利用内置的dom
<transition>
<keep-alive>
<component v-bind:is="currentTab"></component>
</keep-alive>
</transition>
复制代码
前者是局部注册组件,用法以下:异步
export default{
components:{home}
}
复制代码
后者是全局注册组件,主要针对一些全局使用的组件,用法以下:
Vue.component('home',home)
复制代码
Vue.nextTick()方法在下次DOM更新循环结束以后执行延迟回调,所以能够页面更新加载完毕以后再执行回调函数。下面介绍几个经常使用场景:
<template>
<div>
<div ref = "ref"/>
</div>
</template>
<script>
export default {
created(){
console.log(this.$refs.ref)
//undefined
})
}
}
</script>
复制代码
由于这个时候created阶段dom并未彻底渲染完成,因此获取值为undefined,咱们对其改造一下:
<template>
<div>
<div ref = "ref"/>
</div>
</template>
<script>
export default {
created(){
Vue.nextTick(()=>{
console.log(this.$refs.ref)
})
//<div></div>
})
}
}
</script>
复制代码
这样就能够获取到dom了。
<template>
<div>
<div v-if="visible" ref = "ref"/>
</div>
</template>
<script>
export default {
data() {
return {
visible: false
};
},
showRef() {
this.visible = true;
console.log(this.$refs.ref);
//undefined
},
}
}
</script>
复制代码
由于这个时候虽然visible的值为true,可是页面dom并无更新完成,因此获取值为undefined,咱们对其改造一下:
<template>
<div>
<div v-if="visible" ref = "ref"/>
</div>
</template>
<script>
export default {
data() {
return {
visible: false
};
},
showRef() {
this.visible = true;
Vue.nextTick(()=>{
console.log(this.$refs.ref)
})
//<div></div>
},
}
}
</script>
复制代码
这样就能够获取到dom了。
场景:官方给咱们提供了不少指令,可是咱们若是想将文字变成指定的颜色定义成指令使用,这个时候就须要用到Vue.directive,示例以下:
// 全局定义
Vue.directive("change-color",function(el,binding,vnode){
el.style["color"]= binding.value;
})
// 使用
<template>
<div v-change-color>{{message}}
</div>
</template>
<script>
export default{
data(){
return{
color:'green'
}
}
}
</script>
复制代码
当在项目中直接设置数组的某一项的值,或者直接设置对象的某个属性值,这个时候,你会发现页面并无更新。这是由于Object.defineprototype()限制,监听不到变化。
解决方式:
this.$set(this.arr, 0, "OBKoro1"); // 改变数组
this.$set(this.obj, "c", "OBKoro1"); // 改变对象
复制代码
splice()、 push()、pop()、shift()、unshift()、sort()、reverse()
复制代码
意思是使用这些方法不用咱们再进行额外的操做,视图自动进行更新。 推荐使用splice方法会比较好自定义,由于splice能够在数组的任何位置进行删除/添加操做
从 2.3.0 起vue从新引入了 .sync 修饰符,可是此次它只是做为一个编译时的语法糖存在。它会被扩展为一个自动更新父组件属性的 v-on 监听器。示例代码以下:
<comp :foo.sync="bar"></comp>
复制代码
会被扩展为:
<comp :foo="bar" @update:foo="val => bar = val"></comp>
复制代码
当子组件须要更新 foo 的值时,它须要显式地触发一个更新事件:
this.$emit('update:foo', newValue)
复制代码
众所周知,vue会经过object.defineProperty对数据进行劫持,进而实现页面实时相应数据的变化,然而咱们有些时候,须要的仅仅就是纯粹的展现数据,由于数据不会有任何改变,咱们就不须要vue来劫持咱们的数据。在数据量很大的状况下,这能够很明显的减小加载时间。
那么如何实现禁止vue劫持咱们的数据尼?能够经过object.freeze方法来冻结数据,冻结以后数据也就不能再修改了。示例以下:
let longList = [
{name:'monkeysoft'},
...
]
this.longList = Object.freeze(longList)
复制代码
最后,若是你们想和我一块儿讨论探索前端,能够关注一下个人公众号,不按期更新干货,更可加入技术群交流讨论。