其他
# 其他
# 生命周期钩子 🔥
setup中如何使用生命周期函数呢?可以使用直接导入的 onX 函数注册生命周期钩子:
- 可以每个使用多次!
下表包含如何在setup()内部调用生命周期钩子:
| 选项式 API | Hook inside setup |
|---|---|
beforeCreate | Not needed* |
created | Not needed* |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
errorCaptured | onErrorCaptured |
renderTracked | onRenderTracked |
renderTriggered | onRenderTriggered |
activated | onActivated |
deactivated | onDeactivated |
因为 setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup 函数中编写。
# Provide & Inject 函数—不推荐
事实上我们之前还学习过Provide和Inject,Composition API也可以替代之前的 Provide 和 Inject 的选项
我们可以通过 provide来提供数据:
- 可以通过 provide 方法来定义每个 Property;
- provide可以传入两个参数:
- name:提供的属性名称;
- value:提供的属性值;
在 后代组件 中可以通过 inject 来注入需要的属性和对应的值:
- inject可以传入两个参数:
- 要 inject 的 property 的 name;
- 默认值;
<template>
<div>
<home/>
<h2>App Counter: {{counter}}</h2>
<button @click="increment">App中的+1</button>
</div>
</template>
<script>
import { provide, ref, readonly } from 'vue';
import Home from './Home.vue';
export default {
components: {
Home
},
setup() {
const name = ref("coderwhy");
let counter = ref(100);
provide("name", readonly(name));
provide("counter", readonly(counter));
const increment = () => counter.value++;
return {
increment,
counter
}
}
}
</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
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
<template>
<div>
<h2>{{name}}</h2>
<h2>{{counter}}</h2>
<button @click="homeIncrement">home+1</button>
</div>
</template>
<script>
import { inject } from 'vue';
export default {
setup() {
const name = inject("name");
const counter = inject("counter");
const homeIncrement = () => counter.value++
return {
name,
counter,
homeIncrement
}
}
}
</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
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
# 示例
# useCounter.js
import { ref, computed } from 'vue';
export default function() {
const counter = ref(0);
const doubleCounter = computed(() => counter.value * 2);
const increment = () => counter.value++;
const decrement = () => counter.value--;
return {
counter,
doubleCounter,
increment,
decrement
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# useTitle.js
import { ref, watch } from 'vue';
export default function(title = "默认的title") {
const titleRef = ref(title);
watch(titleRef, (newValue) => {
document.title = newValue
}, {
immediate: true
})
return titleRef
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# useScrollPosition.js
import { ref } from 'vue';
export default function() {
const scrollX = ref(0);
const scrollY = ref(0);
document.addEventListener("scroll", () => {
scrollX.value = window.scrollX;
scrollY.value = window.scrollY;
});
return {
scrollX,
scrollY
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# useMousePosition.js
import { ref } from 'vue';
export default function() {
const mouseX = ref(0);
const mouseY = ref(0);
window.addEventListener("mousemove", (event) => {
mouseX.value = event.pageX;
mouseY.value = event.pageY;
});
return {
mouseX,
mouseY
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# useLocalStorage.js
我们来完成一个使用 localStorage 存储和获取数据的Hook
import { ref, watch } from 'vue';
export default function(key, value) {
const data = ref(value);
if (value) {
window.localStorage.setItem(key, JSON.stringify(value));
} else {
data.value = JSON.parse(window.localStorage.getItem(key));
}
watch(data, (newValue) => {
window.localStorage.setItem(key, JSON.stringify(newValue));
})
return data;
}
// 一个参数: 取值
// const data = useLocalStorage("name");
// 二个参数: 保存值
// const data = useLocalStorage("name", "coderwhy");
// 自动修改值
// data.value = "kobe";
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
# index.js
import useCounter from './useCounter';
import useTitle from './useTitle';
import useScrollPosition from './useScrollPosition';
import useMousePosition from './useMousePosition';
import useLocalStorage from './useLocalStorage';
export {
useCounter,
useTitle,
useScrollPosition,
useMousePosition,
useLocalStorage
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# setup script 🔥
<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。相比于普通的<script> 语法,它具有更多优势:
- 更少的样板内容,更简洁的代码。
- 能够使用纯 Typescript 声明 props 和抛出事件。
- 更好的运行时性能 (其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理)。
- 更好的 IDE 类型推断性能 (减少语言服务器从代码中抽离类型的工作)。
App.vue
<template>
<div>
<h2>当前计数: {{ counter }}</h2>
<button @click="increment">+1</button>
<hello-world message="呵呵呵" @increment="getCounter"></hello-world>
</div>
</template>
<script setup>
import { ref } from 'vue'
import HelloWorld from './HelloWorld.vue'
const counter = ref(0)
const increment = () => counter.value++
const getCounter = (payload) => {
console.log(payload)
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
HelloWorld.vue
<template>
<div>
<h2>Hello World</h2>
<h2>{{ message }}</h2>
<button @click="emitEvent">发射事件</button>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
const props = defineProps({
message: {
type: String,
default: '哈哈哈',
},
})
const emit = defineEmits(['increment', 'decrement'])
const emitEvent = () => {
emit('increment', '100000')
}
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
编辑 (opens new window)
上次更新: 2022/03/23, 17:55:39