[10. 生命周期的使用]
新版的生命周期函数,可以按需导入到组件中,且只能在 setup()
函数中使用,代码示例如下:
import { onMounted, onUpdated, onUnmounted } from 'vue'
const MyComponent = {
setup() {
onMounted(() => {
console.log('mounted!')
})
onUpdated(() => {
console.log('updated!')
})
onUnmounted(() => {
console.log('unmounted!')
})
}
}
下面的列表,是 vue 2.x 的生命周期函数与新版 Composition API 之间的映射关系:
-
beforeCreate
-> usesetup()
-
created
-> usesetup()
-
beforeMount
->onBeforeMount
-
mounted
->onMounted
-
beforeUpdate
->onBeforeUpdate
-
updated
->onUpdated
-
beforeDestroy
->onBeforeUnmount
-
destroyed
->onUnmounted
-
errorCaptured
->onErrorCaptured
[11. provide & inject]共享数据
provide()
和 inject()
可以实现嵌套组件之间的数据传递。这两个函数只能在 setup()
函数中使用。父级组件中使用 provide()
函数向下传递数据;子级组件中使用 inject()
获取上层传递过来的数据。
[11.1 共享普通数据]
App.vue
根组件:
<template>
<div id="app">
<h1>App 根组件</h1>
<hr />
<LevelOne />
</div>
</template>
<script>
import LevelOne from './components/LevelOne'
// 1. 按需导入 provide
import { provide } from '@vue/composition-api'
export default {
name: 'app',
setup() {
// 2. App 根组件作为父级组件,通过 provide 函数向子级组件共享数据(不限层级)
// provide('要共享的数据名称', 被共享的数据)
provide('globalColor', 'red')
},
components: {
LevelOne
}
}
</script>
LevelOne.vue
组件:
<template>
<div>
<!-- 4. 通过属性绑定,为标签设置字体颜色 -->
<h3 :style="{color: themeColor}">Level One</h3>
<hr />
<LevelTwo />
</div>
</template>
<script>
import LevelTwo from './LevelTwo'
// 1. 按需导入 inject
import { inject } from '@vue/composition-api'
export default {
setup() {
// 2. 调用 inject 函数时,通过指定的数据名称,获取到父级共享的数据
const themeColor = inject('globalColor')
// 3. 把接收到的共享数据 return 给 Template 使用
return {
themeColor
}
},
components: {
LevelTwo
}
}
</script>
LevelTwo.vue
组件:
<template>
<div>
<!-- 4. 通过属性绑定,为标签设置字体颜色 -->
<h5 :style="{color: themeColor}">Level Two</h5>
</div>
</template>
<script>
// 1. 按需导入 inject
import { inject } from '@vue/composition-api'
export default {
setup() {
// 2. 调用 inject 函数时,通过指定的数据名称,获取到父级共享的数据
const themeColor = inject('globalColor')
// 3. 把接收到的共享数据 return 给 Template 使用
return {
themeColor
}
}
}
</script>
如果我们确实希望改变父组件的数据,此时我们可以在父组件中设置方法,通过provide
将该方法传递给子组件,保证数据是数据提供的位置进行修改。
[11.2 共享 ref 响应式数据]
如下代码实现了点按钮切换主题颜色的功能,主要修改了 App.vue
组件中的代码,LevelOne.vue
和 LevelTwo.vue
中的代码不受任何改变:
<template>
<div id="app">
<h1>App 根组件</h1>
<!-- 点击 App.vue 中的按钮,切换子组件中文字的颜色 -->
<button @click="themeColor='red'">红色</button>
<button @click="themeColor='blue'">蓝色</button>
<button @click="themeColor='orange'">橘黄色</button>
<hr />
<LevelOne />
</div>
</template>
<script>
import LevelOne from './components/LevelOne'
import { provide, ref } from '@vue/composition-api'
export default {
name: 'app',
setup() {
// 定义 ref 响应式数据
const themeColor = ref('red')
// 把 ref 数据通过 provide 提供的子组件使用
provide('globalColor', themeColor)
// setup 中 return 数据供当前组件的 Template 使用
return {
themeColor
}
},
components: {
LevelOne
}
}
</script>
[12. template refs]
通过 ref()
还可以引用页面上的元素或组件。
[12.1 元素的引用]
示例代码如下:
<template>
<div>
<h3 ref="h3Ref">TemplateRefOne</h3>
</div>
</template>
<script>
import { ref, onMounted } from '@vue/composition-api'
export default {
setup() {
// 创建一个 DOM 引用
const h3Ref = ref(null)
// 在 DOM 首次加载完毕之后,才能获取到元素的引用
onMounted(() => {
// 为 dom 元素设置字体颜色
// h3Ref.value 是原生DOM对象
h3Ref.value.style.color = 'red'
})
// 把创建的引用 return 出去
return {
h3Ref
}
}
}
</script>
[12.2 组件的引用]
TemplateRefOne.vue
中的示例代码如下:
<template>
<div>
<h3>TemplateRefOne</h3>
<!-- 4. 点击按钮展示子组件的 count 值 -->
<button @click="showNumber">获取TemplateRefTwo中的count值</button>
<hr />
<!-- 3. 为组件添加 ref 引用 -->
<TemplateRefTwo ref="comRef" />
</div>
</template>
<script>
import { ref } from '@vue/composition-api'
import TemplateRefTwo from './TemplateRefTwo'
export default {
setup() {
// 1. 创建一个组件的 ref 引用
const comRef = ref(null)
// 5. 展示子组件中 count 的值
const showNumber = () => {
console.log(comRef.value.count)
}
// 2. 把创建的引用 return 出去
return {
comRef,
showNumber
}
},
components: {
TemplateRefTwo
}
}
</script>
TemplateRefTwo.vue
中的示例代码:
<template>
<div>
<h5>TemplateRefTwo --- {{count}}</h5>
<!-- 3. 点击按钮,让 count 值自增 +1 -->
<button @click="count+=1">+1</button>
</div>
</template>
<script>
import { ref } from '@vue/composition-api'
export default {
setup() {
// 1. 定义响应式的数据
const count = ref(0)
// 2. 把响应式数据 return 给 Template 使用
return {
count
}
}
}
</script>
[13. createComponent]
这个函数不是必须的,除非你想要完美结合 TypeScript 提供的类型推断来进行项目的开发。
这个函数仅仅提供了类型推断,方便在结合 TypeScript 书写代码时,能为 setup()
中的 props
提供完整的类型推断。
import { createComponent } from 'vue'
export default createComponent({
props: {
foo: String
},
setup(props) {
props.foo // <- type: string
}
})