#根据官网看vue3的变化
#Composition API
目的:把以前放在computed
、methods
、watch
内的代码组合一起放在同一个地方,方便阅读与理解,以前是散装的,现在融合。
方法:setup
参数:
- props
- context
注意点:
- 没有
this
- 只能访问组件内的
props
,通过参数获取
defineComponent
: 定义Vue组件
内部可以使用的方法
ref
: 返回一个响应式且可变的ref对象,可以用于组件实例ref实例toRefs
: 创建对prop的响应式引用computed
: 计算属性reactive
: 对象响应式,与传入的对象一致
<template>
<button type="button" @click="addSize">count is: {{ count }}</button>
<p>{{ size }}</p>
<p>{{ allMsg }}</p>
<p>{{ person.age }}</p>
</template>
<script lang="ts">
import { ref, defineComponent, onMounted, watch, toRefs, computed, reactive } from 'vue'
type Size = 'sm' | 'md' | 'lg'
export default defineComponent({
props: {
msg: {
type: String,
default: ''
}
},
setup: (props, context) => {
// 上下文中的三个属性
console.log(context.attrs)
console.log(context.slots)
console.log(context.emit)
// 响应式
const { msg } = toRefs(props)
const size = ref<Size>('md')
const person = reactive({ age: 18 })
const addSize = () => {
size.value = 'lg'
}
const update = () => {
size.value = 'sm'
window.console.log(`prop msg: ${msg.value}`)
}
// vue2的mounted方法
onMounted(update)
// vue2的computed方法
const allMsg = computed(() => size.value + msg.value);
// vue2的watch方法
watch(size, (newSize, oldSize) => {
if (newSize === 'lg') {
console.log(`new value is ${newSize}, old value is ${oldSize}`)
}
})
return { size, addSize, allMsg, person }
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
内部生命周期函数
onBeforeMount
onMounted
onBeforeMount
onBeforeUpdate
onBeforeMount
onUpdated
<script lang="ts">
import { defineComponent, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onMounted, onUnmounted, onUpdated } from 'vue'
export default defineComponent({
setup: () => {
onBeforeMount(() => {
console.log('beforeMount')
})
onMounted(() => {
console.log('mounted')
})
onBeforeUpdate(() => {
console.log('beforeUpdate')
})
onUpdated(() => {
console.log('update')
})
onBeforeUnmount(() => {
console.log('beforeUnmounted')
})
onUnmounted(() => {
console.log('unmounted')
})
return { }
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
provide
&inject
App.vue
<template>
<HelloWorld />
</template>
<script lang="ts">
import { defineComponent, provide, reactive, ref } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
export default defineComponent({
name: 'App',
components: {
HelloWorld
},
setup() {
const num = ref(0)
const person = reactive({ age: 18 })
const changePerson = () => {
person.age = 19;
}
provide('num', num)
provide('person', person)
provide('changePerson', changePerson)
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
HelloWorld.vue
<template>
<button @click="changePerson">test</button>
<p>inject num is {{ num }}, inject person age is {{ person.age }}</p>
</template>
<script lang="ts">
import { defineComponent, inject } from 'vue'
export default defineComponent({
setup: () => {
const num = inject('num')
const person = inject('person')
const changePerson = inject('changePerson')
return { num, person, changePerson }
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ref
实例
<template>
<div ref="root">
root node
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, ref } from 'vue'
export default defineComponent({
setup: () => {
const root = ref(null)
onMounted(() => {
console.log(root.value)
})
return { root }
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ref
+v-for
<template>
<ul>
<li v-for="(num, index) in nums" :key="num" :ref="el => numRef(el, index)">
{{ num }}
</li>
</ul>
</template>
<script lang="ts">
import { defineComponent, onBeforeUpdate, reactive, ref } from 'vue'
export default defineComponent({
setup: () => {
const nums = reactive([1, 2, 3])
let numRefs = ref<HTMLLIElement[]>([])
const numRef = (el: HTMLLIElement, idx: number) => {
numRefs.value[idx] = el
}
// 动态更新
onBeforeUpdate(() => {
numRefs.value = []
})
return { nums, numRefs, numRef }
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
watchEffect
<template>
<div ref="root">
root node
</div>
</template>
<script lang="ts">
import { defineComponent, ref, watchEffect } from 'vue'
export default defineComponent({
setup: () => {
const root = ref(null)
// 监听
watchEffect(() => {
console.log(root.value)
}, {
flush: 'post' // 是否在更新之后运行watch,post在dom更新之后
})
return { root }
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
teleport
:允许开发者控制渲染的DOM节点
<template>
<button @click="modalOpen = true">open</button>
<teleport to="body">
<div v-if="modalOpen">
<div>模态框</div>
<button @click="modalOpen = false">close</button>
</div>
</teleport>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
export default defineComponent({
setup() {
const modalOpen = ref(false);
return {
modalOpen
}
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23