前端大事件
就在本月的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项目可谓是如虎添翼,前端开发者的体验将有质的飞跃。