阅读 1680
卷死了!再不学vue3就没有人要你了!速来围观vue3新特性

卷死了!再不学vue3就没有人要你了!速来围观vue3新特性

一文入门了解vue3新特性

这是我参与更文挑战的第22天,活动详情查看:更文挑战

紧跟新技术的步伐,周一也开始学起了 vue3 。去年11月份的时候对 vue3 其实已经有所耳闻,但当时对 vue3 完全没有想学习的欲望。当时就觉得,够用就行,新技术那么多哪里学得动。然而现在……悔不当初😭,时代在推你进步,你却停滞不前,只会被时代淘汰。迫于内卷压力,再不学 vue3 真的感觉在跟时代划一道鸿沟。

所以,今年赶忙把 vue3 提上日程。原本 vue3 的学习计划是在三月份,但因为各种事情耽搁了到了现阶段才进行。

求求别再卷了……我学❗❗我学❗❗

在今天的这篇文章中,将带领大家全面了解 vue3 的新特性,vue3vue2 的一些区别, Composition APIOptions API 的区别。

下面开始进行本文的讲解🤪

一、😶vue3比vue2有什么优势?

vue3比vue2来说,性能上更好代码体积更小,并且有更好的ts支持

同时,更为突出的特点是,vue3有更好的代码组织能力,有更好的逻辑抽离能力,并且还有更多各式各样的新功能

其中尤为突出的就是大家平常耳熟能详的 Composition APIOptions API

那是不是 vue3 就一定比 vue2 好呢?或者是 Composition API 就一定比 Options API 好呢?

其实大家心里可能在此打下了一个问号⁉️

那接下来就带着这个问号,一起来了解 vue3 的新特性吧!

二、🧐Vue3升级了哪些重要的功能

1、createApp

vue2 不同的是, vue2 使用 new 的方式来初始化一个实例,而 vue3 则用 Vue.createApp初始化一个实例如下所示:

//vue2.x 实例化方式
const app = new Vue({ /*选项*/ })
//vue2.x 使用方式
Vue.use(/*...*/)
Vue.mixin(/*...*/)
Vue.component(/*...*/)
Vue.directive(/*...*/)

//vue3 实例化方式
const app = Vue.createApp({ /*选项*/ })
//vue3 使用方式
app.use(/*...*/)
app.mixin(/*...*/)
app.component(/*...*/)
app.directive(/*...*/)
复制代码

2、emits(父子组件间的通信)

(1)通信方式

传递形式通信方式
emits子组件向父组件传递数据
props父组件的数据需要通过props把数据传给子组件,props的取值可以是数组也可以是对象

(2)举个例子🌰

vue2 的时候,我们可以用 $emitprops 来进行父子组件间的通信。而现在, vue3 使用 emitsprops 来实现父子组件间的通信

我们定义一个父组件, 名字叫 App.vue具体代码如下:

<template>
  <HelloWorld msg="Hello Vue 3.0 + Vite" @onSayHello="sayHello"/>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld,
  },

  data() {
    return {
      msg: 'hello vue3'
    } 
  },
  methods: {
    sayHello(info) {
      console.log('hello', info)
    }
  }
}
</script>
复制代码

再定义一个子组件,名字叫 HelloWorld.vue具体代码如下:

<template>
  <h1>{{ msg }}</h1>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
    return {
      
    }
  },
  emits: ['onSayHello'],
  setup(props, { emit }) {
    emit('onSayHello', 'vue3')
  }
}
</script>
复制代码

此时浏览器的显示效果如下:

emits

vue3 中,可以直接将 emit 参数传入 setup 生命周期里面,来达到父子组件的通信

3、多事件处理

vue2 时,每一个点击只能定义一个事件;而在 vue3 时,打破原有的规则,每一个 @click 可以点击多个事件如下代码所示:

<!-- 在 methods 里定义 one two 两个函数 -->
<button @click="one($event), two($event)">
	submit
</button>
复制代码

4、Fragment

fragment ,中文翻译过来就是碎片的意思。

vue2.x 时,是不允许有碎片存在的。所以我们每次在写程序时,最外层总要再给它包个 div 。但这个时候就会感觉特别麻烦,因为有时候想这个 divclass 名还得思考给命个什么名字好,感觉心里都已经没墨水了。

因此,在 vue3 时,就除去了这个规范,可以不用最外层再包个 div如下代码所示:

