特点
vue2 的特点
1. 易用 (容易上手)
2. 灵活 (可以在一个库或者一个框架中使用)
3. 高效 ( 20kB min+gzip 运行大小 超快虚拟 DOM 最省心的优化)
vue3的特点
1. 易用 (容易上手)
2. 灵活多变 (丰富的、可渐进式集成的生态系统,可以根据应用规模在库和框架间切换自如。)
3. 性能出色 (经过编译器优化、完全响应式的渲染系统,几乎不需要手动优化。)
特点上最大的区别是vue3增加了编译器优化
Vue3是一个编译时+运行时的框架,它在保持灵活性的基础上,还能够通过编译手段分析用户提供的内容,从而进一步提升更新性能
监听事件
父组件可以通过 v-on 或 @ 来选择性地监听子组件上抛的事件,
子组件可以通过调用内置的 $emit 方法,通过传入事件名称来抛出一个事件:
在vue3中新增了emits来声明需要抛出的事件
这个 emits 选项还支持对象语法,它允许我们对触发事件的参数进行验证:
export default {
emits: {
submit(payload) {
// 通过返回值为 `true` 还是为 `false` 来判断
// 验证是否通过
}
}
}
子组件
<template>
<div class="blog-post">
<h4>{{ title }}</h4>
<button @click="$emit('enlarge-text')">Enlarge text</button>
</div>
</template>
<script>
export default {
props: ['title'],
emits: ['enlarge-text']
}
</script>
父组件
<BlogPost
...
@enlarge-text="postFontSize += 0.1"
/>
组件名
在vue3中使用 <script setup> 的单文件组件会自动根据文件名生成对应的 name 选项,无需再手动声明。
vue3新增显著的新功能
- vue3 增加组合式 API
- vue3增加新特性 (比如 Teleport、Suspense,以及多根元素模板)
- emits用于声明由组件触发的自定义事件。
- setup
中断性的改变
模版指令
1. v-mode(双向数据绑定)
v-bind 的sync修饰符被删除,并替换为v-model上的参数 在一个组件上创建多个 v-model 双向绑定
```
属性名可以任意,比如x,那么事件名必须是update:x,然后使用v-model
在3.x中,自定义组件上的v-model相当于传递modelValue属性并发出update:modelValue事件:
并且可以要更改模型名称,而不是模型组件选项,现在我们可以向v-model传递一个参数:
这也可以替代.sync修饰符,并允许我们在自定义组件上有多个v模型。
```
2.key
在v-if/v-else/v-else-if中不再需要key,因为Vue现在自动生成唯一键
3.v-if和v-for的优先级问题
vue2中 当处于同一节点`v-for`的优先级高于`v-if`
vu3中 当处于同一节点`v-if`的优先级高于`v-for`
4.v-bind 绑定行为
<!--v-bind的绑定顺序会影响渲染结果-->
<div id="red" v-bind="{ id: 'blue' }"></div>
<!-- 2.xresult -->
<div id="red"></div>
<!-- 3.xresult -->
<div id="blue"></div>
5.v-on.native (将原生事件绑定到组件)已删除
Vue现在将未在子组件中定义该事件,则会被作为本机事件添加到子级的根元素中(除非在子级的选项中设置了inheritAttrs:false)
<my-component
v-on:close="handleComponentEvent"
v-on:click="handleNativeClickEvent"
/>
<script>
export default {
emits: ['close']
}
</script>
handleNativeClickEvent就会被作为本机事件添加到子组件的根元素中
Components(组件)
1. 只能使用普通函数创建功能组件
2. defineAsyncComponent异步组件
定义一个异步组件,它在运行时是懒加载的。参数可以是一个异步加载函数,或是对加载行为进行更具体定制的一个选项对象。返回一个Promise加载函数
例如:导入单个组件
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() =>
import('./components/MyComponent.vue')
)
最后得到的 AsyncComp 是一个外层包装过的组件,仅在页面需要它渲染时才会调用加载内部实际组件的函数。它会将接收到的 props 和插槽传给内部组件,所以你可以使用这个异步的包装组件无缝地替换原始组件,同时实现延迟加载。
3.emits (用于声明由组件触发的自定义事件。)
渲染函数
1.渲染函数的API发生了改变
h() 是 hyperscript 的简称——意思是“能生成 HTML (超文本标记语言) 的 JavaScript”。准确的名称应该是 createVnode()
创建虚拟 DOM 节点 (vnode)
接收的参数
function h(
type: string | Component,
props?: object | null,
children?: Children | Slot | Slots
): VNode
h()现在被全局导入,而不是作为参数传递给呈现函数
// 完整参数签名
function h(
type: string | Component,
props?: object | null,
children?: Children | Slot | Slots
): VNode
声明渲染函数
我们可以使用 render 选项来声明渲染函数:
import { h } from 'vue'
export default {
render() {
return h('div')
}
}
在 vue2中render函数将自动接收h函数(这是createElement的传统别名)作为参数:
// Vue 2 Render Function Example
export default {
render(h) {
return h('div')
}
}
VNode属性格式
在vue2中domProps在VNode props中包含一个嵌套列表:
// 2.x
{
staticClass: 'button',
class: {'is-outlined': isOutlined },
staticStyle: { color: '#34495E' },
style: { backgroundColor: buttonColor },
attrs: { id: 'submit' },
domProps: { innerHTML: '' },
on: { click: submitForm },
key: 'submit-button'
}
//3.x中整个VNode支柱结构被展平
{
class: ['button', { 'is-outlined': isOutlined }],
style: [{ color: '#34495E' }, { backgroundColor: buttonColor }],
id: 'submit',
innerHTML: '',
onClick: submitForm,
key: 'submit-button'
}
2.slots作为函数公开
//2.x
h(LayoutComponent, [
h('div', { slot: 'header' }, this.header),
h('div', { slot: 'content' }, this.content)
])
this.$scopedSlots.header
//3.x
h(LayoutComponent, {}, {
header: () => h('div', this.header),
content: () => h('div', this.content)
})
this.$slots.header()
3.移除了listeners(事件侦听器)/合并到attr中
listeners:(2.3.0+) 一个包含了所有父组件为当前组件注册的事件监听器的对象。这是 data.on 的一个别名。
事件侦听器现在是attr中的一部分
//2.x
<template>
<label>
<input type="text" v-bind="$attrs" v-on="$listeners" />
</label>
</template>
<script>
export default {
inheritAttrs: false
}
</script>
//3.x
<template>
<label>
<input type="text" v-bind="$attrs" />
</label>
</template>
<script>
export default {
inheritAttrs: false
}
</script>
其他细微的变化
- 生命周期重命名
destroyed改为unmounted
beforeDestroy改为 beforeUnmount
- data只能是一个返回对象的函数
//2.x data可以是一个对象,或者是函数
<!-- Object Declaration -->
<script>
const app = new Vue({
data: {
apiKey: 'a1b2c3'
}
})
</script>
<!-- Function Declaration -->
<script>
const app = new Vue({
data() {
return {
apiKey: 'a1b2c3'
}
}
})
</script>
//3.x
<script>
import { createApp } from 'vue'
createApp({
data() {
return {
apiKey: 'a1b2c3'
}
}
}).mount('#app')
</script>
- Transition过渡样式名的修改
v-enter 改为v-enter-from v-leave改为v-leave-from
- vue3 filter过滤器移除
内置组件
vue2
-
component
渲染一个“元组件”为动态组件。依 is 的值,来决定哪个组件被渲染。
-
transition
单个元素/组件的过渡效果
-
transition-group
多个元素/组件的过渡效果
-
keep-alive
缓存
-
slot
插槽。
vue3
- Transition
- TransitionGroup
- KeepAlive
- Teleport
它可以将一个组件内部的一部分模板“传送”到该组件的 DOM 结构外层的位置去。
- Suspense
异步组件
组合式API
vue3
- watchEffect()
立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。
第一个参数就是要运行的副作用函数。
第二个参数是一个可选的选项,可以用来调整副作用的刷新时机或调试副作用的依赖。
兼容v2老版本的方式
对于更老的 Vue 2 版本,可以使用官方维护的插件 @vue/composition-api 来实现vue3的写法,后期如果升级只需要把@vue/composition-api替换成vue即可