Vue组件间传值,默认遵循单向下行绑定原则
prop传值的本质,是传递的引用。内外组件同一参数指向同一个内存区域,所以数据可以同步。
如果遇到在子组件内部需要更改prop传值,可以按照如下思路来巧妙处理:子组件sel-user代码如下:
<template>
<div class="sel-user">
<!--侧边栏导航-选择用户-->
<el-dialog :visible.sync="cVisible" :title="title" :close-on-click-modal="false" width="880px">
<el-row style="padding:10px 0; border-top:1px solid #eee;">
<el-col>
<el-button size="small" @click="cancel" class="fr marr15">取 消</el-button>
<el-button type="primary" size="small" @click="sure" class="fr marr10">确 定</el-button>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script>
export default {
name: "sel-user",
props: {
title: { type: String, required: false, default: "选择用户" },
visible: { type: Boolean, required: false, default: false }
},
data: function() {
return {
cVisible: this.visible
};
},
watch: {
visible(newVal) {
this.cVisible = newVal;
}
},
methods: {
sure: function(flag) {
this.cVisible = false;
this.$emit("on-selected", this.cData);
},
cancel: function(flag) {
this.cVisible = false;
}
}
};
</script>
可以看到,接受外部的两个prop参数,title
和visible
两个参数,title
是仅用于显示,visible
是需要修改用于切换dialog隐藏/显示。所有,需要给visible
参数创建一个内部副本cVisible
,实现和visible
解绑,支持修改。完美避开单向数据流。父组件中调用代码:
<template>
<div>
<sel-user ref="seluser" :visible="dialog.user" @on-selected="selUser"></sel-user>
<el-button type="success" class="fl" @click="openSelUser">添加用户</el-button>
</div>
</template>
<script>
import selUser from "@/views/components/sel-user";
export default {
name: "admin_module_public",
components: { selUser},
data() {
return {
dialog: {
user: false
}
}
},
methods: {
openSelUser: function() {
this.dialog.user = true;
}
}
}
</script>
实现效果:
点击添加用户按钮,改变
dialog.user=true
,传入sel-user组件
:visible="dialog.user"
参数,
sel-user
显示出来。但是发现当弹窗关闭后,再次点击父组件中的添加用户按钮,弹窗丝毫没有反应,控制台也没有报错。原因是在
sel-user
中
cVisible副本
实现对
visible
值的
watch
监听,但是外部
dialog.user
的值并没有改变,没有触发监听,所以内部
cVisible永远都等于false
;
解决思路有2种:
1、添加一个专用于触发监听的prop参数
2、在sel-user中创建一个
show
方法,用于直接修改cVisible参数
下面演示方案2实现方式
sel-user组件中methods代码,其他代码都不用动。
...
methods: {
show() {
this.cVisible = true;
},
sure: function(flag) {
this.cVisible = false;
this.$emit("on-selected", this.cData);
},
cancel: function(flag) {
this.cVisible = false;
}
}
...
父组件调用方式:
...
openSelUser: function() {
this.$refs.seluser.show();
},
...
这样,父组件中直接修改子组件中cVisible
的值,子组件中可以直接去掉prop -> visible
。
Vue官网提供的规避单项数据流的解决方案: 规避单向数据流