關于Vue3實踐的一些問題清單
本文轉載自微信公眾號「微醫大前端技術」,作者黃琴 。轉載本文請聯系微醫大前端技術公眾號。
前言
瞪瞪,胖琴的第三篇文章來襲!近期在自己的規劃中列著一份 vue3 清單。關于 vue3,雖然之前很早就看過了,但是也只是簡單的了解一番寫了幾個小 demo,而且我司的主要技術棧也是 vue, 近期趁著這股學習的勁,趕緊向上申請了一個內部項目,想著用 vue3 實踐一波,希望這一篇總結對一些小伙伴提供一些幫助。
以下主要會從兩部分去做總結,一部分是可能混淆的點 or 一些常見的問題,另外一部分是實踐過程中遇到的坑點/注意點。
關于 vue3 的一些疑問點
1: 使用了 Vue3,是否都要遵循用 Composition API 的形式去寫頁面?
答案是否定的。需要注意一點:Vue3 并沒有廢棄 Options API,甚至還會全力支持兼容 Vue2 語法的工作。而 CompositionAPI 出現的背景主要是為了解決邏輯抽象和和復用的問題,但不意味著它成為了 Vue3 的標準。So,如何區分場景使用Options API or Composition API主要看業務邏輯的復雜程序,例如一些簡單的 toast/button 等基礎組件,用options API形式會更加清晰和簡潔。而相對復雜的業務邏輯,可以用Composition API,可以把單獨一塊邏輯抽離到一個模塊,通過 hook 函數的方式去解決。
2: Vue3 中混用 Options API 和 Composition API 會不會對性能產生影響?
不會。其實從問題 1 就可以明顯地看出來并不會對性能產生任何影響。不應該被option api限制思維,而更多關注邏輯內聚問題
3: 關于 setup 中沒有 this 的問題
vue 官方文檔是這么解釋的:在 setup() 內部,this 不會是該活躍實例的引用,因為 setup() 是在解析其它組件選項之前被調用的,所以 setup() 內部的 this 的行為與其它選項中的 this 完全不同。這在和其它選項式 API 一起使用 setup() 時可能會導致混淆。這意味著,除了 props 之外,你將無法訪問組件中聲明的任何屬性---本地狀態,計算屬性/方法。
但是從源碼實現你會發現其實組件實例創建在前,函數之所以訪問不到 this,是因為它在執行 setup 函數的時候,就沒有把組件實例 instance 傳給 setup。也沒有把 this 指向實例 instance。So 執行順序其實是:組件實例創建在 setup 函數執行之前,但是 setup 執行的時候,組件還沒有 mounted,而晚于 beforeCreate 鉤子,早于 create 鉤子。
4: reactive VS ref
剛開始看文檔時,大家往往會去拿這兩個去對比,總結一下:
reactive API: 可以把一個對象數據變成響應式(等同于 2.x 中的 Vue.observable()),Composition API 更推薦用戶主動定義響應式式數據,而非內部的黑盒處理
ref: 針對數組 or 對象本質就是reactive實現的,讀取值時是ref.value
另外注意一下toRefs: 針對組合函數返回響應式對對象時使用 toRefs, 本質上是幫我們做了一層getter和setter處理,解構就可以得到響應式的數據,這也就降低了一些關于ref的心智負擔
5: Vue3 響應式比 Vue2 的性能要好嗎?
vue3 出來的時候,往往聽到的一些答案都是說 Vue3 性能比 Vue2 性能好,但真的是嗎?在 Vue3 發布那一段期間中(我也去薅羊毛薅到了 1 元的源碼課解析中學習了一番:老黃 YYDS),甚至包括群里大家都在討論這個問題。
首先從實現上來講:我們都知道 vue2 中的響應式主要歸功于Object.defineProperty, 它主要劫持對象的屬性,所以它不能觀測到對象屬性的添加和刪除,而在 vue 中,是用Proxy實現的,劫持的是整個對象,能規避掉 vue2 留下的問題,但也有明顯的缺點就是兼容性不夠強。但是對比 Vue2,你需要知道的是 vue3 性能上的優勢主要還是體現在初始化階段。因為 Vue2 中定位響應式對象時,會遞歸把子對象變成響應式。而 Vue3 其實是惰性執行:在對象屬性被真正訪問的時候才會遞歸執行子對象變成響應式。
6: Vue Composition API VS React Hooks
Vue3 的Composition API和React Hooks的寫法很像,大家都會忍不住拿他們去做個對比,關于這部分內容的 PK,我司的小伙伴已經給總結過了,還很全面,這個就不細說了,傳送門:
Vue Composition API 和 React Hooks 對比:https://juejin.cn/post/6847902223918170126
除了一些常見的問題時,更重要的就是實踐,對于新項目,可以直接使用 vue3 起步,但更多的對于已有的項目,在 vue2 升級到 vue3 實踐時,肯定會踩不少坑,以下是關于在實踐過程中可能會遇到的一些注意點&坑點
1. 報錯以下警告:告知 script setup 當前仍然是個實驗性的新特性,還沒有作為正式特性發布,后面會不會有變化還不好說。
- [@vue/compiler-sfc] <script setup> is still an experimental proposal.
- Follow its status at https://github.com/vuejs/rfcs/pull/227.
- [@vue/compiler-sfc] When using experimental features,
- it is recommended to pin your vue dependencies to exact versions to avoid breakage.
- [@vue/compiler-sfc] `defineProps` is a compiler macro and no longer needs to be imported.
2: 遷移 vue3 時,setup 中只保留了不再有once, $off 等方法,只保留了 emit,如下:
- setup(props, { emit }) {
- const rootRef = ref(null)
- const scroll = useScrolll(rootRef, props, emit)
- return {
- rootRef,
- scroll
- }
- }
- // scroll.js 中
- scrollVal.on('scroll', pos => {
- emit('scroll', pos)
- })
3: 關于 computed: 3.X 把 computed 變成了一個計算屬性 API,所以可以有多個 computed,可以沿用 Vue.js 2.x 的使用方法
- // vue2.x
- computed: {
- loading() {
- return !this.list.length
- }
- },
- // vue3.x
- const loading = computed(() => !this.list.length)
- const titleList = computed(() => {
- return props.data.map((item) => item.title)
- })
4: 關于 watch:對于監聽對象是分隔字符串時,需要在選項參數中指定 deep: true
- // vue2.x
- watch: {
- 'data.distance': function (newVal, oldVal) {
- if (newVal === constants.DISTANCE_ON) {
- ...
- }
- },
- },
- // vue3.x
- watch(
- () => this.data.distance,
- (newVal, oldVal) => {
- if (newVal === constants.DISTANCE_ON) {
- ...
- }
- },
- { deep: true },
- )
5: 在 Vue3 中組件沒有filters選項,遷移過程中,可以用computed/methods替代
- // vue2.x
- filters: {
- // just a method
- dateFormat,
- },
- // vue3.x
- const dateFormat = computed(() => {
- // just a method
- dateFormat,
- })
可以在同一個組件上使用多個 進行雙向綁定,可以使用自定義 v-model 修飾符
6: vue3.X 中去掉了.sync,用v-model代替 并且同一個組件中不僅限于只有一個v-model
- // vue2.x
- <basic-info-dialog :shown.sync="dialogFormVisible">
- <ChildComponent v-bind:name.sync="name" />
- // vue3.x
- <basic-info-dialog v-model:shown="dialogFormVisible">
總結
踩坑還在繼續,繼續實踐繼續踩!
參考資料
vue 文檔:https://vue3js.cn/docs/zh/guide/composition-api-setup.html#%E4%BD%BF%E7%94%A8%E6%B8%B2%E6%9F%93%E5%87%BD%E6%95%B0
Vue Composition API 和 React Hooks 對比:https://juejin.cn/post/6847902223918170126
前往微醫互聯網醫院在線診療平臺,快速問診,3分鐘為你找到三甲醫生。(https://wy.guahao.com/?channel=influence)