使用js方法调用获取弹窗信息

67 阅读1分钟

在new Promise作用域外更改状态

假设你有多个页面的一些功能需要先收集用户的信息才能允许使用,在点击使用某功能前先弹出信息收集的弹框,你会怎么实现呢?

  1. 创建收集信息的弹窗组件

<template>
  <el-dialog
    :modelValue="isShowUserInfo"
    title="Warning"
    width="500"
    align-center
  >
    <el-form :model="form" label-width="120px">
      <el-form-item label="用户名">
        <el-input v-model="form.name" />
      </el-form-item>
      <el-form-item label="密码">
        <el-input v-model="form.password" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">同意</el-button>
        <el-button @click="onCancel">取消</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

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

defineProps({
  isShowUserInfo: Boolean
})

const form = ref({ name: '', password: '' })

const emit = defineEmits(['onSubmit', 'onCancel'])
const onSubmit = () => {
  emit('onSubmit', form.value)
}

const onCancel = () => {
  emit('onCancel', 'onCancel')
}
</script>

<style lang="scss" scoped></style>
  1. 封装hooks

import { provide, ref } from 'vue'

const useGetInfo = () => {
  const isShowUserInfo = ref(false)

  let resolveFn, rejectFn

  provide('getInfo', () => {
    isShowUserInfo.value = true
    return new Promise((resolve, reject) => {
      resolveFn = resolve
      rejectFn = reject
    })
  })

  const onSubmit = (value) => {
    isShowUserInfo.value = false
    resolveFn && resolveFn(value)
  }

  const onCancel = (value) => {
    isShowUserInfo.value = false
    rejectFn && rejectFn(new Error(value))
  }

  return {
    isShowUserInfo,
    onSubmit,
    onCancel
  }
}

export default useGetInfo
  1. 在父级页面注册弹窗组件

<script setup>
import userInfoCom from '@/components/userInfoCom.vue'
import useGetInfo from '@/hooks/useGetInfo'

const { isShowUserInfo, onSubmit, onCancel } = useGetInfo()
</script>

<template>
  <router-view></router-view>
  <user-info-com
    :isShowUserInfo="isShowUserInfo"
    @onSubmit="onSubmit"
    @onCancel="onCancel"
  ></user-info-com>
</template>
  1. 需要使用的组件只需inject

const getInfo = inject('getInfo')

const handelClick = async () => {
  try {
    const res = await getInfo()
    console.log(res)
  } catch (error) {
    console.dir(error.message)
  }
}

<template>
  <el-button type="primary" @click="handelClick">showUserInfo</el-button>
</template>