最近用vue3 重構vue2.x的項目,真是一坑未平,一波又起,話不多說 上代碼
<template>
<div>{{ loadingStatus }}</div>
</template>
...
setup(props, context) {
// @ts-ignore
const { proxy } = getCurrentInstance();
const typeClassName = computed(() => {
return "xb-" + props.type;
});
let loadingStatus = ref(false);
const handleClick = () => {
if (props.autoLoading) {
loadingStatus= true;
}
context.emit("click", () => {
loadingStatus= false;
});
};
return {
loadingStatus,
handleClick
};
}
乍一看是不是沒什么問題,但是視圖上loadingStatus依然是false,為什么呢,setup內部打印出為true,於是我看文檔突然。。。
因為我們在使用Vue3的時候,通常使用ref來監聽一些簡單數據類型如數字、字符串、布爾等。你可能注意到一種現象,是更改ref的值的時候,需要使用ref.value的形式,(在template中使用ref時,Vue自動幫我們添加.value了,所以不需要我們手動添加),看起來很神奇,為什么會有一個.value呢?是因為ref本質上是一個包裝過后的reactive。在你去定義ref的時候,Vue會內部幫我們包裝一下。
對於ref而言,因為ref是包裝過的reactive,所以使用reactive就可以定義ref:
let age = ref(18) // 等價於 let age = reactive({value: 18})
function ref(val) { return reactive({value: val}) }
所以最終代碼:
<template>
<div>{{ loadingStatus }}</div>
</template>
...
setup(props, context) {
// @ts-ignore
const { proxy } = getCurrentInstance();
const typeClassName = computed(() => {
return "xb-" + props.type;
});
let loadingStatus = ref(false);
const handleClick = () => {
if (props.autoLoading) {
loadingStatus.value= true;
}
context.emit("click", () => {
loadingStatus.value= false;
});
};
return {
loadingStatus,
handleClick
};
}
一句話:修改ref需要.value 而 reactive 則不用
