写在前面
Vue
全局 api
及实例 api
很多,有很多会被遗忘在角落,如果不熟读文档很难想起它们。但是这些 api
又是日常开发必备,并且在面试的时候常考必考的。所以这里放在这里总结一下,其实了解这些 api
能扩展出很多知识点。当然这里不会过多设计扩展的知识点。
注意很多东西实际上文档上有,但是阅读文档其实很枯燥,特别是初学者,而且文档很多东西比较隐讳、生涩
数据相关 api
Vue
为何需要这两个 api
呢?这主要是跟 Vue
的响应式原理相关的。当创建 Vue
实例的时候,Vue
会将 model
层的数据做响应式处理,监听数据的 set&get
,以便将来更新视图。但是经常有时候我们可能需要在未来某个时刻添加或者删除一些属性,而这个时候我们期望视图也能作出变化。如果我们只是简单的对实例属性做赋值/删除操作,那么由于在初始化实例的时候,这个属性并没有经历过响应式处理,很显然Vue
不会帮我们做视图的自动更新,因此为了实现这种场景,它贴心的给用户提供了这两个 api,不光是静态方法Vue.set
& Vue.delete
,每个 Vue 实例也都有对应的实例方法 vm.$set
& vm.$delete
- Vue.set 向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。
- Vue.delete 删除对象的 property。如果对象是响应式的,确保删除能触发更新视图。
<div id="app">
<p>{{message}}</p>
<p>姓名:{{info.name}}</p>
<p v-show="info.age">年龄:{{info.age}}</p>
<p v-if="info.sex">性别:{{info.sex}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
message: "hello",
info: {
name: "tom",
sex: "男",
},
},
});
setTimeout(() => {
Vue.set(vm.info, "age", 12);
Vue.delete(vm.info, "sex");
}, 3000);
</script>
事件相关 api
在Vue
文档教程部分可能只会提到$emit
以及v-on
这些跟事件相关的东西。但是很多时候比如需要做跨组件通信,我记得刚开始接触Vue
的时候社区充斥着大量的bus
总线机制,往往这时候还需要自己去实现消息订阅发布。实际上Vue
已经提供了这样的能力,主要有如下几个api
:
注意这些 api 都是 Vue 实例上的
- $on 绑定事件
- $emit 触发事件
- $once 仅绑定一次,触发后即移除
- $off
解绑事件,注意这个方法的参数有点意思
- 如果没有提供参数,则移除所有的事件监听器;
- 如果只提供了事件,则移除该事件所有的监听器;
- 如果同时提供了事件与回调,则只移除这个回调的监听器。
<script>
// 测试 $on & $emit
const vm1 = new Vue({})
vm1.$on('hello-world',function(msg){
console.log(msg);
})
vm1.$emit('hello-world','hello china',)
// 测试$once
const vm2 = new Vue;
vm2.$once('test-once',function(){
console.log('abc');
})
vm2.$emit('test-once')
vm2.$emit('test-once')
// 测试$off
const vm3 = new Vue;
vm3.$on('off1',function(){
console.log(123);
})
vm3.$on('off2',function(){
console.log(456);
})
// 不传参数
vm3.$off()
vm3.$emit('off1')
vm3.$emit('off2')
vm3.$on('off3',function(){
console.log(789);
})
vm3.$on('off4',function(){
console.log(101112);
})
// 只传一个事件名称
vm3.$off('off3')
vm3.$emit('off3')
vm3.$emit('off4')
// 传事件名称 和 回调函数
function off5(){
console.log('off5');
}
function off6(){
console.log('off6');
}
vm3.$on('off5',off5)
vm3.$on('off5',off6)
vm3.$off('off5',off6)
vm3.$emit('off5')
</script>
熟悉 jQuery 的同学应该惊讶吧~~
ref & nextTick
这两个都是 Vue
里面面试比较常考的东西,特别是 nextTick
会延伸出 Vue
的异步更新队列;而ref
又是组件通信的一种形式。所以这里非常有必要说明一下
简单通俗点说:
-
ref
是一个属性,可以作用于原生DOM
,此时ref
指向的就是DOM
元素;也可以作用于自定义组件,此时ref
指向的是组件实例. 当然最后ref
都会归于他父组件实例的$refs
属性上。 -
nextTick
又是什么呢?其实它会把回调函数放入一个数组,然后通过降级(支持promise就用promise,否则用元定时器)的形式,当数据发生变化,然后视图也异步更新完毕后,这个回调函数将执行。
具体实例如下:
<div id="app">
<p ref="p1">hello vue</p>
<v-message ref="message"></v-message>
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
<button @click="addList">addList</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
Vue.component("v-message", {
template: `<div>this is message comopnents</div>`,
methods: {
say() {
console.log("hello");
},
},
});
const vm = new Vue({
el: "#app",
data: {
list: [1, 2, 3, 4, 5, 6],
},
methods: {
addList() {
this.list.push(Math.random());
console.log(document.getElementsByTagName("li").length);
this.$nextTick(function() {
console.log(document.getElementsByTagName("li").length);
});
},
},
});
console.log(vm.$refs.p1.innerHTML);
console.log(vm.$refs.message);
vm.$refs.message.say();
</script>
最后
通过总结这几个常用常考的Vue
必备api
,希望能够帮助一下正在找工作的你~~,另外也希望一起进步,没事多翻翻文档。其实文档中隐藏了很多很多知识点。
- 参考 vue.js