发现expose函数
今天在看setup script语法糖的时候发现有说到context上的expose
函数,然后就查了一下这个函数,发现是在setRef中被使用到,源码中在对ref的value赋值时的代码如下。
value = vnode.component!.exposed || vnode.component!.proxy
不难看懂这句代码的意思,了解到expose是用来维护vue组件封装性的。
我们先看一下vue3中的ref方法:
ref方法用于创建一个响应式的数据,其使用方法大致如下:
1.先从vue中引入
import { ref } from 'vue';
2.使用ref方法创建数据
具体使用方式就是用ref方法包裹原本的数据。对象类型数据推荐使用reactive
激活响应式,详情见vue3响应式文档。
const testValue = ref(null);
const numberValue = ref(1);
const booleanValue = ref(false);
const stringValue = ref('string');
const arrVlue = ref([]);
3.返回数据到模板
这一步的目的是让模板能够使用到setup函数中的数据和方法,对于模板无需使用的数据和方法可以不进行返回。
return { testValue, numberValue, booleanValue, stringValue, arrVlue }
以上就是ref方法的使用方式,然后问题就来了,这个ref方法和expose函数有什么关系呢?别急,继续往下看
ref方法还有一种特殊的用法,就是像vue2中的ref一样,用来获取一个确定的vue组件实例。使用的方法就是上面所说,在定义了一个值为null的响应式数据之后,将其返回给模板使用即可。 现有如下情景:
1.父组件Father.vue
//Father.vue
<template>
<div @click="handleClick">
<h2>我是父组件!</h2>
<Child ref="child" />
</div>
</template>
<script>
import { defineComponent, ref } from 'vue';
import Child from './Child.vue'
export default defineComponent({
components: {
Child
},
setup() {
const child = ref(null)
const handleClick = () => {
console.log(child.value);
child.value.toDo();
}
return {
child,
handleClick
}
}
});
</script>
2.子组件Child.vue
//Child.vue
<template>
<span>我是子组件</span>
</template>
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
setup(props, context) {
const data1 = ref(1);
const data2 = ref('string');
const toDo = () => {
console.log('1');
}
return {
data1,
data2,
toDo
}
},
})
</script>
那么点击父组件会打印什么内容呢?结果如下:
不难看出child所获取到的就是子组件的实例,可以通过该实例调用其所有方法和访问其所有数据。
这样直接准确的拿到一个组件的实例的确很方便,但是有一个很大的问题——父组件能拿到子组件实例的所有属性和方法,那也就意味着子组件是没有满足封装性的。
为了解决这个问题,可以使用expose方法。
将子组件Child.vue改为如下内容
<template>
<span>我是子组件</span>
</template>
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
setup(props, context) {
const data1 = ref(1);
const data2 = ref('string');
const toDo = () => {
console.log('1');
}
context.expose({
data1
});
return {
data1,
data2,
toDo
}
},
})
</script>
其实也就只是增加了expose的调用,expose接收一个对象,里面包含了所有想从当前组件实例导出的内容,就像封装一个模块一样,只向外暴露一些必要的方法和数据。
再次点击父组件。
嗯?怎么报错了?看看child.value的内容:
可以发现child.value中没有vue组件实例的那些属性和方法了,只有写在expose函数中的内容,根本没有toDo方法,那肯定会报错了。
看到这里你应该已经明白expose函数
是干什么用的了,使用expose函数
来控制组件被ref时向外暴露的对象内容,借此来维护组件的封装性。
写在最后 (^.^)
如果觉得我写的还不错的话,可以赏我个点赞哦^.^
如果有写错的地方、写的不好的地方也请大家指出,供我纠正。
我是CoCoyY1,一个记录自己学习的前端热爱者。