## 创建工程
npm init vite-app 工程名称
## 进入工程目录
cd 工程名称
## 安装依赖
npm i
## 运行
npm run dev
const xxx = ref(initvalue)
xxx.value
{{xxx}}
Object.defineProperty()
的 get
和 set
reactive()
ref
函数)const 代理对象 = reactive(源对象)
接收一个对象(或数组),返回一个代理对象(Proxy 的实例对象,简称 Proxy 对象)new Proxy(data, {
// 拦截读取属性值
get(target, prop){
return Reflect.get(target, prop)
},
// 拦截设置属性值或添加新属性
set(target, prop){
return Reflect.set(target, prop, value)
}
// 拦截删除属性
deleteProperty(target, prop){
return Reflect.deleteProperty(target, prop)
}
})
ref 用来定义:【基本类型数据】
reactive 用来定义:【对象或数组类型数据】
备注:ref 也可以用来定义对象或数组类型数据,它内部会自动通过 reactive 转为代理对象
ref 通过
Object.defineProperty()
的 get 与 set 来实现响应式(数据劫持)。
reactive 通过使用Proxy
来实现响应式,并通过Reflect
操作源对象内部的数据。
ref 定义的数据:操作数据需要
.value
,读取数据时模板中直接读取不需要.value
reactive 定义的数据:操作数据与读取数据,均不需要.value
props:值为对象,包含:组件外部传递过来,且组件内部声明接受了的属性。
context:上下文对象
attrs:值为对象,包含:组件外部传递过来,但没有在 props 配置中声明的属性,相当于
this.$attrs
slots:收到的插槽内容,相当于this.$slots
emit:分发自定义事件的函数,相当于this.$emit
import { computed } from 'vue'
setup(){
...
// 计算属性——简写(没有考虑计算属性被修改的情况)
let fullName = computed(() => {
return person.firstName + '-' + person.lastName
})
// 计算属性——完整
let fullName = computed({
get(){
return person.firstName + '-' + person.lastName
},
set(value){
const nameArr = value.split("-")
person.firstName = nameArr[0]
person.lastName = nameArr[1]
}
})
与 Vue2 中的 watch 配置功能一致
两个小坑:
监视 reactive 定义的响应式数据时:oldValue 无法正确获取、强制开启了深度监视(deep 配置失效)
监视 reactive 定义的响应式数据中某个属性时:deep 配置有效。
// 情况一:监视【一个】 ref 定义的响应式数据
watch(sum, (newValue, oldValue) => {
console.log('sum变化了', newValue, oldValue)
}, {immediate: true})
// 情况二:监视【多个】 ref 定义的响应式数据
watch([sum, msg], (newValue, oldValue) => {
console.log('sum 和 msg 变化了', newValue, oldValue)
})
// 情况三:监视 reactive 定义的响应式数据,无法正确获得 oldValue,强制开启深度监视
watch(person, (newValue, oldValue) => {
console.log('person 变化了', newValue, oldValue)
}.{immediate: true, deep: false}) // 此处的 deep 配置失效
// 情况四:监视 reactive 定义的响应式数据中的【某个】属性
watch(() => person.job, (newValue, oldValue) => {
console.log('person的job变化了', newValue, oldValue)
}.{immediate: true, deep: true}) // 此处的 deep 配置奏效
// 情况五:监视 reactive 定义的响应式数据中的【某些】属性
watch([() => person.name, () => person.age], (newValue, oldValue) => {
console.log('person的name或age变化了', newValue, oldValue)
})
但 computed 注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
而 watchEffect 更注重的是过程(回调函数的函数体),所以不用写返回值。
// watchEffect 所指定的回调中用到的数据只要发生变化,则直接重新执行回调
watchEffect(() => {
const x1 = sum.value
const x2 = person.name
console.log("watchEffect配置的回调执行了")
})
Vue3 中可以继续使用 Vue2 中的生命周期钩子,但有两个被更名:
beforeDestory
改名为beforeUnmounted
destory
改名为unmounted
Vue3 也提供了 Composition API 形式的生命周期钩子,与 Vue2 中的钩子对应如下:
beforeCreate ===> setup()
create ===> setup()
beforeMount ===> onBeforeMount
mounted ===> onMounted
beforeUpdate ===> onBeforeUpdate
updated ===> onUpdate
beforeUnmount ===> onBeforeUnmount
unmounted ===> onUnmounted
Vue2 中的 beforeCreate
和 create
不能写进 setup 中
setup 中的钩子比 Vue2 中的钩子优先级高
const name = toRef(person, 'name')
toRefs
与 toRef
功能一致,但可以批量创建多个 ref 对象,语法:toRefs(person)