Vue3.2.x中的小技巧及注意事項(xiàng)總結(jié)
前言
vue3在2022年的2月7號成為了vue默認(rèn)版本,并且隨之而來的還有vue3的新文檔, 并且從實(shí)際使用的角度來說, vue3確實(shí)比vue2使用起來更加的舒服,所以覺得經(jīng)過一段時間的使用,來分享一下使用過程中的小技巧以及注意事項(xiàng)。
小技巧
關(guān)于減少.value的使用
使用watch來監(jiān)聽Ref數(shù)據(jù)的時候, 可以做到省略.value的使用, 例如:
const value = ref(1); // 省略() => value.value watch(value, (v) => { // 省略v.value console.log(v); }, { immediate: true }); setTimeout(() => { value.value = 2; }, 1000);使用vue3.2.25以上版本提供的$ref, 還是跟上面的代碼實(shí)現(xiàn)一樣的功能
該功能是一個實(shí)驗(yàn)性能, 需要相應(yīng)的配置, 這里以vite為例, 需要在vite.config.ts的vue plugin中添加一個reactivityTransform屬性, 請看下面的配置。如果用的是其他工程化工具, 可以參考vue的新文檔, 文檔中有詳細(xì)的說明。
plugins: [ vue({ reactivityTransform: true, }) ]const count = $ref(1); // 增加了() => count watch( () => count, (v) => { console.log(v); }, { immediate: true } ); setTimeout(() => { // 省略了count.value count++; }, 1000);
輸出:

