Vue3
- 一 Vue3的变化
- 二 创建Vue3项目的两种方式
- 2.1 vue-cl创建
- 2.2 vite创建
- 三 常用API
- 3.1 setup
- 3.2 ref和reactive
- 3.3 计算和监听属性
- 3.4 生命周期
- 3.5 自定义hook函数
一 Vue3的变化
-
性能的提升
打包大小减少41%初次渲染快55%, 更新渲染快133%
内存减少54%
-
源码的升级
使用Proxy代替defineProperty实现响应式重写虚拟DOM的实现和Tree-Shaking
-
拥抱TypeScript
Vue3可以更好的支持TypeScript -
新的特性
Composition API(组合API)setup配置
ref与reactive
watch与watchEffect
provide与inject
新的内置组件Fragment
Teleport
Suspense
其他改变新的生命周期钩子
data 选项应始终被声明为一个函数
移除keyCode支持作为 v-on 的修饰符 -
组合式API和配置项API
使用传统OptionsAPI中,新增或者修改一个需求,就需要分别在data,methods,computed里修改 。组件中的template标签可以没有根标签
二 创建Vue3项目的两种方式
2.1 vue-cl创建
vue-cli创建和之前创建vue2一样,选择vue版本时选择3.x即可。
2.2 vite创建
创建的项目将使用基于 Vite 的构建设置,并允许我们使用 Vue 的单文件组件 (SFC)。
-
在终端输入以下命令
npm init vue@latest
-
cd到项目文件夹,执行npm install,然后执行npm run dev
-
项目启动成功,访问网址。
-
也可在vscode中打开项目文件夹
三 常用API
3.1 setup
-
setup为Vue3.0中一个新的配置项,值为一个函数
-
setup是所有Composition API(组合API)编写的位置
-
组件中所用到的:数据、方法等等,均要配置在setup中
-
setup函数的返回值:返回一个对象,对象中的属性、方法, 在模板中均可以直接使用
注意:
尽量不要与Vue2.x配置混用
Vue2.x配置(data、methos、computed…)中可以访问到setup中的属性、方法。
但在setup中不能访问到Vue2.x配置(data、methos、computed…)。
如果有重名, setup优先。
<template>
{{ name }}
<br>
{{ age }}
<br>
<button @click="ageAdd">点击年龄+1</button>
</template>
<script>
export default {
name: 'App',
created(){
console.log(this)
},
setup() {
let name = 'xuxiaoxu'
let age = 18
console.log(this)
let ageAdd = () => {
age++
console.log(age)
}
return {
name, age,ageAdd
}
}
}
</script>
注意:
- setup函数中没有了this,在setup函数外是有this的,但是不是Vc实例了,而变成了Proxy实例。
- 所有的变量和方法都在setup函数中写。
- 定义了变量,变量可以渲染,但是没有响应式,值变了,但是渲染的值没有跟着改变。
- setup必须要有返回值,返回的值才能在模板中使用。
3.2 ref和reactive
-
作用: 定义一个响应式的数据
-
语法: const 变量= ref(值)
创建一个包含响应式数据的引用对象(reference对象,简称ref对象)。
JS中操作数据: 变量.value
模板中读取数据: 不需要.value,直接:{{变量}}
<template>
{{ name }}
<br>
{{ age }}
<br>
<button @click="ageAdd">点击年龄+1</button>
</template>
<script>
import { ref } from 'vue'
export default {
name: 'App',
setup() {
let name = ref('xuxiaoxu')
let age = ref(18)
console.log(name)
console.log(age)
let ageAdd = () => {
age.value++
console.log(age.value)
}
return {
name, age,ageAdd
}
}
}
</script>
-
接收的数据可以是:基本类型、也可以是对象类型。
基本类型的数据:响应式依然是靠Object.defineProperty()的get与set完成的
对象类型的数据:内部 求助 了Vue3.0中的一个新函数—— reactive函数
<template>
{{ info.name }}
<br>
{{ info.age }}
<br>
<button @click="info.ageAdd">点击年龄+1</button>
</template>
<script>
import { reactive } from 'vue'
export default {
name: 'App',
setup() {
let info = reactive({
name: 'xuxiaoxu',
age: 18
})
info.ageAdd = () => {
info.age += 1
console.log(info.age)
}
console.log(info)
return {
info
}
}
}
</script>
对象在渲染时直接对象点key就可以获取到value,也可以直接给对象添加方法。
3.3 计算和监听属性
computed函数使用
<template>
<p>姓:<input type="text" v-model="info.firstName"></p>
<p>名:<input type="text" v-model="info.lastName"></p>
<p>全名:<input type="text" v-model="info.fullName"></p>
</template>
<script>
import { computed, reactive } from 'vue'
export default {
name: 'App',
setup() {
const info = reactive({
firstName: '',
lastName: ''
})
info.fullName = computed({
get() {
return info.firstName + '_' + info.lastName
},
// 修改属性会执行set函数,并将修改后的值传入
set(val) {
console.log(val)
let strArray = val.split('_')
info.firstName = strArray[0]
info.lastName = strArray[1]
}
})
return {
info
}
}
}
</script>
watch函数
<template>
<p><input type="text" v-model="name">{{ name }}</p>
</template>
<script>
import { watch, ref, watchEffect } from 'vue'
export default {
name: 'App',
setup() {
const name = ref('xuxiaoxu')
watch(name, (value, oldvalue) => {
console.log(value)
console.log(oldvalue)
})
watchEffect(()=>{
// 只有当watchEffect里使用的变量值改变才会执行该函数
let a = name.value
console.log('执行了')
})
return {
name
}
}
}
</script>
3.4 生命周期
- beforeCreate:在组件实例初始化完成之后立即调用。组合式 API 中的 setup() 钩子会在所有选项式 API 钩子之前调用,beforeCreate() 也不例外。
- created:在组件实例处理完所有与状态相关的选项后调用。当这个钩子被调用时,以下内容已经设置完成:响应式数据、计算属性、方法和侦听器。然而,此时挂载阶段还未开始,因此 $el 属性仍不可用。
- beforeMount:在组件被挂载之前调用。当这个钩子被调用时,组件已经完成了其响应式状态的设置,但还没有创建 DOM 节点。它即将首次执行 DOM 渲染过程。这个钩子在服务端渲染时不会被调用。
- mounted:在组件被挂载之后调用。这个钩子在服务端渲染时不会被调用。
- beforeUpdate:在组件即将因为一个响应式状态变更而更新其 DOM 树之前调用。
- updated:在组件因为一个响应式状态变更而更新其 DOM 树之后调用。
- beforeUnmount:在一个组件实例被卸载之前调用。当这个钩子被调用时,组件实例依然还保有全部的功能。
- 在一个组件实例被卸载之后调用。可以在这个钩子中手动清理一些副作用,例如计时器、DOM 事件监听器或者与服务器的连接。
<template>
<h1>生命周期</h1>
<hr>
<button @click="handleClick">点我消失</button>
<Child v-if="show"></Child>
</template>
<script>
import Child from "./components/Child.vue";
import { ref } from 'vue'
export default {
name: 'App',
components: { Child },
setup() {
let show = ref(true)
const handleClick = () => {
show.value = !show.value
}
return {
show, handleClick
}
}
}
</script>
<template>
<h1>我是Child组件</h1>
</template>
<script>
import {onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted} from 'vue'
export default {
name: 'Child',
setup() {
console.log('组合式api的beforeCreate')
console.log('组合式api的created')
onBeforeMount(() => {
console.log('组合式api的onBeforeMount')
})
onMounted(() => {
console.log('组合式api的onMounted')
})
onBeforeUpdate(() => {
console.log('组合式api的onMounted')
})
onBeforeUnmount(() => {
console.log('组合式api的onBeforeUnmount')
})
onUnmounted(() => {
console.log('组合式api的onUnmounted')
})
return{}
}
}
</script>