改变——this,data,computed,components,周期函数,$refs,props,provide/inject,$watch,$wathcEffect,$nextTick
在setup里,this不能再用了
为什么不能使用this?官方是这样说的:
在
setup()内部,this不会是该活跃实例的引用,因为setup()是在解析其它组件选项之前被调用的,
所以setup()内部的this的行为与其它选项中的this完全不同。这在和其它选项式API一起使用setup()时可能会导致混淆。
我们可以理解为:
this未指向当前的组件实例,在setup被调用之前,data,methods,computed等都没有被解析,但是组件实例确实在执行setup函数之前就已经被创建好了
作者:忘魂儿 https://www.bilibili.com/read/cv12456516 出处:bilibili
替代方法,但是不推荐在组合式中使用以下方法,(即组合式中不推荐用this,"不纯洁..等原因")
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance(); //此处一定是proxy(官网也是),网上有很多用ctx,但是ctx是获取不到的
选项式中的data换做ref,reactive定义数据
1. ref适用于定义基础数据类型的,比如string,number,boolen;在方法中使用时要通过.value获取,在html中则不需要
2. reactive适合用于定义复杂类型的数据,比如object,array;只能接收对象
3. ref也可以用于定义复杂数据,但其实对于复杂的对象,ref还是求助于reactive处理
简言之:看起来ref比reactive有更多功能,缺点就是要.value
computed选项换做函数
import { computed } from 'vue'
const doSomething = computed(() => {
do something...
})
在组合式里不用components,直接引入就可以用了
<script setup>
import TodoItem from './ToduItem.vue'
</script>
<TodoItem />
周期函数
1. 取消掉了beforeCreate, created,setup在它俩之前执行,也因此有的数据要在onMounted里取才行(当时具体情况我忘了,但是我确实遇到过)
2. 在vue2中vue3的代码是以补丁的形式加上去的,所以vue2的周期函数会比vue3先执行
3. 在vue3中vue3的先执行
选项式里获取节点的$refs在组合式
<div ref="myDiv"></div>
<script setup>
import { ref } from 'vue'
const myDiv = ref()
console.log(myDiv) //这就取到了
</script>
props在组合式通过defineProps获取
import { defineProps } from 'vue'
let props = defineProps({
msg1: { type: String, required: true }, //或者
msg2: String
})
//还可以做ts校验
interface Props{
msg1: String
msg: String
}
let props = defineProps<Props>()
provide/inject
组件间数据传输的api
和prop的不同之处:
- 父亲props要传递数据给孙子,那需要父传子,子传孙。而provide不同,一个组件provide数据后,该组件的所有子组件都可以通过inject获取到该数据
- props是单向的,父组件改数据子组件会改,但是子组件改props里的数据不会影响父组件。provide/inject不同,如果传递的是ref或者reactive类型的数据,父子组件都可以改数据,而且还实时的渲染修改后的数据
- 最好是在组合式api里用,在选项式里provide的数据好像不能实时渲染(inject的可以)。用法:
father.vue
<script setup>
import {provide} from 'vue'
let firstname = ref("李")
provide("姓", firstname) //注意此处不带.value
</script>
son.vue
<script setup>
import {inject} from 'vue'
let firstname = inject("姓")
</script>
grandSon.vue
<script setup>
import {inject} from 'vue'
let firstname = inject("姓")
</script>
watch
watch需要监听指定的ref或者reactive对象。
如果监听的值一次都没有改变,那我一次都不触发。不像watchEffect要触发一次
如果监听整个reactive对象的话,并不能打印出正确的oldvalue,而是old value也和new value一样

触发两次setName()之后发现,oldvalue 和 newvalue一样

要监听具体的属性/变量,才会打印出正确的oldvalue,newvalue


watchEffect
不需要指定监听对象,在watchEffect参数函数里用到的ref,reactive类型变量都会被自动监听
不论改变与否,我都会触发一次,如果有改变会继续触发,如果没有,就从此不触发
userinfo.age改变了,但是watchEffect里只有用到userinfo,没有用到userinfo.age则不会监听到


nextTick
在组合式中不像选项式那样有this,随时帮忙“看着”,在这里就需要把nextTick放在每一个会导致dom重新渲染的事件里
nextTick和watch不同,watch监听的是数据改变,nextTick监听的是被改的数据重新渲染到dom(在watch之后)
<script setup>
import { ref, nextTick } from 'vue'
const par = ref()
function changeMsg() {
msg.value += '~,'
console.log("before render: ", par.value.innerHTML);
nextTick(() => {
console.log("be rendered: ", par.value.innerHTML);
})
}
</script>
<p ref="par" @click="changeMsg">{{ msg }}</p>
//除了这种用法还可以同步使用:
async function changeMsg(){
msg.value += '~,'
console.log("before render: ", par.value.innerHTML);
await nextTick()
console.log("be rendered: ", par.value.innerHTML);
}
浙公网安备 33010602011771号