這里需要說明一下使用$ref需要注意的問題, 首先該功能是一個實(shí)驗(yàn)性性能, 需要相應(yīng)的配置, 并且vue的文檔中指出該方法是一個編譯器宏使用時無需引入, 但為了ts和編輯器的無端報錯, 個人還是喜歡顯示的引入, 就像這樣
import { $ref } from 'vue/macros'接著再說一下$ref的另一個很嚴(yán)重的問題, 就是丟失響應(yīng)式, 為什么會丟失響應(yīng)式呢? 其實(shí)這部分官方文檔已經(jīng)做出了說明, 請看下面的代碼
// App.vue
import { $ref } from "vue/macros";
import { useApp } from "./App";
let count = $ref(1);
useApp(count);
setTimeout(() => {
console.log("change");
count++;
}, 1500);
// App.ts
import { watch } from "vue";
export const useApp = (count) => {
watch(
() => count,
(c) => {
console.log("watch", c);
},
{ immediate: true }
);
};上面代碼中App.ts里面的watch只會執(zhí)行一次, 很明顯, count丟失了響應(yīng)性
如何解決這個問題呢?請看下面的代碼:
// App.vue
import { $ref, $$ } from "vue/macros"; // 引入$$
import { useApp } from "./App";
let count = $ref(1);
useApp($$(count)); // useApp(count) --> useApp($$(count))
setTimeout(() => {
console.log("change");
count++;
}, 1500);
// App.ts
import { watch } from "vue";
export const useApp = (count) => {
watch(
count, // () => count --> count
(c) => {
console.log("watch", c);
},
{ immediate: true }
);
};可以看到, 我們在傳遞$ref值的時候 需要用一個$$方法包裹一下, 這樣就不會丟失響應(yīng)性了, 具體更詳細(xì)的使用方法, 還是希望大家仔細(xì)閱讀一下vue的新文檔
關(guān)于減少import導(dǎo)入語句
發(fā)現(xiàn)這個功能是無意間的,在使用element-plus的時候, 查看elment-plus官網(wǎng) 指南 快速開始, 其中提到了自動導(dǎo)入的功能, 文檔中說的是 首先下載對應(yīng)的插件
npm install -D unplugin-vue-components unplugin-auto-import, 然后如果使用的是vite的話, 需要在vite.config中添加幾條配置, 就像下面一樣:
// vite.config.ts
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default {
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
}因?yàn)楹闷嫒タ戳诉@兩個包的介紹, 發(fā)現(xiàn)不光可以自動導(dǎo)入組件, 還可以自動導(dǎo)入方法, 例如心細(xì)的小伙伴已經(jīng)發(fā)現(xiàn), .value那部分的代碼 不管是ref還是$ref我都沒有寫import語句來導(dǎo)入, 這里就用到了這兩個插件, 我們來看一下如果要自動導(dǎo)入vue的方法對應(yīng)的配置。
// vite.config.ts
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default {
plugins: [
// ...
AutoImport({
imports: ["vue", "vue/macros"], // 增加這一行代碼
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
}在這樣的配置下就可以愉快的減少import導(dǎo)入了。
關(guān)于在script setup中聲明組件名字
在script setup的方式剛發(fā)布的時候, 我就一直在糾結(jié)這個問題, 因?yàn)轫?xiàng)目中有很多的遞歸組件, 如果沒有name來做標(biāo)識的話, 勢必會產(chǎn)生問題
- 剛開始vue的issues中其他用戶提出的解決方式是在.vue文件中定義兩個script標(biāo)簽, 其中一個用來定義組件的name, 而另一個用來編寫組件邏輯, 例如下面這樣:

這種方式相信對于一些有強(qiáng)迫癥或者完美主義者來說是完全不能接受的, 包括我 也不能接受, 所以在vue的issues中就有一個用戶開發(fā)了一個插件來解決這個問題。
- unplugin-vue-define-options插件
下載插件
npm i unplugin-vue-define-options -D我們直接來看一下這個插件的使用方式:
在vite中使用
// vite.config.ts
import DefineOptions from 'unplugin-vue-define-options/vite'
import Vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [Vue(), DefineOptions()],
})ts項(xiàng)目需要在tsconfig.json中添加一個配置
{
"compilerOptions": {
"types": ["unplugin-vue-define-options"]
}
}使用方式
<script setup lang="ts">
defineOptions({
name: 'App'
})
</script>該插件的功能遠(yuǎn)遠(yuǎn)不止定義組件的name, 還可以定義組件的props、emits、render等,有興趣的小伙伴可以去看一下,感覺可以利用這一特性才做一些騷操作,不過尤大大覺得這種方式不太好。
注意事項(xiàng)
關(guān)于響應(yīng)式的問題
- props不能使用解構(gòu)的方式來使用, 例如下面的例子
// Parent.vue
<template>
<ChildVue ref="childRef" v-bind="data" />
</template>
<script setup lang="ts">
import { reactive } from 'vue';
import ChildVue from "./views/Child.vue";
const data = reactive({ name: 'veloma' });
setTimeout(() => {
data.name = 'timer';
}, 1500);
</script>
// Child.vue
<template>
<div>{{ data.name }}</div>
</template>
<script lang="ts" setup>
const props = defineProps<{
name: string;
}>();
const data = reactive({ ...props });
</script>上面的例子在子組件中, 通過reactive將props進(jìn)行了解構(gòu), Parent組件中1.5s后更新name, 這時我們會發(fā)現(xiàn)Child組件中的模板并不會產(chǎn)生更新, 那如何來解決這個問題呢?
首先有兩種解決方式:1.使用3.2.25或以上的版本直接解構(gòu)defineProps, 例如這樣
const { name } = defineProps<{ name: string }>()2.或者通過computed來解構(gòu), 例如
const data = computed(() => ({ ...props }))
模板循環(huán)中加不加key的問題
關(guān)于這個問題, 在vue新文檔中有提到這樣一句話

