05. script_setup中的私有属性

197 阅读1分钟

<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。解决Vue3.0中setup需要繁琐将声明的变量、函数以及 import 引入的内容通过return向外暴露,才能在<template/>使用的问题。

那么我们怎么在 Vue3 script setup 中设置私有属性呢?

有时,当一个组件被 $ref 访问时,我们想指定该组件中的哪些属性可被访问,哪些不可访问。这里的不可访问,我们暂且先称作私有属性。那怎么来实现私有属性呢?

这个可以使用 Vue3 中新出的 expose 属性,直接看下面的例子:

<template>
  <div>
    <p>私有数据:{{ privateData }}</p>
    <p>私有数据(大写):{{ upperCasePrivateData }}</p>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        privateData: 'secrecy'
      };
    },
    computed: {
      upperCasePrivateData() {
        return this.privateData.toUpperCase();
      }
    }
  };
</script>

父组件中引入 SetupInfo,在 SetupInfo 组件中,我们声明了一个 privateData 值为 secrecy,然后还有个计算属性 upperCasePrivateData 它的值是privateData 的大写形式。最后,在模板中把两个值显示出来,如下所示:

image.png

在父组件中,引入一个 ref 值,用来访问 SetupInfo 组件中的内容,如下所示:

<template>
  <SetupInfo ref="useRef" />
</template>

<script setup lang="ts">
  import SetupInfo from '@/components/SetupInfo.vue';
  const useRef = ref(null);
  onMounted(() => {
    console.log(useRef.value.privateData);
    console.log(useRef.value.upperCasePrivateData);
  });
</script>

<style scoped></style>

如上所示,声明了一个 useRef 表示对 SetupInfo 组件的引用,然后再 onMounted 函数中也就是组件挂载完成时,把 useRef 的值打印出来,如下所示:

image.png

如是我们不想让外界访问到 SetupInfo 组件中的 privateData 值,那么,我们可以在 SetupInfo 中使用 expose,它是一个数组,数组元素表示要暴露出来的属性。

在这里,我们只暴露 upperCasePrivateData 的值,那么可以这么写:

<script>
  export default {
    expose: ['upperCasePrivateData'],
    data() {
      return {
        privateData: 'secrecy'
      };
    },
    computed: {
      upperCasePrivateData() {
        return this.privateData.toUpperCase();
      }
    }
  };
</script>

运行:

image.png

此时查看控制台,privateData 已经为 undefined。

本节 expose 用法,使用的选项 API ,使用组合 API 怎么写呢? 改造如下:

<template>
  <div>
    <p>私有数据:{{ privateData }}</p>
    <p>私有数据(大写):{{ upperCasePrivateData }}</p>
  </div>
</template>

<script setup lang="ts">
  const privateData = ref('secrecy');

  const upperCasePrivateData = computed(() => {
    return privateData.value.toUpperCase();
  });

  defineExpose([upperCasePrivateData]);
</script>

<style scoped></style>

特别注意: 如果使用<script setup> 方式,那么情况是与选项 API 方式完全相反的,表示外面访问不到里面的内容,除非使用 defineExpose 暴露出去,这点是需要注意的。