vue3中更新知识点
分享给0107
createApp
应用初始化
import { createApp } from 'vue'
const app = createApp(App)
app.mount('#app')
mount
vue2中替换mount参数的节点
vue3中是mount节点的子节点 == innerHTML
data
只能接受返回对象的function
mixin
mixin中data的声明和data进行浅合并
setup
vue3中最大的更新就是新增了setup语法,setup中拿不到this。
组件实例的获取在setup中使用getCurrentInstance,拿到组件实例。
setup函数包括两个属性:props & context;
const ref = getCurrentInstance();
setup返回一个对象,对象可以在模板中直接使用
<template>
<div >
<p>{{count}}</p>
<button @click="onIncrease">increase</button>
<button @click="onDecrease">decrease</button>
</div>
</template>
<script lang="ts">
import { defineComponent, getCurrentInstance, ref } from 'vue'
export default defineComponent({
name: 'Home',
setup() {
const count = ref(0)
const onIncrease = () => count.value++
const onDecrease = () => count.value--
return {
count,
onIncrease,
onDecrease
}
}
})
</script>
具体的setup语法中的使用方式Vue3 Composition API -- setup内 props 和 component 使用
props
父组件传递给子组件的属性
context
包括三个属性: { attrs、slots、emit }
ref,reactive
vue3中组件的响应式,需要去手动声明了
其中ref可以用作单个基础类型变量的响应式,也可以用来保存组件实例的引用, 代码中读取ref的值都必须要通过.value的形式去读取,由这个也能推测出,vue基础类型的值实现响应式的原理就是通过把值包裹成一个对象去进行响应式的。内部同样是使用reactive包裹实现响应式。
获取html组件的dom实例方式:通过ref声明一个变量,在setup中返回,在vue模板中需要引用的dom元素上定义一个同名的ref属性,后可以在js中的onMounted属性中可以拿到
<template>
<div>
<button ref="btnRef" @click="onIncrease">increase</button>
</div>
</template>
<script lang="ts">
import { onMounted, ref } from 'vue'
export default defineComponent({
setup() {
const btnRef = ref(null)
onMounted(() => {
console.log(btnRef.value)
})
return {
btnRef
}
}
})
</script>
生命周期函数
删除了beforeCreate,created
| 选项式 API | setup 中 |
|---|---|
beforeCreate | -- |
created | -- |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
errorCaptured | onErrorCaptured |
renderTracked | onRenderTracked |
renderTriggered | onRenderTriggered |
activated | onActivated |
deactivated | onDeactivated |
虚拟的Fragment
原来的vue2中,模板代码必须包含在一个html标签之内,vue3之后实现了一个虚拟的Fragment,可以直接把代码并列书写
<template>
<p>{{name}}</p>
<p>1</p>
<p>2</p>
<p>3</p>
</template>
h函数
h在vue2中是render函数的参数
vue3中是从vue中引入的
import { h } from 'vue'
nextTick
vue2中使用是vm.$nextTick
vue3中需要从vue中引入
import { nextTick } from 'vue'
自定义组件v-model
v-model prop 和事件默认名称调整: value更改为modelValue, input更改为update:modelValue
。同时一个组件上可以有多个v-model
vue2中子组件中需要定义model
model: {
prop: 'title',
event: 'change'
},
vue3中不需要定义了,但需要显式的定义emit
child2.vue
<template>
<input id="child2" type="text" :value="modelValue" @input="onInputChange">
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
props: {
modelValue: String
},
emits: ['update:modelValue'],
setup(props, { emit }) {
const onInputChange = (e: any) => {
emit('update:modelValue', e.target.value)
}
return {
onInputChange
}
}
})
</script>
parent.vue 定义modelValue, 通过@update:modelValue去显式更新modelvalue的值
<template>
<div>
<Child2 :modelValue="child2Value" @update:modelValue="child2Value = $event"></Child2>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, watch } from 'vue'
import Child2 from "./Child2.vue"
export default defineComponent({
components: {
Child2
},
setup() {
const child2Value = ref('1')
watch(child2Value, () => {
console.log('change value:', child2Value.value)
})
return {
child2Value,
}
}
})
</script>
其中删除了vue2中.sync语法
$listeners
移除。 vue2中$listeners包含了组件所有的监听事件,vue3中监听事件都包含在$attrs中
$attrs
vue2中$attrs、style和class在vnode中是分开定义的。
vue3中style、class和原生定义的属性都会包含在$attrs中, 同时也会包含定义的监听事件,以on开头的事件。
parent.vue
<Child id="child3" class="child3-demo"></Child>
child.vue
<template>
<label>
<input type="text">
</label>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
inheritAttrs: false
})
</script>
inheritAttrs:
- true: 最终的
html中,label上会有id和class属性 - false:
label上没有父组件上定义的属性
$children
vue3中删除了这个属性,需要通过ref获取子组件
off、$once
移除。 现在事件总线需要使用第三方库。
filters
移除。过滤器现在推荐使用computed或者函数去实现。
自定义指令
指令中新增了多个生命周期的勾子
const CustonDirective = {
created(el, binding, vnode, prevVnode) {}, // 新增
beforeMount() {},
mounted() {},
beforeUpdate() {}, // 新增
updated() {},
beforeUnmount() {}, // 新增
unmounted() {}
}
mounted 中 binding可以拿到组件实例,如果是Fragment, 自定义组件就会被忽略