3. Vue实例核心选项

3.1. 1. 数据选项

参考文献:

https://v3.cn.vuejs.org/api/options-data.html#data-2

3.2. 2.生命周期钩子

每个Vue实例都有完整的生命周期,即从开始创建、初始化数据、编译模板、DOM挂载、数据更新并重新渲染、组件卸载等一系列过程,我们称为Vue实例的生命周期。在整个周期中,每个节点都会有一个钩子函数来处理该阶段的某些事物,这些钩子函数被称为生命周期函数。

生命周期每个阶段具体的钩子函数内容如下。

3.2.1. 2.1 create初始化

1.beforeCreate

在Vue实例初始化之后,在数据观测和事件配置之前被调用,这时自定义组件的选项对象还没有被创建出来,el和data选项并未初始化,所以在该钩子函数中无法访问methods、data、computed等选项上的方法和数据。

2.created

在Vue实例已经创建完成之后被调用,在该钩子函数中可以对data数据进行观测,对实例上的属性和方法进行运算,执行watch和event事件的回调,完成data数据的初始化等操作。

但是在该阶段,由于还未到挂载阶段,所以$ el属性仍然不能访问。

在created钩子函数中,我们常对一些实例进行预处理操作,例如发送ajax请求等。因为在该阶段可以调用methods中的方法,并对data中的数据进行修改。由于该阶段还未渲染DOM,所以在该阶段中不能进行有关DOM操作的处理。

3.2.2. 2.2 mount组件挂载

1.beforeMount

在挂载之前被调用,Vue中的render()函数第一次被调用,在该阶段虚拟DOM已经完成了模板编译,把data中的数据和模板生成了HTML,完成了el和data初始化工作。该阶段虽然已经完成了基本的初始化工作,但是还没有执行挂载操作。

2.mounted

在挂载完成后调用,也就是模板中的HTML已经被渲染到了浏览器中,一般会在该阶段执行ajax操作,或者执行DOM元素操作。

3.2.3. 2.3 update组件更新

1.beforeUpdate

在数据更新之前被调用,发生在虚拟DOM被重新渲染和打补丁之前,可以在该钩子中进一步更改状态,不会触发附加重复渲染过程。

2.updated

当data的数据发生改变时,虚拟DOM被重新渲染后会调用updated()钩子函数。

在调用时,组件DOM已经发生了更新,在这个阶段可以执行依赖DOM的操作。在该阶段应该避免出现操作数据的情况,因为可能会导致虚拟DOM被重新渲染,从而使更新进入无限循环的状态。该钩子函数在服务器端渲染期间不会被调用。

3.2.4. 2.4 destroy组件销毁

1.beforeDestroy

在Vue实例销毁之前调用,此时的实例还是完全可用状态。在该阶段可以使用this获取Vue实例,一般情况下会在该钩子函数中进行一些重置操作。例如,清除组件中的定时器,或清除监听DOM的事件等。

2.destroyed

在Vue实例被销毁之后调用,当钩子函数被调用后,所有的事件监听都会被移除,并且所有的组件都会被销毁。该钩子函数在服务器端渲染时不会被调用。

示例参考

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
        </div>
        <script>
            var vm = new Vue({
                el: "#app",
                beforeCreate() {
                    console.log('beforeCreate...')
                },
                created(){
                    console.log('created...')
                },
                beforeMount() {
                    console.log('beforeMount...')
                },
                mounted() {
                    console.log('mounted...')
                },
                beforeDestroy() {
                    console.log('beforeDestroy...')
                },
                destroyed() {
                    console.log('destroyed...')
                }
            })
        </script>
    </body>
</html>

生命周期钩子函数示例

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>生命周期钩子函数</title>
</head>
<body>
<div id="app">
    <p>{{msg}}</p>
 </div>
