vue性能提升-非响应式数据

7,626 阅读2分钟

vue中的数据来源包括data,computed,实例外,自定义options,开发中多将数据定义在data选项中,data中的数据都是响应式的,然鹅有一些数据并不需要进行响应式,如定时器或常量,总结以下几种方案来避开vue修改数据的访问器属性

1. 数据放在vue实例外

const test = ['1', '2', '3']
export default {
// options
}

弊端: vue template中访问不到数据

2. created, mounted钩子函数中定义

created() {
    // 注意data中不要声明该变量名
    this.testData = 'testData'
}

3. 自定义Options

<template>
  <div>{{ $options.myOptions.test }}</div>
</template>
export default {
    data() {
    },
    // 自定义options和data同级
    // 取值时: this.$options.myOptions.test
    myOptions: {
        test: '111'
    }
}

4. Object.freeze()

冻结对象,禁止对该对象的属性进行修改。这个方法返回传递的对象,而不是创建一个被冻结的副本

let a = { prop: 1, prop2: 2 } // undefined
Object.freeze(a) // {prop: 1, prop2: 2}
a.prop = 3 // 3
a // {prop: 1, prop2: 2}

// Object.freeze()冻结的是值,仍然可以将变量的引用替换掉
a = {prop44: 44} // {prop44: 44}
a // {prop44: 44}

// 注意区分const和Object.freeze
// const表示声明常量 不能再赋值 且声明时必须初始化
const TEST = 1
TEST = 2 // 报错:TypeError: Assignment to constant variable.
  • Object.freeze是浅冻结只冻结一层,如果存在嵌套对象则深层对象仍然可以改变,深冻结函数递归实现

    function deepFreeze (obj) {
      let names = Object.getOwnPropertyNames(obj)
      names.forEach(name => {
        var property = obj[name]
        if (typeof(property) === 'object' && property !== null) {
          deepFreeze(property)
        }
        return Object.freeze(property)
      })
    }
    

扩展

Object.seal()密封对象, 被密封的对象不能添加新的属性,不可配置(属性变的不可删除,以及一个数据属性不能被重新定义成为访问器属性)

总结: 不需要响应式的数据务必不要挂在data上, 添加gettersetter影响性能, 如第三方库, 定时器, 常量等

参考链接