<!-- vue2.x 组件模板 -->
<template>
	<div class="detail">
		<h3>{{ title }}</h3>
        <div v-html="content"></div>
	</div>
</template>
复制代码
<!-- vue3 组件模板 -->
<template>
    <h3>{{title}}</h3>
    <div v-html="content"></div>
</template>
复制代码

5、移除.sync

(1)vue2

vue2 时,我们会通过 v-bind:title.sync 来进行数据双向绑定具体代码如下:

<!-- vue2.x -->
<MyComponent v-bind:title.sync="title"></MyComponent>
复制代码

(2)vue3

而在 vue3 时,直接放弃掉 .sync 而使用 v-model 的形式来对数据进行绑定。具体代码对下:

<!-- vue3.x -->
<MyComponent v-model:title="title"></MyComponent>
复制代码

我们再用一个例子🌰来展示 vue3 是怎么对数据进行双向绑定的。具体代码如下:

我们先定义一个子组件,名字叫 UserInfo.vue具体代码如下:

<template>
    <input :value="name" @input="$emit('update:name', $event.target.value)"/>
    <input :value="age" @input="$emit('update:age', $event.target.value)"/>
</template>

<script>
export default {
    name: 'UserInfo',
    props: {
        name: String,
        age: String
    }
}
</script>
复制代码

再来定义一个父组件,名字叫 index.vue具体代码如下:

<template>
    <p>{{name}} {{age}}</p>

    <user-info
        v-model:name="name"
        v-model:age="age"
    ></user-info>
</template>

<script>
import { reactive, toRefs } from 'vue'
import UserInfo from './UserInfo.vue'

export default {
    name: 'VModel',
    components: { UserInfo },
    setup() {
        const state = reactive({
            name: 'monday',
            age: '18'
        })

        return toRefs(state)
    }
}
</script>

复制代码

此时浏览器的显示效果如下: v-model 此时,我们可以得出结论:子组件通过控制 :value@input 来控制input的值,同时父组件通过 v-model:propertyName 来绑定子组件的值,这样一来,两者就实现了双向数据绑定

6、异步组件

vue2 时,引入异步组件的方法比较简单,直接使用import即可。代码如下:

new Vue({
	//…
	components:{
		'my-component': () => import('./my-async-component.vue')
	}
})
复制代码

而在 vue3 时,引入异步组件需要使用 defineAsyncComponent 方法来进行引入。代码如下:

import { createApp, defineAsyncComponent } from 'vue'

new Vue({
	//…
	components:{
		AsyncComponent: defineAsyncComponent(() =>
			import('./components/AsyncComponent.vue')
		)
	}
})
复制代码

7、移除filter

vue2 时,有 filter 这个功能,但其实这个功能的使用频率还挺低的。所以,在 vue3 中,彻底去除了 filter 这个功能,不再可用。

<!-- 以下filter在vue3中不再可用!! -->
<!-- 在双花括号中 -->
{{ message | capitalize }}

<!-- 在v-bind中使用 -->
<div v-bind:id="rawId | formatId"></div>
复制代码

8、Teleport

Teleport ,中文翻译过来就是远距离传送。在 vue2 中,比如我们要定义点击某个按钮,去跳转一个模态框,这个时候一般需要去操作 DOM 元素,或者再定义一个新的组件。但是在 vue3 ,我们可以用 teleport 来解决。我们可以使用 teleport 来直接定义在当前组件中,之后通过v-if等方式来控制其显示与否。演示代码如下:

<!-- data 中设置modalOpen: false -->
<button @click="modalOpen = true">
    Open full scree modal!(With teleport!)
</button>

<teleport to="body">
	<div v-if="modalOpen" class="modal">
        <div>
            telePort 弹窗(父元素是body)
            <button @click="modalOpen = false">Colse</button>
        </div>
    </div>
</teleport>
复制代码

9、Suspense

Suspense,是对vue2.x中的插槽做一个封装,这里不进行一一讲解。下面给出代码演示:

<Suspense>
	<template>
    	<Test1/> <!--  是一个异步组件 -->
    </template>
    
    <!-- #fallback就是一个具名插槽。即Suspense组件内部,有两个slot,其中一个具名为 fallback -->
    <template #fallback>
    	Loading...
    </template>
</Suspense>
复制代码

三、😜Options API 和 Composition API

1、生命周期对比

以下给出 Vue2Vue3 生命周期的对比。

