一、响应式
1.vue2.0使用 Object.defineProperty()
举个栗子:
<script>
let number = 10
const product = {
number,
price:5
}
let all = product.number * product.price
//当数量更改的时候
product.number = 20
console.log(all); // 打印出来是 50;但是当数量为 20的时候,all应该变为100
//vue 2 响应性核心 API
/* Object.defineProperty(obj, prop, descriptor)
obj: 要定义属性的对象
prop:要定义或修改的属性的名称或 Symbol
descriptor:要定义或修改的属性描述符
*/
Object.defineProperty(product,'number',{
get(){
console.log('我是get');
},
set(n){ //当 product.number = 20 给它赋值的时候,触发set
all = product.price * n
console.log('总价格'+ all);
}
})
</script>
vue2中的响应性是针对 具体的某一个属性来说的,这个属性具备了响应性,那么意味着这个属性被 Object.defineProperty 监听了 getter 和setter 行为。
对于vue2来说,由于js 的限制,vue不知道你为某一个对象新增了一个属性,比如说(obj.age = 30),所以age这个属性,就不能通过 Object.defineProperty 进行监听,所以age不是响应性的
2.vue3使用 Proxy
栗子:
let number = 10
const product = {
number,
price:5
}
let all = product.number * product.price
// 当数量更改的时候
product.number = 20
// console.log(all);
// vue3 的核心 proxy
/* const p = new Proxy(target, handler)
target: 目标对象
*/
/*
product: 被代理对象,不会触发set 和 get
p:代理对象
*/
const p = new Proxy(product,{
get(){
console.log('get');
},
set(target,key,value){
// console.log('set');
// console.log(target); // 被代理对象
// console.log(key);
// console.log(value);
target[key] = value
all = product.number * product.price
console.log('总价格' + all);
return true
}
因为 vue3 通过 Proxy 代理对象去实现的响应性,所以不会出现新增属性丢失响应性的问题;
通过 proxy 对象得到的响应式,不能解构,一旦解构那么会失去响应性
二、语法
- vue2 使用
options API
vue3.0 使用
composition API,组合式API
,没有this
。改变仅针对于script
setup
函数:
想要让响应式数据或方法被模板(tempalte
) 使用,那么方式分为三步:
(1)声明响应式数据或方法
①导入 reactive -- import { reactive } from 'vue'
②利用reactive 生成proxy 代理对象 --- const obj = reactive({ name : '张三' })
(2)在 setup
函数中,renturn
一个对象,对象中包含这个数据或方法
(3)在 tempalte
中使用
3. vue3.2 使用 script setup
( 重要!!!)
想要让响应式数据或方法被模板(tempalte
) 使用,那么方式分为两步:
(1.)声明响应式数据或方法 --
① reactive: 因为reactive 是基于 proxy 实现的,所以它只能声明复杂数据类 型的响应性 --- 导入reactive、生成代理对象
② ref: 可以声明 任意 数据类型的响应性 ,在script 使用 ref 声明的数据, 必须通过.value 访问 --- 导入 import { ref } from 'vue'; let name = ref('张三'); name.value = '李四'
(2.)在 tempalte
中使用
既然 vue3 的响应性是通过 proxy 实现的,那么proxy又不能监听 简单数据类型 的响应性,
如果要完成简单数据类型响应性,应该怎么办呢?
把简单数据类型包装成 复杂数据类型,然后再用proxy代理
可以理解为 :
const ref = (value) => {
const obj = {
value
}
return new Proxy(obj,{
get(target,key){
console.log('get');
return target[key]
}
})
}
const name = ref('张三')
console.log(name.value); //张三
console.log(name); // 打印出的是 被代理对象
vue内部类似于以下代码
class RefImpl{
constructor(val) { //构造函数
this.val = val
console.log(this.val);
}
// 在value 前面加上一个get 可以让name.value() === name.value
get value(){
return new RefImpl(val)
}
set value(val){
this.val = val
}
}
const ref = (val) => {
return new RefImpl(val)
}
const name = ref('张三')
console.log(name.value); //张三
name.value = '李四'
console.log(name.value);
vue3.2 中的 watch、使用
watch(
监听源,
() => {
console.log('监听源发生变化了')
},
{
deep:true,
immediate:true
}
)
webpack和vite
① vue2使用的是webpack形式去构建项目
webpack是一开始是入口文件,然后分析路由,然后模块,最后进行打包,然后告诉你,服务器准备好了可以开始干了
②vue3使用vite构建项目
先告诉你服务器准备完成,然后等你发送HTTP请求,然后是入口文件,Dynamic import(动态导入)code split point(代码分割)