携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 24 天,点击查看活动详情
前言
- 记录一下学习
setup
的笔记。
开始
可以理解 setup 是 Vue3 中一个新的配置项,值为一个函数,是使用组合式 API 的入口。
1. 先不说组合式API是什么,先去看看 setup 的基础使用。
为了更加方便的演示,我将演示案例,放在app页面
的组件 demo
中演示案例。
主页面 app.vue
<template>
<div>
我是 app 主页面
<demo />
</div>
</template>
<script>
import demo from '@/components/demo.vue'
export default {
components: {
demo,
},
}
</script>
组件 demo.vue
<template>
<div>我是demo组件,今天学习 setup的基础使用</div>
</template>
<script>
export default {
setup() {},
}
</script>
总结:
由上可得,setup和之前 vue2 中的 data methond类似,setup 也是一个配置项。它是一个函数;
2. setup 既然是函数,我比较关注四件事:
-
可以做什么;
-
返回值;
-
传入参数;
-
this指向;
2.1 可以做什么
组件中所用到的:数据、方法等等,均要配置在 setup 中。
示例:
<script>
export default {
setup() {
// 组件中所用到的:数据、方法等等,均要配置在setup中。
let name = 'tomato'
function say() {
console.log('I like tomato!!!')
}
},
}
</script>
2.2 返回值
返回值目前有两种:
- 在
setup()
函数中返回的对象会暴露给模板和组件实例。其它的选项也可以通过组件实例来获取setup()
暴露的属性; - 可以返回一个渲染函数;
主要还是使用第一种返回值,用来暴露数据给模板和组件实例。第二种返回值,暂时了解;
情况一示例:
<template>
<div>
<h3>我是demo1组件,今天学习 setup的基础使用</h3>
<div>我的名字 : {{ name }}</div>
<div @click="say">说话</div>
</div>
</template>
<script>
export default {
setup() {
// 组件中所用到的:数据、方法等等,均要配置在setup中。
let name = 'tomato'
function say() {
console.log('I like tomato!!!')
}
return {
name,
say,
}
},
}
</script>
情况二示例:
<script>
// h函数 以后在细说,现在理解它就是渲染函数,根据传入的参数,返回dom结构
import { h } from 'vue'
export default {
setup() {
const text = '渲染函数'
return () => h('h3', text)
},
}
</script>
2.3 传入参数
两个参数:
setup
函数的第一个参数是组件的props
。和标准的组件一致,一个setup
函数的props
是响应式的,并且会在传入新的 props 时同步更新。- 传入
setup
函数的第二个参数是一个 Setup 上下文对象。上下文对象暴露了其他一些在setup
中可能会用到的值:
主页面 app.vue
<template>
<div>
我是 app 主页面
<demo :name="appName" :age="appAge" :other="appOther"> </demo>
</div>
</template>
<script>
import demo from '@/components/demo.vue'
export default {
components: {
demo,
},
// 这里可以看得出来 vue3中依旧兼容 vue2中的写法 例如data
data() {
return {
appName: 'lazy',
appAge: '18',
appOther: '其他属性',
}
},
}
</script>
组件 demo.vue
<template>
<div>
<h3>我是demo1组件,今天学习 setup的基础使用</h3>
</div>
</template>
<script>
export default {
props: {
name: String,
age: String,
},
setup(props, context) {
console.log(props)
// {name: 'lazy', age: '18'}
console.log(context)
// { "attrs": { "other": "其他属性" },"slots": {} }
// 这里我就演示了一下 原本的 this.$attrs的数据。现在放在了 context 上
// 除了attrs 还有这些属性 { attrs, slots, emit, expose }
},
}
</script>
2.4 this指向
setup
中的 this
为 undefined
,这一点 vue3 和 vue2 还是有很大区别的,vue2可以通过 this
获取 data
中的数据 ,method
中的数据,vue3不行,需要注意。
<script>
export default {
setup() {
console.log(this)
// undefined
},
}
</script>
- setup函数的两种返回值:
- 若返回一个对象,则对象中的属性、方法, 在模板中均可以直接使用。(重点关注!)
- 若返回一个渲染函数:则可以自定义渲染内容。(了解)
- 注意点:
- 尽量不要与Vue2.x配置混用
- Vue2.x配置(data、methos、computed...)中可以访问到setup中的属性、方法。
- 但在setup中不能访问到Vue2.x配置(data、methos、computed...)。
- 如果有重名, setup优先。
- setup不能是一个async函数,因为返回值不再是return的对象, 而是promise, 模板看不到return对象中的属性。(后期也可以返回一个Promise实例,但需要Suspense和异步组件的配合)
- 尽量不要与Vue2.x配置混用
3. expose
看到官网介绍 setup的时候,有这么一个属性做了介绍。
expose
函数用于显式地限制该组件暴露出的属性,当父组件通过模板引用访问该组件的实例时,将仅能访问 expose
函数暴露出的内容:
app.vue
<template>
<div>
我是 app 主页面
<demo ref="demoRef"> </demo>
</div>
</template>
<script>
import demo from '@/components/demo.vue'
export default {
components: {
demo,
},
mounted() {
console.log(this.$refs.demoRef)
console.log(this.$refs.demoRef.name)
this.$refs.demoRef.say()
},
}
</script>
demo.vue
<script>
export default {
setup(props, { expose }) {
expose({
name: '暴露的数据',
say() {
alert('番茄真酷!!')
},
})
},
}
</script>
说明:
- 其实主要作用就是,隐藏组件内部的属性,通过 expose 暴露我们想要暴露的数据。
- 在组件的 setup 使用 expose 需要借助 setup的第二个参数 context;
- 访问的时候,我这里演示的是使用
this.refs
去访问
4. 和vue2的选项配置之间的数据访问
- Vue2 配置(data、methos、computed...)中可以访问到 setup 中的属性、方法。
- 但在 setup 中不能访问到 Vue2 配置(data、methos、computed...)。
- 如果有重名, setup 优先。
建议:不要混用 API 以免混淆。
<template>
<div>
<!-- 1.验证第一条 vue2中的配置 (这里演示的是data) 可以访问 setup 的属性 -->
{{ likeName }}
<!-- setup的名称 -->
<!-- 3.验证第三条 如果有重名,setup 优先 -->
{{ hobby }}
<!-- study -->
</div>
</template>
<script>
export default {
data() {
return {
likeName: name,
age: 18,
hobby: 'play game',
}
},
setup() {
let name = 'setup的名称'
// 2. setup 中不能访问到 Vue2 配置 (这里演示的是data)
// console.log('验证第二条', age) // Uncaught ReferenceError: age is not defined
let hobby = 'study'
return {
name,
hobby,
}
},
}
</script>
总结
总结一下今天的收获:
收获:
-
初步熟悉了 setup这个配置项;
-
熟悉了它的:作用;传参;返回值;this指向;
-
还可以通过
expose
,来限制暴露出去的属性; -
学习了 setup 和 vue2 常用的配置项之间数据访问的细节;
遗留疑问:
- 组合式API还不知道是什么意思。
- setup 的第二个参数,还有一些没有属性没有用到。(本次就体验到了 attr 和 expose)
- 数据虽然在组件上显示了,但是不是响应式的。
end
- 加油啦!