Vue.js数据、方法与生命周期

455 阅读4分钟

Vue.js数据

Vue.js数据同步

对于Vue.js框架编程而言,当创建一个新的Vue实例对象时,其会将数据(data)对象中的所有property 属性加入到 Vue.js 框架的响应式系统当中去。该操作带来的最直接效果就是,当这些 property 属性值发生改变时,视图(view)将会随之发生“响应”——也就是同时更新为新匹配的属性值。

Vue.js数据冻结

Vue.js数据“同步更新”的功能很实用,页面渲染效果也很惊艳。不过,我们不总是需要全部数据都保持同步更新,Vue.js框架为数据对象定义了“冻结”方法,可以实现阻止property属性同步更新的功能。 Object.freeze()就会阻止修改现有的property属性,也就意味着Vue.js的视图响应系统无法追踪property属性的变化

应用场景: 如果你有一个巨大的数组或Object,并且确信数据不会修改,使用Object.freeze()可以让性能大幅提升。在我的实际开发中,这种提升大约有5~10倍,倍数随着数据量递增,

对于纯展示的大数据,都可以使用Object.freeze提升性能。

Object.freeze()冻结一个对象有什么意义?
Object.freeze()方法可以冻结一个对象 ,一个被冻结的对象再也不能被修改

  • 不能添加新属性
  • 不能删除已有属性
  • 不能修改已有属性的可枚举性、可配置性、可写性
  • 不能修改已有属性的值
  • 不能修改原型

使用实例
juejin.cn/post/684490…

Vue.js实例 property 属性

除了Vue数据property属性之外,Vue.js 框架还定义了一个非常有用的“Vue实例property属性”的概念。
需要注意的是,在使用该功能时必须要加上 “$” 符号,主要是便于与用户定义的数据property属性进行区分。

<script>
        var oNum = {
            n: 1
        };

        var vm = new Vue({
            el: '#id-div-number',
            data: {
                dNum: oNum
            }
        })
         
        // console.log(vm.$el);
        // console.log(vm.$data.dNum.n); 
    </script>

Vue.js方法

观察属性方法

Vue.js框架设计了一个$watch方法,用于“观察”Vue实例上的属性是否发生变化。
这里的属性变化,具体可以是一个属性表达式的变化,也可以是稍微复杂的一个函数计算结果的变化.如果$watch方法观察到了变化,就会通过一个回调函数得到两个参数,分别表示变化后的新值和变化前的旧值

$watch方法基本语法格式

语法: vm.$watch(expOrFn,callback,[options])
参数说明:
{string | Function} expOrFn
{Function | Object} callback
返回值:{Function} unwatch //返回一个取消观察函数,用来停止触发回调

实例:

 <div id="id-div-counter">
        Current counter is&nbsp;&nbsp;&nbsp;&nbsp;<b>{{ counter }}</b>.
    </div>
    <br>
    <div>
        Click "Start Watch" to start watch & add counter:
        <input type="button" id='id-btn-start-watch' value='Start Watch' onclick="onBtnStartWatch(this.id)" /><br><br> Click "Cancel Watch" to stop watch:
        <input type="button" id='id-btn-cancel-watch' value='Cancel Watch' onclick="onBtnCancelWatch(this.id)" /><br><br>
    </div>
    <script>
        // define Vue entry
        var vm = new Vue({
            el: '#id-div-counter',
            data: {
                counter: 1
            }
        })

        // define watch on counter  
        // counter发生变化触发函数
        var thewatch= vm.$watch('counter', function(newVal, oldVal) {
            console.log("counter from " + oldVal + " turns to " + newVal + ".");
        })

        // start watch
        function onBtnStartWatch(thisid) {
            vm.$data.counter += 1;
            console.log('counter = ' + vm.$data.counter);
        }

        // cancel watch
        //返回一个取消观察函数,用来停止触发回调
        function onBtnCancelWatch(thisid) {
            thewatch();
        }
    </script>

事件触发方法

Vue.js框架设计了一个$emit事件触发方法,用于Vue实例上定义的事件。
$emit方法基本语法格式

语法:vm.$emit(eventName,[...args])
参数说明:
{string} eventName //事件名称
[...args]          //附加参数

自定义事件方法

Vue.js 框架还设计了一组自定义事件触发方法($on和$once),用于触发Vue实例上用户自定义的事件。
其中,$once方法只能触发一次,而$on方法在触发次数上是没有限制的。

$on基本语法格式

语法:vm.$on(event,callback)
参数说明:
{string | Array<string>} event   //数组只在 2.2.0+版本中支持
{Function} callback              //回调函数