只看這句話的話是沒有任何問題的,但在實(shí)際的使用過程中, 舉個??:
// Parent.vue
<template>
<div>
<ChildVue v-for="item of list" v-bind="item"></ChildVue>
<button @click="onClick">按鈕</button>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import ChildVue from "./views/Child.vue";
const list = ref([{ name: "veloma" }, { name: "timer" }, { name: "lucy" }]);
const onClick = () => {
console.log('點(diǎn)擊');
const item = { ...list.value[0] };
item.name = "veloma1111";
list.value[0] = item;
};
</script>
// Child.vue
<template>
<div>{{ name }}</div>
</template>
<script lang="ts" setup>
import { onMounted } from "vue";
defineProps<{
name: string;
}>();
onMounted(() => {
console.log("mounted");
});
</script>我們看上面的代碼會發(fā)現(xiàn)功能非常的簡單, 子組件接收一個name屬性, 父組件循環(huán)渲染子組件, 且子組件中有一個onMounted鉤子, 我們希望的是, 當(dāng)點(diǎn)擊按鈕的時候觸發(fā)子組件的onMounted鉤子, 乍一看是沒有任何問題的, 但實(shí)際是不會觸發(fā)的, 看結(jié)果:

我們發(fā)現(xiàn)click事件確實(shí)觸發(fā)了, 而數(shù)據(jù)也確實(shí)變化了, 頁面也變化了, 但就是沒有觸發(fā)子組件的onMounted鉤子, 那這是怎么回事呢?實(shí)際上在vue處理這一步的時候 重用了之前name為veloma的Child組件, 重用不會產(chǎn)生掛載, 也就不會觸發(fā)onMounted鉤子, 那要怎么解決呢?其實(shí)很簡單, 只需要給Child組件一個key即可.


總結(jié)
到目前為止其實(shí)還有好多公司沒有升級到vue3, 但是我相信 在不久的將來 甚至就是今年, vue3 + vite + typescript 一定會覆蓋大部分的公司, 所以建議小伙伴們還是需要仔細(xì)認(rèn)真的多看兩遍vue的新文檔, 系統(tǒng)的了解一下vue3的變化為以后的升級做好準(zhǔn)備, 加油!
到此這篇關(guān)于Vue3.2.x中的小技巧及注意事項(xiàng)的文章就介紹到這了,更多相關(guān)Vue3.2.x小技巧內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue3中?provide?和?inject?用法小結(jié)
父子組件傳遞數(shù)據(jù)時,使用的是props和emit,父傳子時,使用的是?props,如果是父組件傳孫組件時,就需要先傳給子組件,子組件再傳給孫組件,如果多個子組件或多個孫組件使用時,就需要傳很多次,會很麻煩,這篇文章主要介紹了vue3中?provide?和?inject?用法,需要的朋友可以參考下2023-11-11
Vue 使用 Mint UI 實(shí)現(xiàn)左滑刪除效果CellSwipe
這篇文章主要介紹了Vue 使用 Mint UI 實(shí)現(xiàn)左滑刪除效果CellSwipe,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2018-04-04
vue 動態(tài)改變靜態(tài)圖片以及請求網(wǎng)絡(luò)圖片的實(shí)現(xiàn)方法
下面小編就為大家分享一篇vue 動態(tài)改變靜態(tài)圖片以及請求網(wǎng)絡(luò)圖片的實(shí)現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02
vue之el-menu-item如何更改導(dǎo)航菜單欄選中的背景顏色
這篇文章主要介紹了vue之el-menu-item如何更改導(dǎo)航菜單欄選中的背景顏色問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05
vue報錯之exports is not defined問題的解決
這篇文章主要介紹了vue報錯之exports is not defined問題的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
Vue 實(shí)時監(jiān)聽窗口變化 windowresize的兩種方法
這篇文章主要介紹了Vue 實(shí)時監(jiān)聽窗口變化 windowresize的兩種方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-11-11
詳解mpvue中小程序自定義導(dǎo)航組件開發(fā)指南
這篇筆記主要記錄一下基于mpvue的小程序中實(shí)現(xiàn)自定義導(dǎo)航的思路及應(yīng)用。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-02-02

