在vue3中自定义组件双向绑定语法的改变,使得写法和vue2大为不同。我们以element-plus的dialog组件为例。基于它。封装一个自己的对话框,同时介绍两种实现思路:
思路一:数据驱动型:
我们封装一个test-dialog组件:
<el-button @click="open">打开</el-button>
<test-dialog ref="testDom" v-model:visible="flag" ></test-dialog>
import TestDialog from "@/components/Dialogs/TestDialog"
import { reactive, toRefs, ref, onMounted, watch } from "vue"
setup() {undefined
const state = reactive({
flag: false
})
const open = () => {
state.flag = true
}
watch(() => state.flag, (val) => {
console.log("父组件监听flag:", val)
})
}
子组件(弹窗组件):
<template>
<el-dialog
title="提示"
v-model="dialogVisble"
width="30%"
:before-close="close"
>
<span>这是一段信息</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="close">取 消</el-button>
<el-button
type="primary"
@click="close"
>确 定</el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import { ref, watch } from "vue"
export default {undefined
name: "TestDialog",
components: {},
props: {undefined
visible: {
type: Boolean,
default: false
}
},
setup(props, ctx) {
const dialogVisble = ref(false)
const close = () => {undefined
ctx.emit("update:visible", false)
}
watch(() => dialogVisble.value, (val) => {
ctx.emit("update:visible", val)
})
watch(() => props.visible, (val) => {
dialogVisble.value = val
})
return {
dialogVisble,
open,
close
};
},
};
</script>
<style scoped>
</style>
``
第二种思路:
类似直接操作dom,我们先通过ref拿到test-dialog组件的引用,每次点击打开按钮时,直接通过子组件去操作他内部的变量让它显示和隐藏
父页面:
<el-button @click="openByParentMethod ">打开</el-button>
<test-dialog ref="testDom" v-model:visible="flag" ></test-dialog>
import TestDialog from "@/components/Dialogs/TestDialog"
setup() {
const testDom = ref(null)
const openByParentMethod = () => {
testDom.value.dialogVisble = true
}
const closeByParentMethod= () => {
testDom.value.dialogVisble = false
}
return {
testDom,
openByParentMethod,
closeByParentMethod,
}
}
<template>
<el-dialog
title="提示"
v-model="dialogVisble"
width="30%"
:before-close="close"
>
<span>这是一段信息</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="close">取 消</el-button>
<el-button
type="primary"
@click="close"
>确 定</el-button>
</span>
</template>
</el-dialog>
</template>
setup(props, ctx) {
const dialogVisble = ref(false)
const open = () => {
dialogVisble.value = true
}
const close = () => {
dialogVisble.value = false
}
return {
dialogVisble,
open,
close
};
},