亲爱的视频版
博客内容已经录制了对应视频,点击可跳转
入口函数-setup
现在我们已经知道 为什么要使用组合式 API 了 ,那么接下来我们需要看的就是如何使用 组合式 API。
在 vue 组件之中,我们通过 setup 函数来使用 组合式 API。
那么下面我们将分别从函数的:
- 调用时机
- this 指向
- 函数参数
- 返回值
这四个方面来解析 setup
函数
调用时机与 this 指向
setup
函数在创建组件之前被调用,所以在 setup
被执行时,组件实例并没有被创建。
因此在 setup 函数中,我们将 没有办法 获取到 this 。
我们来看下面的这一段代码:
// 模板
<body>
<div id="app">
<component-b ></component-b>
</div>
</body>
// 配置对象
<script>
const component = {
setup() {
// 先于 created 执行,此时组件尚未创建,this 指向 window
console.log(this); // window
},
created() {
console.log(this); // proxy 对象 -> 组件实例
}
}
// 1. 通过 createApp 方法创建根组件,返回根组件实例
const app = Vue.createApp(component)
// 2. 通过实例对象的 mount 方法进行挂载
app.mount('#app')
</script>
函数参数
对于 setup
函数来说,它接收两个参数,分别为:
- props
- context
props
通过 prop
传递过来的所有数据,我们都可以在这里进行接收。并且获取到的数据将保持响应性。
我们看下面的代码:
父组件:
// 模板
<body>
<div id="app">
<component-b ></component-b>
</div>
</body>
// 配置对象
<script>
const component = {
setup() {
// 先于 created 执行,此时组件尚未创建,this 指向 window
console.log(this); // window
},
created() {
console.log(this); // proxy 对象 -> 组件实例
},
components: {
componentB
}
}
// 1. 通过 createApp 方法创建根组件,返回根组件实例
const app = Vue.createApp(component)
// 2. 通过实例对象的 mount 方法进行挂载
app.mount('#app')
</script>
子组件:
const componentB = {
props: {
title: {
type: String,
required: true
}
},
setup(props) {
console.log(props); // Proxy {title: "父组件传递过来的 title"}
console.log(props.title); // "父组件传递过来的 title"
},
template: `
<div>{{title}}</div>
`
}
context
context 是一个 JavaScript 对象,这个对象暴露了三个组件的属性,我们可以通过 解构 的方式来分别获取这三个属性
// setup(props, context) {
setup(props, { attrs, slots, emit }) {
// Attribute (非响应式对象) 非 props 数据
console.log(attrs)
// 插槽 (非响应式对象)
console.log(slots);
// 触发事件 (方法) === this.$emit
console.log(emit);
}
attrs: 它是绑定到组件中的 非 props 数据,并且是非响应式的。
slots: 是组件的插槽,同样也不是 响应式的。
emit: 是一个方法,相当于 vue2 中的 this.$emit 方法。
然后我们通过下面的代码,来看一下这三个属性的实际使用:
// 父组件
<body>
<div id="app">
<component-b desc="父组件传递过来的普通属性" @update="onUpdate">
<h1>普通的匿名插槽</h1>
</component-b>
</div>
</body>
<script>
const component = {
methods: {
onUpdate(desc) {
console.log(desc); // 子组件更新的数据
}
},
components: {
componentB
}
}
// 1. 通过 createApp 方法创建根组件,返回根组件实例
const app = Vue.createApp(component)
// 2. 通过实例对象的 mount 方法进行挂载
app.mount('#app')
</script>
// 子组件
const componentB = {
props: {
title: {
type: String,
required: true
}
},
setup(props, { attrs, slots, emit }) {
// Attribute (非响应式对象)
console.log(attrs) // Proxy {desc: "父组件传递过来的普通属性", __vInternal: 1, onUpdate: ƒ}
// 插槽 (非响应式对象)
console.log(slots.default()); // [{__v_isVNode: true, __v_skip: true, type: "h1", …}]
// 触发事件 (方法)
// console.log(emit);
emit('update', '子组件更新的数据') // 发出一个事件,在父组件中监听这个事件,并进行打印
},
template: `
<div>{{title}}</div>
`
}
返回值
我们可以在 setup
函数中返回一个对象,这样我们就可以在模板中直接访问该对象中的属性和方法。
setup(props, { attrs, slots, emit }) {
return {
content: '这是 setup 中返回的数据',
onLog: () => {
console.log('调用 onLog 方法')
}
}
},
template: `
<div>
{{content}}
<button @click="onLog">log</button>
</div>
`
总结
那么我们最后总结一下 setup
函数的所有特性:
- setup 函数是组合式 API 的入口函数,它在 组件创建之前 被调用
- 因为在
setup
执行时组件尚未创建,setup
函数中的this
不是当前组件的实例 - 函数接收两个参数,props 和 context,context 可以解构为 attrs、slots、emit 函数
- 函数可以返回一个对象,对象的属性可以直接在模板中进行使用,就像之前使用 data 和 methods 一样。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!