在Vue.js框架中,还定义了一个类似的$once自定义事件。二者的区别主要就体现在触发次数上,$once自定义事件只能触发一次$once基本语法格式

语法:vm.$once(event,callback)
参数说明:
{string} event
{Function} callback //回调函数

Vue.js生命周期

Vue.js生命周期是创建Vue.js应用的核心基础

Vue.js生命周期图示

在Vue.js应用中,每个Vue实例在被创建(new Vue())时,都要经过一系列的初始化过程,例如:设置数据监听、编译模版、将实例挂载在DOM上,以及在数据变化时更新DOM等。一般地,在前端应用框架中将这个过程称为应用的“生命周期”。
同时,在Vue应用的“生命周期”过程中,会根据进程演化的不同阶段定义一组相关过程方法(回调函数的形式)。前端框架会将这组过程方法称为“生命周期的钩子函数”,所谓“钩子函数”就是给用户提供了在这些回调函数中添加自定义代码的机会。因此,这些“生命周期的钩子函数”类似于事件方法中的回调函数,只不过是只有存在于前端框架的“生命周期”中才会又意义。

Vue.js框架的“生命周期”的详细内容

如图所示,从Vue实例的创建(“new Vue()”)开始,其“生命周期”就按部就班地开始了。
列举几个最常用的“生命周期”阶段进行介绍:

  • beforeCreate: 在Vue实例初始化之后,在数据观测(data observer)和(event/watcher)事件配置之前调用。

    初始化 一些默认的声明周期函数和默认的事件
    这时候,data和methods中的数据都没初始化

  • created:在Vue实例创建完成后被立即调用。

    初始化数据 data和methods中的数据都被初始化好了

  • brforeMount: 在Vue实例挂载开始之前被调用,此时相关的render函数首次被调用。

    编译模板 即 <div id=“app”>{{msg}} </div> -> 在内存中生成一个编译好的最终模板字符串 -> 把这个模板字符串渲染为内存中dom   注意:只是在内存中渲染好了模板,并没有把模板挂载到页面上去,此时 页面还是旧的, 简单的说 结果就是在内存中渲染了一个 <div id=“app”>ok</div> 的dom元素,但是页面上还是 <div id=“app”>{{msg}} </div>

  • mounted:在Vue实例挂载后调用,这是el已被新创建的vm.$el替换了。

    将编译好的模板真实提换到页面中去

    即 将内存中渲染好的dom元素即 < div id=“app”>ok< /div>已经 提换了页面上的 < div id=“app”>{{msg}} < /div>运行

  • beforeUpdate: 在数据更新时调用,发生在虚拟DOM打补丁之前。

    页面上的数据还是旧的,但是data中的数据都是最新的,页面和最新的数据尚未保存同步

  • updated: 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子函数。

    页面上的数据和data中的数据都是最新的,页面和最新的数据保存同步

  • avtivated: 被 keep-alive 缓存的组件激活时调用。

  • deactivated:被 keep-alive缓存的组件停用时调用。

  • beforeDestroy:在Vue实例销毁之前调用,在这一阶段的Vue实例仍然完全可用。

    销毁之前,实例上的data和所有methods,以及过滤器、指令。。。都处于可用状态,还未真正销毁

  • destroyed:在Vue实例销毁后调用。该钩子函数被调用后,对应Vue实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都会被销毁。

    销毁,实例上的data和所有methods,以及过滤器、指令。。。都处于不可用状态

<script>
  // define Vue entry
  var vm = new Vue({
      el: '#id-div-vue-lifecycle',
      data: {
          msg: ''
      },
      beforeCreate: function() {
          // this.$data.msg += 'beforeCreate' + '<br/>';    //'msg' of undefined"
          console.log('Lifecycle hook --- beforeCreate.');
          console.log('$el: ' + this.$el);        //$el: undefined
          console.log('$data: ' + this.$data);    //$data: undefined
      },
      created: function() {
          // this.$data.msg += 'created' + '<br/>';
          console.log('Lifecycle hook --- created.');
          console.log('$el: ' + this.$el);              //$el: undefined
          console.log('$data: ' + this.$data);          //$data: [object Object]
      },
</script>            

vue生命周期在真实场景下的业务应用

  • beforeCreate 可以在此时加一些loading效果,在created时进行移除
  • created:进行ajax请求异步数据的获取、初始化数据
  • mounted 当需要操作dom的时候执行,可以配合$.nextTick 使用进行单一事件对数据的更新后更新dom
  • updated:任何数据的更新,如果要做统一的业务逻辑处理
  • watch:监听具体数据变化,并做相应的处理