vue3父子组件交互问题,哪种写法更优,为什么?
描述:在父组件引入子组件,子组件是一个弹窗,两种方式都可实现,哪种写法更好,为什么?方式1是在父组件定义控制子组件是否打开的参数以及传递的参数,在子组件进行监听赋值方式2是用ref操作子组件方法
方式一:
父组件
<template>
<el-button
text
type="warning"
icon="CircleCheck"
@click="handleSetRole(scope.row)"
>分配角色</el-button>
<AssigningRoles
:is-open="isOpen"
:params-data="paramsData"
@get-role-result="getRoleResult">
</AssigningRoles>
</template>
<script setup>
const isOpen = ref(false) // 控制子组件是否显示
const paramsData = ref({}) // 其他数据传递
// 方法
const handleSetRole = () => {
isOpen.value = true
paramsData.value = {
account: row.account,
nickname: row.nickname
}
}
分配角色回调
const getRoleResult = (flag) => {
isOpen.value = false
flag && getList()
}
</script>
子组件
<template>
<el-dialog
title="分配角色"
v-model="isOpen"
width="500px"
append-to-body
:close-on-click-modal="false"
@close="cancel">
<el-form>
<el-input v-model="form.account"></el-input>
....
</el-form>
<template #footer>
<el-button text @click="cancel">取消</el-button>
<el-button type="primary" @click="submitForm">确定</el-button>
</template>
</el-dialog>
</template>
<script setup>
const { proxy } = getCurrentInstance()
const form = reactive({
account: '',
nickname: '',
role: []
})
// props
const props = defineProps({
isOpen: {
type: Boolean,
default: false
},
paramsData: {
type: Object,
default: () => ({})
}
})
const { isOpen } = toRefs(props)
// watch监听
watch(
() => props.paramsData,
(newVal, oldVal) => {
form.account = newVal.account
form.nickname = newVal.nickname
form.role = []
},
{ immediate: true, deep: true }
)
// 子组件传父组件emit
const emit = defineEmits(['get-role-result'])
// 取消
const cancel = () => {
emit('get-role-result', false)
}
// 提交
const submitForm = () => {
assignUserRole(form.value).then((res) => {
proxy.$modal.msgSuccess('分配成功')
emit('get-role-result', true)
})
}
</script>
方式二:
父组件
<template>
<el-button
text
type="warning"
icon="CircleCheck"
@click="handleSetRole(scope.row)"
>分配角色</el-button>
<AssigningRoles
ref="editFormRef"
@getEditResult="editEvent">
</AssigningRoles>
</template>
<script setup>
const editFormRef = ref(null)
// 分配角色
function handleSetRole(row) {
proxy.$refs.editFormRef.openEditForm(row)
}
// 分配角色回调
function editEvent() {
getList()
}
</script>
子组件
<template>
<el-dialog
title="分配角色"
v-model="editVisible.visible"
width="500px"
append-to-body
:close-on-click-modal="false"
@close="cancel">
<el-form>
<el-input v-model="form.account"></el-input>
....
</el-form>
<template #footer>
<el-button text @click="cancel">取消</el-button>
<el-button type="primary" @click="submitForm">确定</el-button>
</template>
</el-dialog>
</template>
<script setup>
const { proxy } = getCurrentInstance()
// 定义form表单数据
const form = reactive({
account: '',
nickname: '',
role: []
})
// 编辑窗口参数
const editVisible = reactive({
visible: false // 窗口开关
})
const emit = defineEmits(['getEditResult'])
const openEditForm = (data) => {
form.account = data.account
form.nickname = data.nickname
form.role = []
editVisible.visible = true
}
// 取消
const cancel = () => {
editVisible.visible = false
}
// 提交
const submitForm = () => {
assignUserRole(form.value).then((res) => {
proxy.$modal.msgSuccess('分配成功')
editVisible.visible = false
emit('getEditResult')
})
}
defineExpose({ openEditForm })
</script>
回复
1个回答
test
2024-06-28
一种是状态控制(响应式),一种是直接控制(命令式)
对于 Vue 来说,推荐使用响应式(本来 Vue 设计就是数据触发呈现变化的)
但是有些组件确实控制性要求较强,需要主动控制的,使用 ref 处理会方便一些。不过不建议使用 ref 来直接修改数据。
回复
适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容