Vue2生命周期(Options API)Vue3生命周期(Composition API)含义
beforeCreatesetup在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用
createdsetup页面还没有渲染,但是vue的实例已经初始化结束。
beforeMountonBeforeMount在挂载开始之前被调用:相关的 render 函数首次被调用。
mountedonMounted页面已经渲染完毕。
beforeUpdateonBeforeUpdate数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
updatedonUpdated由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。
beforeDestoryonBeforeUnmount实例销毁之前调用。在这一步,实例仍然完全可用。
destroyonUnmountedVue 实例销毁后调用。

2、Composition API 和 Options API 对比

(1)Composition API带来了什么?

Composition API 相较于 Options API 来说,拥有更好的代码组织能力,更好的逻辑复用能力,以及更好的类型推导。

这里引用大帅老师的几张动图来对 Composition APIOptions API 做一个对比。原文搓👉做了一夜动画,就为让大家更好的理解Vue3的Composition Api,再悄悄告诉各位小伙伴,大帅老师的文章融入大量的动画,通俗易懂,路过的小伙伴赶紧关注一波哦,学习路上不迷路🚦

废话不多说,赶紧来看看 Options APIComposition API 的区别。

Options API:

options API

options API

Composition API:

composition API

composition API

从上图中可以看到,对于 Options API 来说,它的逻辑是散落在各处的,懒懒散散的。假设我们现在有一个功能要实现,而这个功能的逻辑代码有2000-3000行,试想一下,如果我们用 Options API 来实现的话,假设这个功能在 methods 里面有定义了一个方法,然后呢又要滑动一两千行mounted 里面看挂载的内容,这真的是出奇的浪费时间呐!所以, vue3 提出了 composition API ,就来解决这个问题了。

composition API 把代码的逻辑抽离出来封装,并把封装的内容直接引用到生命周期里面,这样使用起来真的方便太多了。

我们举个简单的例子来看看 composition API 的使用方式。如下代码所示:

抽离某个逻辑放在同一个函数上:

function sum(){
    let a = ref(10);
    let b = computed(() => {
        return a.value * 2
    })
    
    const handleSum = () => {
        a.value = a.value + b
    }
    
    return {
        a,
        b,
        handleSum
    }
}
复制代码

将sum函数逻辑放在组件中使用:

export default defineComponent({
	setup(){
		const { a, b, handleSum } = sum();
        return {
            a,
            b,
            handleSum
        }
	}
})
复制代码

综上可以得出,对于一个项目来说,尤其是代码量越多,逻辑越复杂的, Composition API 的优势会更加明显。那对于一个项目来说,我们应该在这两者中如何抉择而选择更好的方案呢? 接着我们继续往下看。

(2)Composition API和Options API如何选择?

通过上面的分析我们可以知道, Composition API 虽然好用,但也不能乱用。因此,对于 Composition APIOptions API 的使用,主要有以下几点建议:

  • 两者不建议共用,不然很容易引起混乱;
  • 对于小型项目、或者业务逻辑比较简单的项目,建议使用 Options API
  • 对于中大型项目、或者逻辑比较复杂的项目,建议使用 Composition API ,相较于 Options API 来说, Composition API 对大型项目更好一些,逻辑的抽离,代码的复用,使得大型项目得以更好的维护。

(3)别误解Composition API

很多小伙伴在没学 vue3 之前,就依稀有听到 Composition API 的声音,这个时候就会使得很多人觉得,要想学会 Vue3 ,就得先学会 Composition API

其实……不是这样的。

Composition API 属于高阶技巧并不是学基础时必须要会的内容

正如上面所演示的内容, Composition API 的出现是为了解决复杂业务逻辑而设计,而不是为了学基础而设计的。

所以说,对于小白学 vue3 时,需要先学会 vue3 的基础,再来学 Composition API ,这样的学习路线更为合理。

四、🙃结束语

vue3 确实解决了 vue2 的很多问题,上文所描述的也只是冰山一角。但并没有说 vue3 出了就是 vue3 最好, vue2 不用了。因为 vue3 确实解决了一些问题,但同时也带来了一些问题,所以说,两者更多的是一个相辅相成的结果。

关于 vue3 的超入门知识就讲到这里啦!希望对大家有帮助~

  • 关注公众号 星期一研究室 ,第一时间关注学习干货,更多有趣的专栏待你解锁~
  • 如果这篇文章对你有用,记得 一键三连 再走哦!
  • 我们下期见!🥂🥂🥂
文章分类
前端
文章标签