前端大事件
就在本月的20號,vue框架作者尤雨溪在知乎發布了一篇文章,在該篇文章中宣告vue的又一巨大革新。
尤大在文章中提到,Vue 3 將在 2022 年 2 月 7 日 成為新的默認版本!以下是部分原文:
“軟發布” 的過程比預期要長,但這個時刻終於到了:
我們很高興地宣布,Vue 3 將在 2022 年 2 月 7 日 成為新的默認版本。
除了 Vue 核心庫以外,我們還幾乎改進了框架的每個方面。
· 基於 Vite 的極速構建工具鏈
· <script setup> 帶來的開發體驗更絲滑的組合式 API 語法
· Volar 提供的單文件組件 TypeScript IDE 支持
· vue-tsc 提供的針對單文件組件的命令行類型檢查和生成
· Pinia 提供的更簡潔的狀態管理
· 新的開發者工具擴展,同時支持 Vue 2/Vue 3,並且提供一個插件系統來允許社區庫自行擴展開發者工具面板。
我們還徹底重寫了主文檔。全新的 vuejs.org (目前處於待發布狀態,中文版的翻譯還在進行中) 將提供最新的框架概述與開發建議、
針對不同背景的用戶的靈活的學習路徑,在整個指南與示例中都能夠在選項式 API 和組合式 API 之間進行切換,以及許多新的深入章節。
新文檔本身的網站性能也非常優秀——我們將在不久后的另一篇博文中詳細探討一下。
…………
詳細內容可以參考原文 Vue 3 將成為新的默認版本
這可以說是vue框架自誕生以來最為勁爆的一則消息了。vue3從2018年開始提出構造,到2020年9月正式發布3.0版本,兩年多的開發成本不可謂不低。然而即使攜帶着前瞻的composition-api思想和一系列性能優化及生態革新, 最初發布的vue3.0並沒有得到大多數開發者的青睞,與以往大相徑庭的編程樣式和不穩定性讓他們更多的選擇保持vue2.x。
但是又經過一年多的沉淀,在今年的新年之際,vue終於拋棄2.0,迎來3.0的主場。vue3是以解決vue2.0開發大型復雜項目產生的代碼邏輯分散性高的目的誕生的,全新的composition-api較以往的options-api有着完全的進步,如今vue3的生態圈也進一步完善,對ts的支持也不再殘疾,相信vue3一定會在國內乃至全球范圍產生一定影響力。
簡要談談一些變化
vue3與vue2不同的內核標志着與之關聯緊密的生態圈必然也將發生較大的變化,下面簡要談談必要的一些改變。
1. <script setup>
語法糖
組合式api初識
composition-api與options-api在表現形式上的最大不同就是其更像函數式編程,所有業務邏輯均寫在setup(prop,context)
函數中,不再區分data
,methods
,props
,watch
等等。這個更改的好處就是代碼關聯性更強,邏輯相關的代碼位置相近,方便書寫及查找、維護。
常規寫法類似如下:
<script>
import { reactive, ref, computed } from "vue";
export default {
name: "Hello1",
// 接收父組件傳遞的數據
props: {
msg: {
type: String,
},
code: {
type: Number,
},
},
//聲明要向父組件傳遞的自定義事件
emits: ["test"],
setup(props, context) {
// 計算屬性
let completeMsg = computed(() => {
return props.msg + props.code;
});
// 利用context拋出事件
function click_() {
context.emit("test", "waga");
}
// 將數據及方法return 出去
return {
click_,
completeMsg,
};
},
};
</script>
可以看到此時的寫法還是有些options-api的影子,export defalut導出一個組件對象,里面有各種屬性包括setup()
函數等,而且在setup()
最后還要將dom元素使用到的數據及方法return出去,還是有些繁瑣的,這也是我在學習vue3時看到不少一起學習的網友經常吐槽的點。
使用setup標注
使用了setup標志的<script>
標簽會將標簽內的代碼封裝為setup函數,並采用了宏定義及api的方式提供prop
,emits
的獲取,末尾也不用再麻煩的return出去,你要做的只是處理邏輯,不必再關心js/ts代碼的結構,setup語法糖已經幫開發者進行了屏蔽。
下面給出一個使用setup語法糖的demo:
<script setup>
// 導入所需方法及組件
import { ref, reactive, onBeforeMount, onMounted,computed } from 'vue';
import TabBar from '@/components/TabBar.vue';
import TabBarItem from '@/components/TabBarItem.vue';
import { testStore } from '@/store/index.js';
// vue3全新生命周期鈎子 對標vue2 created
onMounted(() => {
const test_store_ins = testStore();
test_store_ins.set_major("動畫制作");
test_store_ins.set_grade(2019);
})
// 聲明響應式數據
const num = ref(180);
const person = reactive({
name:"dio"
age:22,
stand:{
name:"the world",
damage:120
}
})
// 宏定義獲取props
const props = defineProps({
color: String
})
// 計算屬性
const bg_color = computed(() => {
return `background-color:${props.color}`;
})
</script>
可以看到所有js代碼只需要按順序書寫即可,不必再考慮應該放置在哪個板塊中,setup標注幫開發者封裝的很徹底,相較於options-api,開發及維護體驗都有了良好的提升。除上述demo所引用的功能外,原本vue2內置的所有屬性都可以在vue3的vue
模塊中找到相應的api並進行引用,(比如watch
等)
2. vue-router@4
vue-router作為vue單頁應用中進行路由跳轉的插件,在4.0版本前提供對vue2的支持,在進入vue3的時代后,vue-router也更新到4.x版本已提供對vue3的支持。
vue4較先前版本有着諸多破壞式不兼容的變更,拿比較顯著的幾個方面作個例子:
實例創建方式
在vue-router4以前,創建一個vue-router實例采用的是調用構造函數
// 構造函數實例化
const Router=new VueRouter({
routes
})
來到vue-router4后,實例創建方式改為調用createRouter
方法;
const Router = createRouter({
route
})
mode屬性變更為history
history屬性已替代mode屬性用於表示瀏覽器歷史記錄模式
原本的三種模式分別由vue-router
庫中的三個函數表示:
"history"
:createWebHistory()
"hash"
:createWebHashHistory()
"abstract"
:createMemoryHistory()
import { createRouter, createWebHistory } from 'vue-router'
// 還有 createWebHashHistory 和 createMemoryHistory
createRouter({
history: createWebHistory(),
routes: [],
})
其他詳細
可以參考 從vue2遷移-vue-router
3. vuex@4
官網中遷移部分提到:
Almost all Vuex 4 APIs have remained unchanged from Vuex 3.
However, there are still a few breaking changes that you must fix.
vuex4較3版本並無太大變化,簡而言之即兼容度極高。對此感興趣想詳細了解的可以參考 從vue2遷移-vuex
4. pinia
尤大在這次宣告中也提到了一個新技術棧——pinia
, 這是由vuex團隊核心團隊的成員開發的另一款vue狀態管理插件,對標vuex5, 超越vuex4。pinia較目前的vuex4在諸多方面有更強的功能及優勢。官網也給出了明確的描述:
Pinia API is very different from Vuex ≤4, namely:
-
mutations no longer exist. They were very often perceived as extremely verbose. They initially brought devtools integration but that is no longer an issue.
-
No need to create custom complex wrappers to support TypeScript, everything is typed and the API is designed in a way to leverage TS type inference as much as possible.
-
No more magic strings to inject, import the functions, call them, enjoy autocompletion!
-
No need to dynamically add stores, they are all dynamic by default and you won't even notice. Note you can still manually use a store to register it whenever you want but because it is automatic you don't need to worry about it.
-
No more nested structuring of modules. You can still nest stores implicitly by importing and using a store inside another but Pinia offers a flat structuring by design while still enabling ways of cross composition among stores. You can even have circular dependencies of stores.
-
No namespaced modules. Given the flat architecture of stores, "namespacing" stores is inherent to how they are defined and you could say all stores are namespaced.
翻譯下來大概有如下區別:
-
突變不再存在。他們經常被認為非常冗長。他們最初帶來了 devtools 集成,但這不再是問題。
-
無需創建自定義的復雜包裝器來支持 TypeScript,所有內容都是類型化的,並且 API 的設計方式盡可能地利用 TS 類型推斷
-
Pinia 不支持嵌套存儲。相反,它允許你根據需要創建store。但是,store仍然可以通過在另一個store中導入和使用store來隱式嵌套
-
存儲器在被定義的時候會自動被命名。因此,不需要對模塊進行明確的命名。
-
Pinia允許你建立多個store,讓你的捆綁器代碼自動分割它們
-
Pinia允許在其他getter中使用getter
-
Pinia允許使用 $patch 在devtools的時間軸上對修改進行分組。
簡單使用下來最為直接的感覺就是代碼比vuex更簡短了,vuex的不同modules多放在不同js文件中再進行集成,代碼復雜且集成后的state
,mutations
等仍屬於同一store。
pinia提供了多store的書寫方式,切實做到了store的分類,邏輯關聯的內容封裝為一個個獨立的store, 使用更輕巧。
import { defineStore } from "pinia";
// 學生相關的store屬性、方法
export const stuStore = defineStore({
id: "global_stu",
state: () => {
major: String;
grade: Number;
},
getters: {
SchoolAndMajor(state) {
return `${state.grade}級${state.major}專業`;
},
},
actions: {
set_major(val) {
this.major = val;
},
set_grade(val) {
this.grade = val;
},
},
});
// 角色相關的store屬性、方法
export const roleStore = defineStore({
id: "global_role",
state: () => {
name: String;
apperance: Number;
gender: String;
},
getters: {
RoleInfo(state) {
return `角色名${state.name},性別${state.gender}`;
},
},
actions: {
set_name(val) {
this.name = val;
},
set_apperance(val) {
this.apperance = val;
},
},
});
更多細節請查閱 pinia官方文檔
5. element-ui
element-ui作為vue開發者常用的ui庫,其簡易、靈活、輕巧先進的組件能在提供美觀界面的同時提供全面而強大的功能。
由於vue3.0在插件install函數的入參從Vue原型(類)改成了app(vue實例e)。導致element-ui中Vue.prototype.* 這樣的代碼已經全都失效了, 標示着element-ui並不兼容vue3。
好在element-ui團隊早已馬不停蹄地肝,如今已產出了element vue3
適配版 element-plus
。不過目前該項目仍處於beta測試版,還不穩定,之前去官網看了一眼,賦值粘貼就能用的字體圖標居然也給摒棄了,希望element-plus還能維持以往友好的特性吧。
6. Typescript
遙想還在vue2時期,在項目中引入ts,需要vue-property-decorator
插件提供支持,再在代碼中用一系列裝飾器進行標注,搞得和寫springboot的注解開發似的,vue2對ts的支持可謂缺胳膊少腿,前端開發人員們苦不堪言。
vue3改變了底層邏輯,從根本上提供了對ts的支持, 並且專門開發了官方vscode插件volar
來為ts項目提供強大的多功能服務,( 詳細內容可以參考這篇文章關於volar ) 現在使用vue3開發ts項目可謂是如虎添翼,前端開發者的體驗將有質的飛躍。