vue2&vue3:封装子组件el-dialog弹框
使用.sync修饰符:实现子组件同步改变父组件通过props对应绑定的父组件变量值。修饰符在vue3中已废弃,需改用用法。
·
一、Vue2实现:
使用.sync修饰符:实现子组件同步改变父组件通过props对应绑定的父组件变量值。
<!-- 父组件:使用封装的el-dialog子组件 -->
<add-or-edit-dep-dialog v-if="showAddOrEditDialog" :show.sync="showAddOrEditDialog" :title="title" @update="updateList"/>
<script lang="ts">
@Component({
name: 'FatherComponent',
components: {
AddOrEditDepDialog: () => import(/* webpackChunkName: 'add-or-edit-dep-dialog' */ './components/add-or-edit-dep-dialog.vue'),
}
})
...
private showAddOrEditDialog = false
</script>
<!-- 子组件:使用了el-dialog组件 -->
<template>
<div class="add-or-edit-detail-container">
<!--:before-close="closeDg",用于解决第一次点击可以弹框,第2次点击弹框不出现的bug -->
<el-dialog :title="title" :visible.sync="visible" width="65%" top="5vh" :destroy-on-close="true" :close-on-click-modal="false" :show-close="!loading" :before-close="closeDg">
<div class="add-box my-custom-form" v-loading="loading">
<el-form ref="form" :model="form" label-width="28%" size="small" :rules="formRules">
...
</el-form>
<el-divider/>
<el-row type="flex" justify="center">
<el-button @click="closeDg" class="mr-10">取消</el-button>
<el-button type="primary" @click="submit('form')">确定</el-button>
</el-row>
</div>
</el-dialog>
</div>
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator'
@Component({
name: 'AddOrEditDepDg'
})
export default class extends Vue {
@Prop({ default: false }) private show!: boolean
private visible = false
... // 省略代码
@Watch('show', { immediate: true })
private setShow(val: boolean) {
this.visible = val
}
private closeDg() {
this.$emit('update:show', false)
}
}
</script>
二、Vue3实现:
xxx.sync 修饰符在vue3中已废弃,需改用 v-model: xxx 用法。
setup语法糖实现:
<!-- 父组件 -->
<use-child-dialog v-model:show="showChild" />
<script setup lang="ts">
import { ref } from "vue";
let showChild = ref(false)
</script>
<!-- 子组件 -->
<script lang="ts" setup>
const emit = defineEmits(["update:show"]);
const close = () => {
emit('update:show', false) // 自动修改父组件的变量值为false
}
</script>
非setup语法糖实现:
<!-- 父组件 -->
<template>
<div class="parent_wrapper">
<ProjectNameEdit v-model:show="showAddOrEdit" :title="dialogTitle" @update-show="updateShow"/>
</div>
</template>
<script>
import { defineComponent, reactive, toRefs, onMounted } from 'vue'
import ProjectNameEdit from './components/project-name-edit.vue'
export default defineComponent({
components: {
ProjectNameEdit
},
setup() {
const state = reactive({
dialogTitle: '',
showAddOrEdit: false
}),
... // 省略代码
const updateShow = (payLoad) => {
state.showAddOrEdit = payLoad // 子组件传给父组件的值
}
return {
...toRefs(state),
updateShow
}
}
})
</script>
<!-- 子组件 -->
<template>
<el-dialog v-model="visible" :title="title" :before-close="closeDg">
<el-form :model="form" label-width="120px">
....
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button @click="closeDg">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
</template>
<script>
import { defineComponent, reactive, toRefs, onMounted, watch } from 'vue'
export default defineComponent({
props: {
show: Boolean
},
emits: ['update-show'], // 定义声明emit触发的事件名
setup(props, { emit }) {
const state = reactive({
form: {},
visible: false
})
// 监听props对象的show属性
watch(() => props.show, (newVal) => {
state.visible = newVal
}, { immediate: true })
const closeDg = () => {
state.visible = false
emit('update-show', false) // 触发父事件,并传布尔值false
}
... // 省略代码
return {
...toRefs(state),
closeDg
}
},
})
</script>
更多推荐
已为社区贡献16条内容
所有评论(0)