vue2
原理:在vue2中利用的是原生js下边的object.defineProperty()进行数据劫持,在通过里面的getter和setter方法,进行查看数据的修改,通过发布、订阅者模式进行数据与试图的响应式。
1.定义初始化数据
2.加工数据
为了实现响应式,在javascript中,Object.defineProperty()给每个初始数据都形成了get和set的写法,只要读取数据就会执行get方法,编辑数据执行set方法
(1)定义响应式数据
(2)get查看age属性 执行get
(3)set 修改数据的时候调用
(4) 当数据发生变化时 触发响应的监听回调(get/set),就已经实现了数据的双向绑定。
3.vue2双向绑定的缺点
(1)不能监听对象的新增属性和删除属性
(2)无法正确的监听数组的方法,当监听的下标对应的数据发生改变时
4.解决方案
(1)、重写数组或者对象
(2)、vue中 通过this.$set(目前属性,新增的属性,新增的值)来解决 注 括号是三个参数
vue3
基本原理:
1、对于基本数据类型来说,响应式依然是靠Object.defineProperty()的get和set来完成的
2、对于对象类型的数据:
- 通过Proxy代理:拦截对象中任意属性的变化,包括属性值得读写、添加、删除等操作等..
- 通过Reflect反射函数进行操作
vue3中响应式是通过函数来实现的
1.ref函数
- 作用:定义一个响应式数据
- 语法:let xxx = ref(xxx)
- 创建一个包含响应式数据的引用对象
- js中操作数据:xxx.value
- 模板中读取数据:不需要 .value 直接使用插值语法即可
- 注:接收的数据可以是基本类型也可以是对象类型
2.reactive函数
1、作用:定义一个对象类型的响应式数据(基本数据类型 最好用ref函数)
2、语法:const xxx = reactive(源对象)接收一个数组或者对象,返回一个Proxy的实例对象,简称Proxy对象
返回proxy对象
整个new Vue
阶段做了什么?
1,执行init操作。包括且不限制initLifecycle
、initState
等
2,执行mount 进行元素挂载
3,compiler步骤在runtime-only版本中没有。
- compiler步骤对template属性进行编译,生成render函数。
- 一般在项目中是在
.vue
文件开发,通过vue-loader处理生成render函数。
4,执行render 生成vnode
render例子,如下
<div id="app">{{ message }}</div>
对应手写的render函数
render (h) {
return h('div', {
attrs: {
id: 'app'
},
}, this.message)
}
5.patch 新旧vnode经过diff后,渲染到真实dom上
普通dom元素如何渲染到页面?
以下代码案例讲解更加清晰哦 就是一个初始化的Vue项目
// mian.js
import Vue from 'vue'
import App from './App.vue'
new Vue({
render: h => h(App),
}).$mount('#app')
// App.vue
<template>
<div id="app">
<p>{{ msg }}</p>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
msg: 'hello world'
}
}
}
主要讲解组件跟普通元素的不同之处 主要有2点:
1,如何生成VNode——创建组件VNode createComponent
- 区分普通元素VNode
- 普通VNode:tag是html的保留标签,如
tag: 'div'
- 组件VNode:tag是以
vue-component
开头,如tag: 'vue-component-1-App'
- 普通VNode:tag是html的保留标签,如
2,如何patch——组件new Vue到patch流程createComponent
- $vnode:占位符vnode。最终渲染vnode挂载的地方。所有的组件通过递归调用createComponent直至不再存在组件VNode,最终都会转化成普通的dom。
{
tag: 'vue-component-1-App',
componentInstance: {组件实例},
componentOptions: {Ctor, ..., }
}
3,_vnode:渲染vnode。
{
tag: 'div',
{
"attrs": {
"id": "app"
}
},
// 对应占位符vnode: $vnode
parent: {
tag: 'vue-component-1-App',
componentInstance: {组件实例},
componentOptions: {Ctor, ..., }
},
children: [
// 对应p标签
{
tag: 'p',
// 对应p标签内的文本节点{{ msg }}
children: [{ text: 'hello world' }]
}, {
// 如果还有组件VNode其实也是一样的
tag: 'vue-component-2-xxx'
}
]
}
4,Vue组件化简化流程
前面应该看的晕头转向了吧 下面我会用一个简化版的流程图进行回顾 加深理解