欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

自定义指令及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() 定义全局的指令

  1. 第一个参数为指令的名称(注:在定义时,指令的名称前面,不需要加 v- 前缀),但在调用时,必须在指令名称前加上 v- 前缀来进行调用。
  2. 第二个参数是一个对象,这个对象有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作。常用的三个钩子函数为 bind , inserted , update。
  3. bind:每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次。
  4. inserted:表示元素插入到DOM中的时候,会执行inserted函数,触发一次。
  5. update:当组件(或VNode)更新的时候,会执行 update,可能会触发多次。

钩子函数

  1. 第一个参数都为el,表示被绑定了指令的那个元素,这个el参数是一个原生的js对象,可直接用来操作DOM。
  2. 第二个参数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 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

  1. 概念: 从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期。
  2. 生命周期钩子: 就是生命周期函数(生命周期事件)的别名。
  3. 主要的生命周期函数分类:
    - 创建期间的生命周期函数:beforeCreate、created、beforeMount、mounted
    - 运行期间的生命周期函数:beforeUpdate、updated
    - 销毁期间的生命周期函数:beforeDestroy、destroyed

自定义指令及Vue实例的生命周期

<!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