IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue实例初始化循序 -> 正文阅读

[JavaScript知识库]vue实例初始化循序

vue数据初始化

vue的基层响应式的逻辑是通过Object.defineProperty()函数控制的,先来说一说该方法的知识点:

1. Object.defineProperty()

1.1 对象的定义与赋值

经常使用的定义与赋值方法obj.prop =value或者obj['prop']=value

let obj = {}
obj.name = 'jack'
//或者
obj['name'] = 'tom'

1.2 Object.defineProperty()语法说明

Object.defineProperty(obj, prop, desc)

作用该方法的作用就是在对象上定义一个新属性或者修改一个已有的属性。

参数:

  • obj 需要定义属性的当前对象
  • prop 当前需要定义的属性名
  • desc 属性描述符

1.3 属性的特性以及内部属性

javacript 有三种类型的属性

  • 命名数据属性:拥有一个确定的值的属性。这也是最常见的属性
var flight = {
    airline: "Oceanic",
    number: 815,
    departure: {
        IATA: "SYD",
        time: "2004-09-22 14:55",
        city: "Sydney"
    },
    arrival: {
        IATA: "LAX",
        time: "2004-09-23 10:42",
        city: "Los Angeles"
    }
};
  • 命名访问器属性:通过gettersetter进行读取和赋值的属性, 就跟java类的set, get方法一样
var people = {
    name: "lyx",
    get value() {
        return "uuuuu";
    },
    set value(value) {
        console.log("==========")
        this.name = value;
    }
};

console.log(people.name); //lyx
console.log(people.value);//uuuuu //调用访问器属性value(getter)
people.value = "12344"; //调用访问器属性value(setter)
console.log(people.name); //12344
  • 内部属性:由JavaScript引擎内部使用的属性,不能通过JavaScript代码直接访问到,不过可以通过一些方法间接的读取和设置。比如,每个对象都有一个内部属性[[Prototype]],你不能直接访问这个属性,但可以通过Object.getPrototypeOf()方法间接的读取到它的值。

1.4 属性描述符

Object.defineProperty()为对象定义属性,有两种形式,且不能混合使用,分别为数据描述符和存取描述符

1.4.1 数据描述符

value: props的值

writable : 是否可写

 let Person = {}
 Object.defineProperty(Person, 'name', {
     value: 'jack',
     writable: false
 })
console.log(Person.name)
// => jsck
Person.name = 'tom'
// =>TypeError: Cannot assign to read only property 'name' of object '#<Object>'"
 let Person = {}
 Object.defineProperty(Person, 'name', {
     value: 'jack',
     writable: true
 })
console.log(Person.name)
// => jsck
Person.name = 'tom'
console.log(Person.name)
// => tom

一些描述符的默认值这是不仅数据描述还有存取描述符

属性名默认值属性描述
valueundefinedprops的值
getundefined赋值的方法
setundefined取值的方法
writablefalse是否可写
enumerablefalse属性是否会出现在for in 或者 Object.keys()的遍历中
configurablefalse属性是否配置,以及可否删除
1.4.2 存取描述符 getter setter
  • get: 给一个属性提供getter方法,默认undefined

  • set:给一个属性提供setter方法,默认undefined

let Person = {}
let temp = 'bobo'
Object.defineProperty(Person, 'name', {
    get() {
        return temp
    },
    set(val) {
        temp = val
    }
})
console.log(Person.name)
// => bobo
Person.name = 'tom'
console.log(Person.name)
// => tom
1.4.3 存取描述符和数据描述符都具有下面的描述符
  • configrable 描述属性是否配置,以及可否删除
  • enumerable 描述属性是否会出现在 for in 或者 Object.keys() 遍历中

当 writable 为true , configurable 为false时 ,可以重新定义props

let Person = {}
Object.defineProperty(Person, 'name', {
    value: 'rose',
    configurable: false,
    writable: true
})
Object.defineProperty(Person, 'name', {
    value: 'jack'
})
console.log(Person.name)
// = > jack

当 writable 为false configurable 为false时 ,不可以重新定义props

let Person = {}
Object.defineProperty(Person, 'name', {
    value: 'rose',
    configurable: false,
    writable: false
})
Object.defineProperty(Person, 'name', {
    value: 'jack'
})
// => TypeError: Cannot redefine property: name"
console.log(Person.name)

当 writable 为false configurable 为true 时 , 可以通过在原型链上重新定义props

let Person = {}
Object.defineProperty(Person, 'name', {
    value: 'rose',
    configurable: true,
    writable: false
})
Object.defineProperty(Person, 'name', {
    value: 'jack'
})
console.log(Person.name)
//=> jack

还有一点:configurable 为 false 时不可以删除对象上的该属性

writableconfigurable讲义
truefalseprops可以重新定义,不能删除(configurable的不能删除属性的定义好使,但是不能重新定义props被忽略了)
falsefalseprops不能重新定义也不能删除
falsetrueprops可以重新定义,也可以被删除
let Person = {}
Object.defineProperty(Person, 'name', {
    value: 'rose',
    configurable: false,
    writable: true
})
delete Person.name
//=> "TypeError: Cannot delete property 'name' of #<Object>"
1.4.4 enumerable 代码片段分析
let Person = {}
Object.defineProperty(Person, 'name', {
    value: 'rose',
    enumerable: false
})
Person.age = '23'
console.log(Person)
// =>{age: '23', name: 'rose'}
for (let item in Person) {
    console.log(item)
}
//=> age

