ref、reactive、toRef、toRefs的区别
ref
为数据添加响应式状态,返回一个具有响应式状态的副本。setup要通过.value属性来获取,在模板中则会自动带入.value。vue强烈建议用ref处理非指针类型的数据类型。
reactive
reactive方法根据传入的对象,创建返回一个深度响应式对象。响应式对象属性值改动,不管层级多深,都会触发响应式,新增和删除属性也会触发响应式。reactive只能给对象添加响应式。也不能通过点语法展开state解构,否则也会失效。
toRef
针对响应式对象的属性创建一个ref,且保持响应式,修改通过toRef创建的响应式数据,会触发UI界面的更新。toRef的本质是引用关系,与原始数据由关联。
toRefs
toRefs和toRef的区别类似于reactive和ref,可以理解成批量包装props对象,用于将响应式对象转换为结果对象,他会遍历对昂身上的所以属性,然后挨个调用toRef执行,其中结果对象的每个属性都是指向原始对象相应属性的ref,toRefs是一种用于破坏响应式对象并将其所有属性转换为ref的实用方法。
vue3中$t()
$t时挂载到Vue.prototype上的一个方法,接收一个字符串作为参。
Setup语法糖
data
起初Vue3中变量必须return出来,才能在template中使用,使用setup语法糖后,无需return。\
<script setup>
import { reactive, ref, toRefs } from 'vue'
// ref声明响应式数据,用于声明基本数据类型
const name = ref('Jerry')
// 修改
name.value = 'Tom'
// reactive声明响应式数据,用于声明引用数据类型
const state = reactive({
name: 'Jerry',
sex: '男'
})
// 修改
state.name = 'Tom'
// 使用toRefs解构
const {name, sex} = toRefs(state)
// template可直接使用{{name}}、{{sex}}
</script>
method
<template>
// 调用方法
<button @click='changeName'>按钮</button>
</template>
<script setup>
import { reactive } from 'vue'
const state = reactive({
name: 'Jery'
})
// 声明method方法
const changeName = () => {
state.name = 'Tom'
}
</script>
computed
<script setup>
import { computed, ref } from 'vue'
const count = ref(1)
// 通过computed获得doubleCount
const doubleCount = computed(() => {
return count.value * 2
})
// 获取
console.log(doubleCount.value)
</script>
watch
<script setup>
import { watch, reactive } from 'vue'
const state = reactive({
count: 1
})
// 声明方法
const changeCount = () => {
state.count = state.count * 2
}
// 监听count
watch(
() => state.count,
(newVal, oldVal) => {
console.log(state.count)
console.log(`watch监听变化前的数据:${oldVal}`)
console.log(`watch监听变化后的数据:${newVal}`)
},
{
immediate: true, // 立即执行
deep: true // 深度监听
}
)
</script>
子组件ref变量和defineExpose
在标准组件写法里,子组件的数据都是默认隐式暴露给父组件的,但在script-setup语法糖里面,所有数据只是默认return给template使用的,不会暴露到组件外,所以父组件是无法直接通过挂载ref变量获取子组件的数据。
如果要调用子组件的数据,需要先在子组件显示的暴露出来,才能正确的拿到,这个操作由defineExpose来完成。
<template>
<span>
{{ state.name }}
</span>
</template>
<script setup>
import { reactive, toRefs, defineExpose } from 'vue'
// defineExpose无需引入
// import { defineExpose, reactive, toRefs } from 'vue'
// 声明state
const state = reactive({
name: 'Jerry'
})
// 将方法、变量暴露给父组件使用,父组件才可通过ref API拿到子组件暴露的数据
defineExpose({
// 解构state
...toRefs(state),
// 声明方法
changeName () {
state.name = 'Tom'
}
})
</script>
setup中this的替换方法
getCurentInstance
通过使用vue里的getCurrentInstance方法,引用里面的proxy和ctx属性获取上下文,
注意: ctx代替this只适用于开发阶段,放在服务器上运行会出错,而proxy不会。