vue2升级vue3:单文件组件概述 及 defineExpos/expose
Author:zhoulujun Date:
像我这种react门徒被迫迁移到vue的,用管了TSX,地vue 单文件组件也不太感冒,但是vue3 单文件组件,造了蛮多api ,还不得去了解下
https://v3.cn.vuejs.org/api/sfc-script-setup.html#单文件组件-script-setup
defineProps、defineEmits没有什么好说的,就是setup中定义 props 与 emits。
useSlots、useAttrs 它会返回与 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
官方文档:https://staging-cn.vuejs.org/api/options-state.html#expose
默认情况下,当通过 $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 的妙用 https://segmentfault.com/a/1190000040179961
参考文章:
vue3-什么是expose,是如何使用的,以及defineExpose的用法 https://blog.csdn.net/vet_then_what/article/details/125515694
Vue3中的expose函数 https://juejin.cn/post/6943950109268770830
最陌生的hooks: useImperativeHandle https://segmentfault.com/a/1190000040758640
useRef、useImperativeHandle https://www.jianshu.com/p/20aa551e44e7
转载本站文章《vue2升级vue3:单文件组件概述 及 defineExpos/expose》,
请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/vue3/8872.html
延伸阅读:
- vue2升级vue3:组合式 API之Setup(props,context)—Vue2.x到Vue3注意
- vue2升级vue3:Vue2/3插槽——vue3的jsx组件插槽slot怎么处理
- vue3响应性API学习笔记
- Vue3新的内置组件
- vue2升级vue3:Vue3时jsx组件绑定自定义的事件、v-model、sync修
- vue2升级vue3:vue2 vue-i18n 升级到vue3搭配VueI18n v9
- vue2升级vue3: 全局变量挂载与类型声明
- vue2升级vue3: Event Bus 替代方案—— mitt
- vue2升级vue3:TypeScript下vuex-module-decorators/vuex-class to vuex4.x
- vue2升级vue3:class component的遗憾
- vue2升级vue3:this.$createElement is not a function—动态组件升级
- vue2升级vue3:异步组件defineAsyncComponent
- vue2升级vue3:webpack vue-loader 打包配置
- Uncaught (in promise) TypeError: 'get' on proxy: property X is a read-on
- vue2升级vue3:composition api中监听路由参数改变
- vue2升级vue3:vue3创建全局属性和方法
-
vue2升级vue3:Vue Router报错,directly inside
or - vue2升级vue3:vue3比vue2究竟好在哪里?
- vue2升级vue3:vue3 hooks库选用
- vue2升级vue3:Vue Demi打通vue2与vue3壁垒,构建通用组件
- vue2升级vue3: h、createVNode、render、createApp使用
- vue2升级vue3:provide与inject 使用注意事项
- vue2升级vue3: TSX Vue 3 Composition API Refs
- VUE3/TS/TSX入门手册指北
- vue2升级vue3:vue3中的watch和watchEffect细讲