likes
comments
collection
share

通过vue3下Dialog组件说下函数式开发解决的痛点

作者站长头像
站长
· 阅读数 28
  1. 先用vue3写一个vue2常见的Dialog组件的伪代码:
<template>
  <Dialog :state="state">
    <div>我是弹窗内容</div>
    <button @click="submit">提交</button>
  </Dialog>
</template>

<script setup>
import Dialog from '@/component/Dialog'
import { ref } from 'vue'

const state = ref(false)

function open(id) {
  state.value = true
  if(id) {
    // ...
  }
}
  const emit = defineEmits(['update'])

function submit() {
  state.value = false
  emit('update')
}

defineExpose({
  open
})
</script>
  1. 父组件在使用的时候:
<template>
  <button @click="openDialog">打开弹窗</button>
  <MyDialog :ref="dialog" @update="getData">
</template>
<script setup>
import MyDialog from './MyDialog.vue'
import { ref } from 'vue'
const dialog = ref()

function openDialog() {
  dialog.value.open()
}
</script>

父组件通过调用子组件暴露的open方法去控制状态,并且还能通过参数就行初数据交互,子组件通过emit暴露方法给父组件交互.

痛点

MyDialog组件一般是对组件库的Model组件进行的二次封窗,假如我想修改或响应Model配置和事件,我要在一级父组件下去调用MyDialog下的定义的方法和属性,然后再传给三级组件.

这样当业务和UI变的越来越复杂的时候,MyDialog组件也许会有多个props,emits,exposes.

如果我们让想父组件直接和三级组件通讯,略过MyDialog转手的繁琐,怎么办呢.

vue3万能的hook

我们把MyDialogDialog组件都用jsx use的形式去写.

// Dialog.jsx
import { reactive, toRefs } from 'vue'
export function useDialog(/*init参数*/) {
  const config = reactive({
    state: false,
    title: '',
    loadingL false
  })
  const Dialog = defineComponent({
    setup(_props, { emit, slots }) {
      return () => <NModel v-model:show={config.state}>
        {slots.default()}
      </NModel>
    }
  })
  return {
    ...toRefs(config),
    Dialog
  }
}
// MyDialog.jsx
import { useDialog } from '@/component/Dialog'

export function useMyDialog(...props) {
  const { Dialog, ...config } = useDialog(...props)
  const MyDialog = defineComponent({
    setup(_props, { emit, slots }) {
      return () => <Dialog>
        // ...
      </Dialog>
  })
  return {
     ...config,
     MyDialog
  }
}

当我们父组件去调用弹窗组件的时候,通过useMyDialog传入的参数,就能控制最底层的封装组件,通过返回的refs获取最原始的响应值.

总结

这样的一个demo也许并不实用,例如二级组件是需要经常手写的,用jsxtemplate麻烦一些.

但是函数式开发的思路还是要掌握的,通过参数和返回值代替vue2的propemit我认为是大势所趋.vue3的prox代理模式也许比react更适合useHook.

转载自:https://juejin.cn/post/7176842885818482745
评论
请登录