<!--引入vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
     //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
              msg : "白日照绿草, 落花散且飞。"
           }
        },
        //在实例初始化之后,数据观测(data observer)和event/watcher 事件配置之前被调用。
        beforeCreate:function(){
            console.log('beforeCreate');
        },
        /* 在实例创建完成后被立即调用。在这一步,实例已完成数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。 */
        created:function(){
            console.log('created');
        },
        //在挂载开始之前被调用:相关的渲染函数首次被调用
        beforeMount : function(){
            console.log('beforeMount');
        },
        //el 被新创建的 vm.$el 替换, 挂在成功
        mounted:function(){
            console.log('mounted');
        },
        //数据更新时调用
        beforeUpdate : function(){
            console.log('beforeUpdate');
        },
        //组件 DOM 已经更新, 组件更新完毕
        updated : function(){
            console.log('updated');
        }
     }).mount('#app');
    setTimeout(function(){
            vm.msg = "孤云还空山, 众鸟各已归。";
         }, 4000);
</script>
</body>
</html>

3.2.5. 2.5 created和mouted

在使用Vue的过程中,经常需要对一些数据做初始化处理,常用的方法是在created与mounted钩子函数中处理。 created是在实例创建完成后立即调用。在这一步,实例已完成了数据观测、属性和方法的运算,以及watch/event事件回调。

然而,挂载阶段还没开始,$el属性目前不可见。所以不能操作DOM元素,多用于初始化一些数据或方法。

mounted是在模板渲染成HTML后调用,通常是初始化页面完成后,再对HTML的DOM节点进行一些需要的操作。

created与mounted函数的应用

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>created与mounted函数的应用</title>
</head>
<body>
<div id="app">
    <ul>
        <li id="b1"></li>
        <li id="b2"></li>
        <li id="b3"></li>
    </ul>
 </div>
<!--引入vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
     //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
               name:'',
               city:'',
               price:0
           }
        },
         //在选项对象的methods属性中定义方法
        methods: {
            way:function () {
                alert("使用created初始化方法")
            }
        },
        created:function(){
            // 初始化方法
            this.way();
            //初始化数据
            this.name="苹果";
            this.city="烟台市";
            this.price="8.88元/公斤";
        },
        //对DOM的一些初始化操作
        mounted:function(){
            document.getElementById("b1").innerHTML=this.name;
            document.getElementById("b2").innerHTML=this.city;
            document.getElementById("b3").innerHTML=this.price;
        }
     //在指定的DOM元素上装载应用程序实例的根组件
     }).mount('#app');
</script>
</body>
</html>

3.3. 3.资源选项

3.3.1. 3.1 directives选项

在Vue中除了内置的指令,例如v-model和v-bind等,Vue还允许手动注册自定义指令。在Vue 2中,代码复用和抽象的主要形式是组件,然而在有些情况下,仍然需要对普通DOM元素进行底层操作,这时就需要用directives选项来自定义指令。

一个指令定义对象可以提供以下几个钩子函数。

(1)bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
(2)inserted:被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。
(3)update:所在组件的VNode更新时调用,但是可能发生在其子VNode更新之前。指令的值可能发生了改变,也可能没有。
(4)componentUpdated:指令所在组件的VNode及其子VNode全部更新后调用。
(5)unbind:只调用一次,指令与元素解绑时调用。

如果想要在页面渲染完成后自动让输入框获取焦点,可以使用directives选项创建一个自定义指令,代码如下:

const app = Vue.createApp({})
// 注册一个全局自定义指令 `v-focus`
app.directive('focus', {
  // 当被绑定的元素挂载到 DOM 中时……
  mounted(el) {
    // 聚焦元素
    el.focus()
  }
})

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            <div v-red>hello</div>
        </div>
        <script>
            var vm = new Vue({
                el: "#app",
                directives:{
                    red: {
                        inserted(el){
                            el.style.color = 'red';
                        }
                    }
                }

            })
        </script>
    </body>
</html>

更多内容参考:

https://v3.cn.vuejs.org/guide/migration/custom-directives.htm

3.3.2. 3.2 filters选项

Vue.js允许自定义过滤器,可以被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和v-bind表达式。过滤器应该被添加在JavaScript表达式的尾部,由“管道”符号指示,代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            <div>{{msg | myFilter}}</div>
        </div>
        <script>
            new Vue({
                el: "#app",
                data: {
                    msg: 'hello'
                },
                filters: {
                    myFilter(str){
                        return str.toUpperCase()
                    }
                }
            })
        </script>
    </body>
</html>