属性的enumerable描述符为false时不能被遍历

Tips: 数据的定义方法的区别

涨知识
let Person = {}
Person.render = 'male'
//等价于
Object.defineProperty(Person, 'render', {
    value: 'male',
    writable: true,
    configurable: true,
    enumerable: true
})
let Person = {}
Object.defineProperty(Person, 'render', {
    value = 'female'
})
//等价于
Object.defineProperty(Person, 'render', {
    value: 'female',
    writable: false,
    configurable: false,
    enumerable: false
})
1.4.5 不变性
1.4.5.1 对象常量

常量属性等价于 不可修改,不可重新定义或者删除 writable false, configurable false

1.4.5.2 禁止扩展 Object.preventExtensions()

禁止对象添加新属性并且保留已有属性 — Object.preventExtensions()

let Person = {}
Object.defineProperty(Person, 'name', {
    value: 'rose'
})
Object.preventExtensions(Person)
Person.age = '23'
// = >"TypeError: Cannot add property age, object is not extensible"
console.log(Person)
1.4.5.3 密封 Object.seal()

Object.seal() = Object.preventExtension() + configurable: false

除了可以修改对象的已有属性的值,不能新添属性,也不能删除属性。

1.4.5.4 冻结 Object.freeze()

Object.freeze() = Object.seal() + writable: false

对冻结的对象不能删除,不能新添属性,也不能修改属性的值。

这个方法是你可以应用在对象上级别最高的不可变性,它会禁止对于对象本身及其任意直接属性的修改(但是这个对象引用的其他对象是不受影响的)。你可以深度冻结一个对象,具体方法为,首先这个对象上调用Object.freeze()然后遍历它引用的所有对象,并在这些对象上调用Object.freeze()。但是一定要小心,因为这么做有可能会无意中冻结其他共享对象。

2. Vue变化侦测

Vue的数据侦测是通过对数据变化的属性的拦截进行的;

2.1 Object的变化侦测

vue的数据驱动视图的首要关键点在于我们如何知道数据发生了变化。

对于对象而言,JS提供了Object.defineProperty方法,可以通过该方法的get给对象取值,通过set给对象赋值,同样通过set方法知道数据发生了变化。

let car = {}
let val = 3000
Object.defineProperty(car, 'price', {
  enumerable: true,
  configurable: true,
  get(){
    console.log('price属性被读取了')
    return val
  },
  set(newVal){
    console.log('price属性被修改了')
    val = newVal
  }
})

3. vue生命周期

在这里插入图片描述

从图中我们可以看到,Vue实例的生命周期大致可分为4个阶段:

  • 初始化阶段:为Vue实例上初始化一些属性,事件以及响应式数据;
  • 模板编译阶段:将模板编译成渲染函数;
  • 挂载阶段:将实例挂载到指定的DOM上,即将模板渲染到真实DOM中;
  • 销毁阶段:将实例自身从父组件中删除,并取消依赖追踪及事件监听器;

3.1 初始化阶段 new Vue

Vue实例的生命周期分为上面的四个阶段,其中初始化阶段基本就做两部分事情

  • 创建一个实例 new Vue()
  • 对创建的实例对象初始化一些事件,属性,响应式数据等;

3.1.1 new Vue()

创建一个实例Vue

function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
}

Vue类的构造函数调用了init函数:

this._init(options)

调用原型上的_init(options)方法并把用户所写的选项options传入。那这个_init方法是从哪来的呢?在Vue类定义的下面还有几行代码,其中之一就是:

initMixin(Vue)

initMixin的源码如下

export function initMixin (Vue) {
  Vue.prototype._init = function (options) {
    const vm = this
    vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
    )
    vm._self = vm
    initLifecycle(vm) //初始化生命周期
    initEvents(vm)  // 初始化事件
    initRender(vm)  //初始化渲染
    callHook(vm, 'beforeCreate')
    initInjections(vm) // 初始化injections resolve injections before data/props
    initState(vm)   //初始化 props,methods,data,computed,watch
    initProvide(vm) //初始化provide resolve provide after data/props
    callHook(vm, 'created')

    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }
  }
}

除了调用初始化函数来进行相关数据的初始化之外,还在合适的时机调用了callHook函数来触发生命周期的钩子 ----->在所有的初始化工作都完成以后,最后判断用户是否传入了el选项如果传入了则调用$mount函数进入模板编译与挂载阶段,如果没有传入el选项,则不进入下一个生命周期阶段,需要用户手动执行vm.$mount方法才进入下一个生命周期阶段。

4.总结

Vue生命周期顺序:

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed

Vue生命周期分为四个阶段:

  • 初始化阶段
  • 模板编译阶段
  • 挂载阶段
  • 销毁阶段

Vue初始化阶段中类的执行顺序:

new Vue

  • _init(options)
    • initLifecycle
    • initEvents
    • initRender
    • callHook(vm, ‘beforeCreate’)
    • initInjections
    • initState
      • initProps
      • initMethods
      • initData
      • initComputed
      • initWatch
    • initProvide
    • callHook(vm, ‘created’)

因此,一个组件中各个属性的执行循序为:

  • inject
  • props
  • method
  • data
  • computed
  • watch
  • provide
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-02 14:34:58  更:2021-10-02 14:35:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 0:44:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码