1.vue3.x的新特性
1.Vue3.0六大亮点
- Performance:性能比Vue 2.x快1.2~2倍
- Tree shaking support:按需编译,体积比Vue2.x更小
- Composition API: 组合API(类似React Hooks)
- Better TypeScript support:更好的 Ts 支持
- Custom Renderer API:暴露了自定义渲染API
- Fragment, Teleport(Protal), Suspense:更先进的组件
2.vue是怎么变快的
- 1.其实就是diff算法优化了
- Vue2中虚拟dom是进行全量的对比
- Vue3新增了静态标记(PatchFlag),在与上次虚拟节点进行对比时候,只对比带有patch flag的节点,并且可以通过flag的信息得知当前节点要对比的具体内容
export const enum PatchFlags {
TEXT = 1,// 动态文本节点
CLASS = 1 << 1, // 2 // 动态 class
STYLE = 1 << 2, // 4 // 动态 style
PROPS = 1 << 3, // 8 // 动态属性,但不包含类名和样式
FULL_PROPS = 1 << 4, // 16 // 具有动态 key 属性,当 key 改变时,需要进行完整的 diff 比较。
HYDRATE_EVENTS = 1 << 5, // 32 // 带有监听事件的节点
STABLE_FRAGMENT = 1 << 6, // 64 // 一个不会改变子节点顺序的 fragment
KEYED_FRAGMENT = 1 << 7, // 128 // 带有 key 属性的 fragment 或部分子字节有 key
UNKEYED_FRAGMENT = 1 << 8, // 256 // 子节点没有 key 的 fragment
NEED_PATCH = 1 << 9, // 512 // 一个节点只会进行非 props 比较
DYNAMIC_SLOTS = 1 << 10, // 1024 // 动态 slot
HOISTED = -1, // 静态节点
// 指示在 diff 过程应该要退出优化模式
BAIL = -2
}
-
2.hoistStatic 静态提升
- Vue2中无论元素是否参与更新, 每次都会重新创建, 然后再渲染
- Vue3中对于不参与更新的元素, 会做静态提升, 只会被创建一次, 在渲染时直接复用即可
-
3.cacheHandlers 事件侦听器缓存
- 默认情况下onClick会被视为动态绑定, 所以每次都会去追踪它的变化,但是因为是同一个函数,所以没有追踪变化, 直接缓存起来复用即可
vue3.x的安装和使用
方式1
<script src="https://unpkg.com/vue@next"></script>
方式2
利用脚手架搭建vue3.x项目
npm init vite-app [project-name项目名称可选]
cd <project-name>
npm install
npm run dev
方式3
npm install -g @vue/cli
# OR yarn global add @vue/cli
vue create hello-vue3
# select vue 3 preset
关于setup函数的使用
<template>
<div>
<h1>vue3的组合特性</h1>
<input type="text"
v-model="title"
@change.13="saveTodo">
<ul v-for="ele in todos">
<li>序号:{{ ele.id }}</li>
<li>条目:{{ ele.title }}</li>
</ul>
</div>
</template>
<script>
// reactive 是 vue3 提供的一个函数,可以对 对象和数组 这种复合数据类型进行包装,返回一个新的对象;该对象可以实现响应式。
// ref 是 vue3 提供的一个函数,可以对 基本数据类型(字符串,Boolean) 进行包装,返回一个新的对象;该对象可以实现响应式。
import { reactive, ref } from 'vue'
export default {
name: "Composition",
// 是vue3 提供的一个新的类似生命周期的函数。自动的执行,执行是在 之前 vue2 的 created 之前,并且里面没办法获取 this 的
setup () {
var todos = reactive([{ id: 1, title: '吃饭' }, { id: 2, title: '睡觉' }, { id: 3, title: '打豆豆' },])
var title = ref('');
function saveTodo () {
var tmp = {
id: todos.length + 1,
title: title.value
};
title.value = ''
todos.push(tmp)
}
return { todos, title, saveTodo }
}
}
</script>
<style scoped>
</style>
关于reactive和ref的使用
在setup中必须用reactive去包裹复合数据类型和用ref去包裹基本数据类型 这个数据才能被动态地使用
// reactive 是 vue3 提供的一个函数,可以对 对象和数组 这种复合数据类型进行包装,返回一个新的对象;该对象可以实现响应式。
// ref 是 vue3 提供的一个函数,可以对 基本数据类型(字符串,Boolean) 进行包装,返回一个新的对象;该对象可以实现响应式。
<template>
<div>
<h2> ref 和 reactive api</h2>
<!--ref包装的对象,在视图上使用的时候直接使用,不需要.value-->
<p>{{ number1 }}</p>
<!--<p>{{ number1.value }}</p>-->
<button @click="add">点击增加 +1</button>
<button @click="addArr">点击为数组增加元素</button>
<ul>
<li v-for="ele in arr">{{ ele }}</li>
</ul>
</div>
</template>
<script>
import { ref, reactive, isRef, isReactive } from "vue";
export default {
setup () {
let number1 = ref(12);
function add () {
number1.value++;
}
let arr = reactive([1, 2, 3, 5, 4])
function addArr () {
arr.push(Math.random());
}
return { number1, add, arr, addArr }
}
}
</script>
<style>
</style>
生命周期函数
生命周期函数必须写在setup函数中
<template>
<div>
<h2>生命周期函数</h2>
<p>{{ number1 }}</p>
<button @click="fn">+1</button>
</div>
</template>
<script>
// 在vue3 里面 生命周期函数的名称发生了变化,api调用方式也发生变化。
import { onMounted, onUpdated, ref } from 'vue'
export default {
name: "ComLife",
// mounted(){}, vue2 里面的写法
setup () {
console.log('setup');
let number1 = ref(0);
function fn () {
number1.value++;
}
// 生命周期函数需要在 setup 里面注册使用
onMounted(() => {
console.log('onMounted');
})
onUpdated(() => {
console.log('onUpdated');
})
return { number1, fn }
}
}
</script>
<style scoped>
</style>