Vue3 ElementPlus Dialog封装 (二:使用provide inject)

引言

上一章Vue3 ElementPlus Dialog封装 (一:使用props emit) prop+emit实现的方法用于父子组件比较方便, 跨多层次组件比较麻烦
vue3 中 还提供了provideinject方法供组件间通信(参考官网图片), 本篇使用该方法实现上章效果

在这里插入图片描述在这里插入图片描述

实现原理

参考官网provideinject例子

官方provide和inject例子

父组件provide如下数据

import { ref, provide } from "vue";
const dialogValue = ref({ name: '', email: '', visible: false })
provide('dialogValue', dialogValue)

MyDialoginject如下:

import { inject, ref } from 'vue';
const dialogValue = inject('dialogValue')

MyDialog绑定如下:

<el-dialog v-model="dialogValue.visible" title="用户录入">
	......
	<!-- 
	直接绑定dialogValue.name,变化会直接展示到上层组件,
	所以里面单独设置个name, email属性,提交适合再改dialogValue中值 
	-->
	<el-input v-model="name" autocomplete="off" />
	<el-input v-model="email" autocomplete="off" />
	.....
	<el-button @click="dialogValue.visible = false">取消</el-button>
	<el-button type="primary" @click="handleClick">确认</el-button>
</el-dialog>
<script setup>
import { inject, ref } from 'vue';
const dialogValue = inject('dialogValue')

// 不直接修改dialogValue.name等属性,确定时再提交
const name = ref('')
const email = ref('')

const handleClick = () => {
    dialogValue.value.visible = false
    dialogValue.value.name = name
    dialogValue.value.email = email
}
</scripte>

MyDialog使用如下:

<MyDialog v-model:visible="visible" v-model="dialogValue" />
<!-- 实际省略了默认modelValue, 等同于下 -->
<MyDialog v-model:visible="visible" v-model:modelValue="dialogValue" />

因此组件中需要定义两个prop和emit

const props = defineProps(['visible', 'modelValue'])
const emit = defineEmits(['update:visible', 'update:modelValue'])

emit触发由弹框点击了确认或者关闭按钮适合调用

	//	点击取消时候设置visible为false关闭
    emit('update:visible', false)
  //	点击取消时候设置visible为false关闭,并触发'update:modelValue' 返回结果,更新父组件的v-model值
    emit('update:visible', false)
    emit('update:modelValue', { name, email })

完整代码

MyDialog.vue

<template>
    <el-dialog v-model="dialogValue.visible" title="用户录入">
        <el-form>
            <el-form-item label="姓名">
                <el-input v-model="name" autocomplete="off" />
            </el-form-item>
            <el-form-item label="邮箱">
                <el-input v-model="email" autocomplete="off" />
            </el-form-item>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogValue.visible = false">取消</el-button>
                <el-button type="primary" @click="handleClick">确认</el-button>
            </span>
        </template>
    </el-dialog>
</template>

<script setup>
import { inject, ref } from 'vue';
const dialogValue = inject('dialogValue')

// 不直接修改dialogValue.name等属性,确定时再提交
const name = ref('')
const email = ref('')

const handleClick = () => {
    dialogValue.value.visible = false
    dialogValue.value.name = name
    dialogValue.value.email = email
}
</script>


App.vue

<template>
    <el-button type="primary" @click="handleClick">点击获取组件值</el-button>
    <MyDialog />
    <h1>弹窗结果是: {{ dialogValue }}</h1>
</template>

<script setup>
import { ref, provide } from "vue";
import MyDialog from "~/components/MyDialog.vue";

const dialogValue = ref({ name: '', email: '', visible: false })
provide('dialogValue', dialogValue)

const handleClick = () => {
    dialogValue.value.visible = true
}

</script>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值