自定义指令及Vue实例的生命周期
程序员文章站
2022-03-28 16:06:56
如v-model,v-bind,v-for,v-show等指令都是Vue内置的指令,但可以通过自定义指令来达到其他的效果。Vue中所有的指令,在调用的时候,都以 v- 开头,所以自定义指令后调用时前面也要加 v- 。使用 Vue.directive() 定义全局的指令第一个参数为指令的名称(注:在定义时,指令的名称前面,不需要加 v- 前缀),但在调用时,必须在指令名称前加上 v- 前缀来进行调用。第二个参数是一个对象,这个对象有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作。常用...
如v-model,v-bind,v-for,v-show等指令都是Vue内置的指令,但可以通过自定义指令来达到其他的效果。
Vue中所有的指令,在调用的时候,都以 v- 开头,所以自定义指令后调用时前面也要加 v- 。
使用 Vue.directive() 定义全局的指令
- 第一个参数为指令的名称(注:在定义时,指令的名称前面,不需要加 v- 前缀),但在调用时,必须在指令名称前加上 v- 前缀来进行调用。
- 第二个参数是一个对象,这个对象有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作。常用的三个钩子函数为 bind , inserted , update。
- bind:每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次。
- inserted:表示元素插入到DOM中的时候,会执行inserted函数,触发一次。
- update:当组件(或VNode)更新的时候,会执行 update,可能会触发多次。
钩子函数
- 第一个参数都为el,表示被绑定了指令的那个元素,这个el参数是一个原生的js对象,可直接用来操作DOM。
- 第二个参数binding,是一个对象,常用的属性有(具体可参考Vue.js官网)
- name:指令名,不包括 v- 前缀
- value:指令绑定的值(计算结果),如v-my-directive=“1 + 1”,绑定值为2
- expression:字符串形式的指令表达式,如v-my-directive=“1 + 1”,表达式为"1 + 1"
- 函数简写: 大多数情况下,可能只在 bind 和 update 钩子上做重复动作,并且不关心其他钩子函数,可以这样写:
Vue.directive('color-swatch',function(el,binding){
el.style.backgroundColor = binding.value;
//这个function相当于在bind和update里面都写了一份
})
指令—自定义全局指令让文本框获取焦点,并改变字体样式:
<div id="app">
<input type="text" v-focus v-fontweight="900">
<!--不能省略单引号,否则会把blue当作一个变量,而不是字符串-->
<p v-fontsize="'50px'" v-color="'blue'">{{mes}}</p>
</div>
<script>
Vue.directive('focus', {
bind: function(el) {
//在元素刚绑定指令的时候,还没有插入到DOM中去,这时调用focus方法没用
//因为一个元素只有插入DOM之后才能获取焦点
//el.focus();
//样式,只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联样式
el.style.color = 'red'
},
inserted: function(el) {
el.focus();
},
update: function(el) {
}
})
Vue.directive('color', {
bind: function(el, binding) { //此为形参,可以改变变量名,下面同步即可
//el.style.color = 'red';
console.log(binding.name); //color
console.log(binding.value); //blue
console.log(binding.expression); //'blue'
el.style.color = binding.value; //通过binding来拿到传递的值
}
})
//执行任何有关Vue操作前,都要先创建vue实例选定Vue控制区域,否则相关Vue操作都会无效
var vm = new Vue({
el: '#app',
data: {
mes: '加油!'
},
methods: {},
filters: {}, //定义私有过滤器
directives: { //自定义私有指令
'fontweight': {
bind: function(el, binding) {
el.style.fontWeight = binding.value;
//fontWeight第二个单词首字母要大写,不然会失效
}
},
'fontsize': function(el, binding) {
//注意:这个function等同于写在了bind和update中去
el.style.fontSize = parseInt(binding.value) + 'px';
}
}
})
</script>
注: bind在Vue实例创建期间执行created函数时执行,但此时并未将数据渲染到内存中的DOM树,对不在DOM树中的元素调用方法是无效的,在插入DOM树之后调用方法才有效。
所以和JS行为有关的操作,最好在inserted中去执行,防止JS行为不生效。和样式相关的操作,一般都可以在 bind 执行,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联样式,浏览器的渲染引擎会解析样式,应用给这个元素。
Vue实例的生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
- 概念: 从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期。
- 生命周期钩子: 就是生命周期函数(生命周期事件)的别名。
-
主要的生命周期函数分类:
- 创建期间的生命周期函数:beforeCreate、created、beforeMount、mounted
- 运行期间的生命周期函数:beforeUpdate、updated
- 销毁期间的生命周期函数:beforeDestroy、destroyed
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue实例的生命周期函数</title>
<script src="../lib/vue.js"></script>
</head>
<body>
<div id="app">
<input type="button" value="修改mes值" @click="mes='快完成啦'">
<h3 id="h3">{{mes}}</h3>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
mes: '明天继续坚持'
},
methods: {
show() {
console.log('执行了show方法')
}
},
//创建期间的生命周期函数
beforeCreate() { //这是我们遇到的第一个生命周期函数,表示实例完全被创建出来之前,会执行它
console.log(this.mes); //undefined
//this.show(); //报错:this.show is not a function
},
created() { //这是我们遇到的第二个生命周期函数
console.log(this.mes); //明天继续坚持
this.show(); //执行了show方法
},
beforeMount() { //这是我们遇到的第三个生命周期函数,表示模板以及在内存中编译完成了,但尚未把模板渲染到页面中去
console.log(document.getElementById('h3').innerText); //{{mes}}
},
mounted() { //这是我们遇到的第四个生命周期函数,表示内存中的模板已挂载到页面中去,可以看见渲染好的页面
console.log(document.getElementById('h3').innerText); //明天继续坚持
},
//运行期间的生命周期函数
beforeUpdate() { //此时数据更新(model)了,但界面(view)还没更新
console.log('界面上元素的内容:' + document.getElementById('h3').innerText); //界面上元素的内容:明天继续坚持
console.log('data中的mes数据:' + this.mes); //data中的mes数据:快完成啦
},
updated() { //此时已同步更新完成
console.log('界面上元素的内容:' + document.getElementById('h3').innerText); //界面上元素的内容:快完成啦
console.log('data中的mes数据:' + this.mes); //data中的mes数据:快完成啦
}
//给router-view加了个keep-alive导致组件缓存了,所以不会触发beforeDestory和destoryed
})
</script>
</body>
</html>
本文地址:https://blog.csdn.net/qq_46469137/article/details/107557695