vue2升级vue3:单文件组件概述 及 defineExpos/expose

像我这种react门徒被迫迁移到vue的,用管了TSX,地vue 单文件组件也不太感冒,但是vue3 单文件组件,造了蛮多api ,还不得去了解下

https://v3.cn.vuejs.org/api/sfc-script-setup.html#单文件组件-script-setup

definePropsdefineEmits没有什么好说的,就是setup中定义 props 与 emits。

useSlotsuseAttrs 它会返回与 setupContext.slots 和 setupContext.attrs

export default defineComponent({
  name: 'RefreshInterval',
  props: {//defineProps
    refreshFun: {
      type: Function,
    },
  },
  emits: ['change'],// defineEmits
  setup(props, { slots,attrs }) {//useSlots、useAttrs 
  }
})

其中比较迷惑的地方就是 defineexpose:

defineExpose

首先看官方文档:

https://v3.cn.vuejs.org/api/sfc-script-setup.html#defineexpose

使用 <script setup> 的组件是默认关闭的,也即通过模板 ref 或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script setup> 中声明的绑定

为了在 <script setup> 组件中明确要暴露出去的属性,使用 defineExpose 编译器宏:

<script setup>
import { ref } from 'vue'

const a = 1
const b = ref(2)

defineExpose({
  a,
  b
})
</script>

当父组件通过模板 ref 的方式获取到当前组件的实例,获取到的实例会像这样 { a: number, b: number } (ref 会和在普通实例中一样被自动解包)

翻译成大白话就是:子组件是<script setup>声明时,父组件(非<script setup>)是不能直接访问子组件的方法,需要子组件手动的抛出才行。即:refChildren.value.children.props 是无效的。

expose

官方文档:状态选项 | Vue.js

默认情况下,当通过 $parent、$root 或模板 refs 访问时,组件实例将向父组件暴露所有的实例 property。这可能不是我们希望看到的,因为组件很可能拥有一些应保持私有的内部状态或方法,以避免紧耦合。

expose 选项期望一个 property 名称字符串的列表。当使用 expose 时,只有显式列出的 property 将在组件实例上暴露

expose 仅影响用户定义的 property——它不会过滤掉内置的组件实例 property。

export default {
  // 只有 `publicMethod` 在公共实例上可用
  expose: ['publicMethod'],
  methods: {
    publicMethod() {
      // ...
    },
    privateMethod() {
      // ...
    }
  }
}

使用expose函数来控制组件被ref时向外暴露的对象内容,借此来维护组件的封装性

其实把它理解为 React函数组件 中的 useImperativeHandle 就行!

子组件利用useImperativeHandle可以让父组件输出任意数据。

// FancyInput组件作为子组件
const FancyInput = React.forwardRef(function FancyInput(props, ref) {
  const inputRef = useRef();

  // 命令式的给`ref.current`赋值个对象
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus()
    }
  }));
  
  return <input ref={inputRef} ... />
})

// Example组件作为父组件
function Example() {
  const fancyInputRef = useRef()

  const focus = () => {
    fancyInputRef.current.focus()
  }

  return (
    <>
      <FancyInput ref={fancyInputRef} />
    </>
  )
}

更多的,可以查看:Vue3 源码解析(九):setup 揭秘与 expose 的妙用  Vue3 源码解析(九):setup 揭秘与 expose 的妙用 - SegmentFault 思否

参考文章:

vue3-什么是expose,是如何使用的,以及defineExpose的用法 vue3-什么是expose,是如何使用的,以及defineExpose的用法_VtoC的博客-CSDN博客_expose vue3

Vue3中的expose函数 Vue3中的expose函数 - 掘金

最陌生的hooks: useImperativeHandle 最陌生的hooks: useImperativeHandle - SegmentFault 思否

useRef、useImperativeHandle 滑动验证页面

转载本站文章《vue2升级vue3:单文件组件概述 及 defineExpos/expose》,
请注明出处:vue2升级vue3:单文件组件概述 及 defineExpos/expose - vue3学习笔记 - 周陆军的个人网站

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值