新聞中心
- Vue3
- Vite
- VueRouter
- Pinia
- ElementPlus
一、Vue3
1. Vue2.x 和 Vue3.x 生命周期方法的變化
文檔地址:https://v3.cn.vuejs.org/guide/composition-api-lifecycle-hooks.html

城固ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!
Vue2.x 和 Vue3.x 生命周期方法的變化蠻大的,先看看:
|
2.x 生命周期 |
3.x 生命周期 |
執(zhí)行時間說明 |
|
beforeCreate |
setup |
組件創(chuàng)建前執(zhí)行 |
|
created |
setup |
組件創(chuàng)建后執(zhí)行 |
|
beforeMount |
onBeforeMount |
組件掛載到節(jié)點上之前執(zhí)行 |
|
mounted |
onMounted |
組件掛載完成后執(zhí)行 |
|
beforeUpdate |
onBeforeUpdate |
組件更新之前執(zhí)行 |
|
updated |
onUpdated |
組件更新完成之后執(zhí)行 |
|
beforeDestroy |
onBeforeUnmount |
組件卸載之前執(zhí)行 |
|
destroyed |
onUnmounted |
組件卸載完成后執(zhí)行 |
|
errorCaptured |
onErrorCaptured |
當捕獲一個來自子孫組件的異常時激活鉤子函數(shù) |
目前 Vue3.x 依然支持 Vue2.x 的生命周期,但不建議混搭使用,前期可以先使用 2.x 的生命周期,后面盡量使用 3.x 的生命周期開發(fā)。
由于我使用都是 script-srtup 模式,所以都是直接使用 Vue3.x 的生命周期函數(shù):
// A.vue
每個鉤子的執(zhí)行時機點,也可以看看文檔:https://v3.cn.vuejs.org/guide/instance.html#生命周期圖示
2. script-setup 模式中父組件獲取子組件的數(shù)據(jù)
文檔地址:https://v3.cn.vuejs.org/api/sfc-script-setup.html#defineexpose
這里主要介紹父組件如何去獲取子組件內(nèi)部定義的變量,關于父子組件通信,可以看文檔介紹比較詳細:https://v3.cn.vuejs.org/guide/component-basics.html
我們可以使用 全局編譯器宏 的 defineExpose 宏,將子組件中需要暴露給父組件獲取的參數(shù),通過 {key: vlaue} 方式作為參數(shù)即可,父組件通過模版 ref 方式獲取子組件實例,就能獲取到對應值:
// 子組件
// 父組件
注意:
- 全局編譯器宏只能在 script-setup 模式下使用;
- script-setup 模式下,使用宏時無需 import 可以直接使用;
- script-setup 模式一共提供了 4 個宏,包括:defineProps、defineEmits、defineExpose、withDefaults。
3. 為 props 提供默認值
definedProps 文檔:https://v3.cn.vuejs.org/api/sfc-script-setup.html#defineprops-%E5%92%8C-defineemitswithDefaults 文檔:https://v3.cn.vuejs.org/api/sfc-script-setup.html#%E4%BB%85%E9%99%90-typescript-%E7%9A%84%E5%8A%9F%E8%83%BD
前面介紹 script-setup 模式提供的 4 個 全局編譯器宏 ,還沒有詳細介紹,這一節(jié)介紹 defineProps 和 withDefaults 。使用 defineProps 宏可以用來定義組件的入?yún)?,使用如下?/p>
這里只定義 props 屬性中的 schema 和 modelValue 兩個屬性的類型, defineProps 的這種聲明的不足之處在于,它沒有提供設置 props 默認值的方式。
其實我們可以通過 withDefaults 這個宏來實現(xiàn):
withDefaults 輔助函數(shù)提供了對默認值的類型檢查,并確保返回的 props 的類型刪除了已聲明默認值的屬性的可選標志。
4. 配置全局自定義參數(shù)
文檔地址:https://v3.cn.vuejs.org/guide/migration/global-api.html#vue-prototype-%E6%9B%BF%E6%8D%A2%E4%B8%BA-config-globalproperties
在 Vue2.x 中我們可以通過 Vue.prototype 添加全局屬性 property。但是在 Vue3.x 中需要將 Vue.prototype 替換為 config.globalProperties 配置:
// Vue2.x
Vue.prototype.$api = axios;
Vue.prototype.$eventBus = eventBus;
// Vue3.x
const app = createApp({})
app.config.globalProperties.$api = axios;
app.config.globalProperties.$eventBus = eventBus;
使用時需要先通過 vue 提供的 getCurrentInstance 方法獲取實例對象:
// A.vue
其中 instance 內(nèi)容輸出如下:
5. v-model 變化
文檔地址:https://v3.cn.vuejs.org/guide/migration/v-model.html
當我們在使用 v-model 指令的時候,實際上 v-bind 和 v-on 組合的簡寫,Vue2.x 和 Vue3.x 又存在差異。
- Vue2.x
在子組件中,如果要對某一個屬性進行雙向數(shù)據(jù)綁定,只要通過 this.$emit('update:myPropName', newValue) 就能更新其 v-model 綁定的值。
- Vue3.x
script-setup 模式下就不能使用 this.$emit 去派發(fā)更新事件,畢竟沒有 this ,這時候需要使用前面有介紹到的 defineProps、defineEmits 兩個宏來實現(xiàn):
// 子組件 child.vue
// 文檔:https://v3.cn.vuejs.org/api/sfc-script-setup.html#defineprops-%E5%92%8C-defineemits
父組件使用的時候就很簡單:
// 父組件 father.vue
6. 開發(fā)環(huán)境報錯不好排查
文檔地址:https://v3.cn.vuejs.org/api/application-config.html#errorhandler
Vue3.x 對于一些開發(fā)過程中的異常,做了更友好的提示警告,比如下面這個提示:
這樣能夠更清楚的告知異常的出處,可以看出大概是 這時候就能看到輸出內(nèi)容如下: 一下子就清楚很多。當然,該配置項也可以用來集成錯誤追蹤服務 Sentry 和 Bugsnag。推薦閱讀:Vue3 如何實現(xiàn)全局異常處理? 當我們在控制臺輸出 ref 聲明的變量時。 會看到控制臺輸出了一個 RefImpl 對象: 看起來很不直觀。我們都知道,要獲取和修改 ref 聲明的變量的值,需要通過 .value 來獲取,所以你也可以: 這里還有另一種方式,就是在控制臺的設置面板中開啟 「 Enable custom formatters 」選項。 這時候你會發(fā)現(xiàn),控制臺輸出的 ref 的格式發(fā)生變化了: 更加清晰直觀了。 這個方法是我在《Vue.js 設計與實現(xiàn)》中發(fā)現(xiàn)的,但在文檔也沒有找到相關介紹,如果有朋友發(fā)現(xiàn)了,歡迎告知~ 文檔地址:https://cn.vitejs.dev/guide/features.html#glob-import 使用 webpack 的同學應該都知道,在 webpack 中可以通過 require.context 動態(tài)導入文件: 在 Vite 中,我們可以使用這兩個方法來動態(tài)導入文件: 該方法匹配到的文件默認是 懶加載 ,通過 動態(tài)導入 實現(xiàn),構建時會 分離獨立的 chunk ,是 異步導入 ,返回的是 Promise,需要做異步操作,使用方式如下: 該方法是 直接導入所有模塊 ,并且是 同步導入 ,返回結(jié)果直接通過 for...in 循環(huán)就可以操作,使用方式如下: 如果僅僅使用異步導入 Vue3 組件,也可以直接使用 Vue3 defineAsyncComponent API 來加載: 文檔地址:https://cn.vitejs.dev/config/#resolve-alias 當項目比較復雜的時候,經(jīng)常需要配置 alias 路徑別名來簡化一些代碼: 在 Vite 中配置也很簡單,只需要在 vite.config.ts 的 resolve.alias 中配置即可: 如果使用的是 TypeScript 時,編輯器會提示路徑不存在的警告:warning:,這時候可以在 tsconfig.json 中添加 compilerOptions.paths 的配置: 文檔地址:https://cn.vitejs.dev/config/#css-preprocessoroptions 當我們需要使用 scss 配置的主題變量(如 $primary )、mixin方法(如 @mixin lines )等時,如: 我們可以將 scss 主題配置文件,配置在 vite.config.ts 的 css.preprocessorOptions.scss.additionalData 中: 如果不想使用 scss 配置文件,也可以直接寫成 scss 代碼: 文檔地址:https://router.vuejs.org/zh/guide/advanced/composition-api.html 由于在 script-setup 模式下,沒有 this 可以使用,就不能直接通過 this.$router 或 this.$route 來獲取路由參數(shù)和跳轉(zhuǎn)路由。當我們需要獲取路由參數(shù)時,就可以使用 vue-router 提供的 useRoute 方法來獲取,使用如下: 如果要做路由跳轉(zhuǎn),就可以使用 useRouter 方法的返回值去跳轉(zhuǎn): 文檔地址:https://pinia.vuejs.org/core-concepts/#using-the-store 當我們解構出 store 的變量后,再修改 store 上該變量的值,視圖沒有更新: 這時候點擊按鈕觸發(fā) changeName 事件后,視圖上的 name 并沒有變化。這是因為 store 是個 reactive 對象,當進行解構后,會破壞它的響應性。所以我們不能直接進行解構。這種情況就可以使用 Pinia 提供 storeToRefs 工具方法,使用起來也很簡單,只需要將需要解構的對象通過 storeToRefs 方法包裹,其他邏輯不變: 這樣再修改其值,變更馬上更新視圖了。 (1)按照官網(wǎng)給的方案,目前有三種方式修改: 通過 store.屬性名 賦值修改單筆數(shù)據(jù)的狀態(tài); 這個方法就是前面一節(jié)使用的: (2)通過 $patch 方法修改多筆數(shù)據(jù)的狀態(tài); 文檔地址:https://pinia.vuejs.org/api/interfaces/pinia._StoreWithState.html#patch 當我們需要同時修改多筆數(shù)據(jù)的狀態(tài)時,如果還是按照上面方法,可能要這么寫: 上面這么寫也沒什么問題,但是 Pinia 官網(wǎng)已經(jīng)說明,使用 $patch 的效率會更高,性能更好,所以在修改多筆數(shù)據(jù)時,更推薦使用 $patch ,使用方式也很簡單: (3)通過 action 方法修改多筆數(shù)據(jù)的狀態(tài); 也可以在 store 中定義 actions 的一個方法來更新: 使用時: 這三種方式都能更新 Pinia 中 store 的數(shù)據(jù)狀態(tài)。 項目新安裝的 element-plus 在開發(fā)階段都是正常,沒有提示任何警告,但是在打包過程中,控制臺輸出下面警告內(nèi)容: 在官方 issues 中查閱很久:https://github.com/element-plus/element-plus/issues/3219。 嘗試在 vite.config.ts 中配置 charset: false ,結(jié)果也是無效: 最后在官方的 issues 中找到處理方法: 文檔地址:https://element-plus.gitee.io/zh-CN/guide/i18n.html#%E5%85%A8%E5%B1%80%E9%85%8D%E7%BD%AE 默認 elemnt-plus 的組件是英文狀態(tài): 我們可以通過引入中文語言包,并添加到 ElementPlus 配置中來切換成中文: 這時候就能看到 ElementPlus 里面組件的文本變成中文了。 以上是我最近從入門到實戰(zhàn) Vue3 全家桶的 3 個項目后總結(jié)避坑經(jīng)驗,其實很多都是文檔中有介紹的,只是剛開始不熟悉。也希望大伙多看看文檔咯~ Vue3 script-setup 模式確實越寫越香。// main.ts
app.config.errorHandler = (err, vm, info) => {
console.log('[全局異常]', err, vm, info)
}7. 觀察 ref 的數(shù)據(jù)不直觀,不方便
const count = ref
console.log('[測試 ref]', count)console.log('[測試 ref]', count.value);二、Vite
1. Vite 動態(tài)導入的使用問題
// https://webpack.js.org/guides/dependency-management/
require.context('./test', false, /\.test\.js$/);const Components = import.meta.glob('../components/**/*.vue');
// 轉(zhuǎn)譯后:
const Components = {
'./components/a.vue': () => import('./components/a.vue'),
'./components/b.vue': () => import('./components/b.vue')
}
const Components = import.meta.globEager('../components/**/*.vue');
// 轉(zhuǎn)譯后:
import * as __glob__0_0 from './components/a.vue'
import * as __glob__0_1 from './components/b.vue'
const modules = {
'./components/a.vue': __glob__0_0,
'./components/b.vue': __glob__0_1
}// https://v3.cn.vuejs.org/api/global-api.html#defineasynccomponent
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
app.component('async-component', AsyncComp)2. Vite 配置 alias 類型別名
import Home from '@/views/Home.vue'
// vite.config.ts
export default defineConfig({
base: './',
resolve: {
alias: {
"@": path.join(__dirname, "./src")
},
}
// 省略其他配置
}){
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}3. Vite 配置全局 scss
// vite.config.ts
export default defineConfig({
base: './',
css: {
preprocessorOptions: {
// 添加公共樣式
scss: {
additionalData: '@import "./src/style/style.scss";'
}
}
},
plugins: [vue()]
// 省略其他配置
})export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: '$primary: #993300'
}
}
}
})三、VueRouter
1. script-setup 模式下獲取路由參數(shù)
// A.vue
const router = useRouter();
router.push({
name: 'search',
query: {/**/},
})四、Pinia
1. store 解構的變量修改后沒有更新
// A.vue
{{name}}// A.vue
{{name}}2. Pinia 修改數(shù)據(jù)狀態(tài)的方式
const changeName = () => {
componentStoreObj.name = 'hello pingan8787';
}const changeName = () => {
componentStoreObj.name = 'hello pingan8787'
componentStoreObj.age = '18'
componentStoreObj.addr = 'xiamen'
}const changeName = () => {
// 參數(shù)類型1:對象
componentStoreObj.$patch({
name: 'hello pingan8787',
age: '18',
addr: 'xiamen',
})
// 參數(shù)類型2:方法,該方法接收 store 中的 state 作為參數(shù)
componentStoreObj.$patch(state => {
state.name = 'hello pingan8787';
state.age = '18';
state.addr = 'xiamen';
})
}// store.ts
import { defineStore } from 'pinia';
export default defineStore({
id: 'testStore',
state: () => {
return {
name: 'pingan8787',
age: '10',
addr: 'fujian'
}
},
actions: {
updateState(){
this.name = 'hello pingan8787';
this.age = '18';
this.addr = 'xiamen';
}
}
})const changeName = () => {
componentStoreObj.updateState();
}五、Element Plus
1. element-plus 打包時 @charset 警告
// vite.config.ts
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
charset: false // 無效
}
}
}
})// vite.config.ts
// https://blog.csdn.net/u010059669/article/details/121808645
css: {
postcss: {
plugins: [
// 移除打包element時的@charset警告
{
postcssPlugin: 'internal:charset-removal',
AtRule: {
charset: (atRule) => {
if (atRule.name === 'charset') {
atRule.remove();
}
}
}
}
],
},
}2. 中文語言包配置
// main.ts
// ... 省略其他
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
import locale from 'element-plus/lib/locale/lang/zh-cn'; // element-plus 中文語言包
app.use(ElementPlus, { locale }); // 配置中文語言包總結(jié)
新聞名稱:分享15個vue3全家桶開發(fā)的避坑經(jīng)驗
標題URL:http://www.dlmjj.cn/article/djheeho.html


咨詢
建站咨詢
