文档:
API Reference
教程
课件
1. 初始化项目
// ① npm i -g @vue/cli // ② vue create my-project // ③ npm install @vue/composition-api -S // ④ main,js import Vue from 'vue' import VueCompositionApi from '@vue/composition-api' Vue.use(VueCompositionApi)
2. setup方法
setup
是vue3.x
中新的操作组件属性的方法,它是组件内部暴露出所有的属性和方法的统一API。
2.1 执行时机
setup的执行时机在:beforeCreate 之后 created之前
setup(props, ctx) { console.log('setup') }, beforeCreate() { console.log('beforeCreate') }, created() { console.log('created') },
// 通过 setup 函数的第一个形参,接收 props 数据: setup(props) { console.log(props) }, // 在 props 中定义当前组件允许外界传递过来的参数名称: props: { p1: String } /* {} p1: "传值给 com-setup" get p1: ƒ reactiveGetter() set p1: ƒ reactiveSetter(newVal) __proto__: Object */
2.3 context
setup
函数的第二个形参是一个上下文对象,这个上下文对象中包含了一些有用的属性,这些属性在 vue 2.x
中需要通过 this
才能访问到,在 vue 3.x
中,它们的访问方式如下:
setup(props, ctx) { console.log(ctx) console.log(this) // undefined }, /* attrs: Object emit: ƒ () listeners: Object parent: VueComponent refs: Object root: Vue ... */
3. reactive
reactive
函数接收一个普通函数,返回一个响应式的数据对象。
reactive
函数等价于 vue 2.x
中的 Vue.observable()
函数,vue 3.x
中提供了 reactive()
函数,用来创建响应式的数据对象,基本代码示例如下:
当前的 count 值为:{{count}}
4. ref
ref()
函数用来根据给定的值创建一个响应式的数据对象,ref()
函数调用的返回值是一个对象,这个对象上只包含一个 .value
属性:
02.ref.vue 文件
refCount:{{refCount}}
4.1 在 reactive 对象中访问 ref 创建的响应式数据
当把 ref()
创建出来的响应式数据对象,挂载到 reactive()
上时,会自动把响应式数据对象展开为原始的值,不需通过 .value
就可以直接被访问,例如:
setup() { const refCount = ref(0) const state = reactive({refCount}) console.log(state.refCount) // 输出 0 state.refCount++ // 此处不需要通过 .value 就能直接访问原始值 console.log(refCount) // 输出 1 return { refCount } }
setup() { // 创建 ref 并挂载到 reactive 中 const c1 = ref(0); const state = reactive({ c1 }); // 再次创建 ref,命名为 c2 const c2 = ref(9); // 将 旧 ref c1 替换为 新 ref c2 state.c1 = c2; state.c1++; console.log(state.c1); // 输出 10 console.log(c2.value); // 输出 10 console.log(c1.value); // 输出 0 }
5. isRef
isRef()
用来判断某个值是否为 ref()
创建出来的对象;应用场景:当需要展开某个可能为 ref()
创建出来的值的时候,例如:
import { ref, reactive, isRef } from "@vue/composition-api"; export default { setup() { const unwrapped = isRef(foo) ? foo.value : foo } };
6. toRefs
toRefs()
函数可以将 reactive()
创建出来的响应式对象,转换为普通的对象,只不过,这个对象上的每个属性节点,都是 ref()
类型的响应式数据。
03.toRefs.vue文件
{{ count }} - {{ name }}
7. computed计算属性
7.1 只读的计算属性
04.computed.vue文件
refCount: {{refCount}}
计算属性的值computedCount : {{computedCount}}
04.computed.vue文件
refCount: {{refCount}}
计算属性的值computedCount : {{computedCount}}
8. watch
watch()
函数用来监视某些数据项的变化,从而触发某些特定的操作,使用之前需要按需导入:
import { watch } from '@vue/composition-api'
05.watch.vue文件
refCount: {{refCount}}
8.2 监视数据源
监视 reactive
类型的数据源:
05.watch.vue文件
count: {{count}}
// 不是响应式数据
export default { setup() { // 定义数据源 let count = ref(0); // 指定要监视的数据源 watch(count, (count, prevCount) => { console.log(count, prevCount) }) setInterval(() => { count.value += 2 }, 2000) console.log(count.value) return { count } } };
8.3 监听多个数据源
监视 reactive
export default { setup() { const state = reactive({count: 100, name: 'houfei'}) watch( // 监听count name [() => state.count, () => state.name], // 如果变换 执行以下函数 ([newCount, newName], [oldCount, oldName]) => { console.log(newCount, oldCount) console.log(newName, oldName) }, { lazy: true} // 在 watch 被创建的时候,不执行回调函数中的代码 ) setTimeout(() => { state.count += 2 state.name = 'qweqweewq' }, 3000) return state } };
export default { setup() { // 定义数据源 const count = ref(10) const name = ref('zs') // 指定要监视的数据源 watch( [count, name], ([newCount, newName], [oldCount, oldName]) => { console.log(newCount, oldCount) console.log(newName, oldName) }, { lazy: true} ) setInterval(() => { count.value += 2 }, 2000) console.log(count.value) return { count } } };
8.4 清除监视
在 setup()
函数内创建的 watch
监视,会在当前组件被销毁的时候自动停止。如果想要明确地停止某个监视,可以调用 watch()
8.5 在watch中清除无效的异步任务
有时候,当被 watch
监视的值发生变化时,或 watch
本身被 stop
之后,我们期望能够清除那些无效的异步任务,此时,watch
回调函数中提供了一个 cleanup registrator function
来执行清除的工作。这个清除函数会在如下情况下被调用:
-
watch 被重复执行了
-
watch 被强制
stop
了
Template 中的代码示例如下
keywords:--- {{ keywords }}
9. provide & inject 组件传值
provide()
和 inject()
可以实现嵌套组件之间的数据传递。这两个函数只能在 setup()
函数中使用。父级组件中使用 provide()
函数向下传递数据;子级组件中使用 inject()
获取上层传递过来的数据。
9.1 共享普通数据
app.vue
父组件
son 组件
07.grandson.vue
son 组件:
grandson 组件
9.2 共享ref
响应式数据
app.vue
父组件
son 组件
grandson 组件
10. 节点的引用 template ref
TemplateRefOne
10.2 组件的引用
App
父组件:
父组件
son 组件
{{str1}}
<template> <div> <h3>09.nextTick 组件h3> <p>学习 $nextTickp> <button v-if="isShowInput === false" @click="showInput">展示文本框button> <input type="text" v-else ref="ipt"> div> template> <script> export default { data() { return { isShowInput: false } }, methods: { showInput() { this.isShowInput = !this.isShowInput // console.log(this.$refs) this.$nextTick(() => { this.$refs.ipt.focus() }) } } } script>