父组件的data内容被子组件自动修改,请高人入内指点
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利
父级组件用了组件1,组件1引用了组件2,每当组件2给组件1返回值的时候,父组件里的lists被改变。
通过控制台打印如下图:
未改变的
被改变的
lists的被选中项中自动添加了组件2返回的token和avatar
下面是代码,请大神指点
父组件
<template>
<div>
<el-row :gutter="20">
<el-col class="title-box" :span="24">
<div class="title">
<i class="el-icon-s-unfold"></i>
账户设置 / 联系人
</div>
<div class="tip">这里是企业招聘联系人,你可以对其编辑、删除等操作。</div>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<div class="box table">
<div class="title-sen">负责人列表</div>
{{lists}}
<el-table border :data="lists" stripe style="width: 100%" v-loading="tableLoading">
<el-table-column fixed="left" prop="name" label="姓名" width="120"></el-table-column>
<el-table-column prop="phone" label="手机号" width="120"></el-table-column>
<el-table-column prop="desc" label="备注" width="200"></el-table-column>
<el-table-column fixed="right" label="操作" width="160">
<template slot-scope="scope">
<el-button @click="handleEdit(scope.row)" type="warning" size="mini" plain>编辑</el-button>
<el-button
@click="handleDel(scope.row.id,scope.row.name)"
type="danger"
size="mini"
plain
>作废</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-col>
<el-col :span="12">
<div class="box edit">
<div class="title-sen">编辑负责人</div>
<add-contact :pushData="pushData" @backValue="editSuccess"></add-contact>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import AddContact from "@/components/contact/add.vue";
export default {
name: "list",
components: {
AddContact
},
data() {
return {
tableLoading: true,
lists: [],
pushData: {
name: "",
phone: "",
desc: "",
id: ""
}
};
},
watch: {
pushData(e) {
console.log("父级pushData变化");
console.log(e);
console.log(this.lists);
},
lists(e) {
console.log("父级lists变化");
console.log(e);
}
},
created() {
this.getList();
},
methods: {
editSuccess() {
this.getList();
},
getList() {
this.tableLoading = true;
this.$api.information.getContact().then(res => {
this.tableLoading = false;
this.lists = res;
});
},
handleEdit(data) {
console.log(this.lists);
console.log("edit");
console.log(data);
this.pushData = data;
},
handleDel(id, name) {
console.log(id);
console.log(name);
}
},
computed: {}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.title-sen {
padding: 10px 20px 30px;
font-weight: 600;
}
</style>
子组件1
<template>
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="100px">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" placeholder="请输入姓名"></el-input>
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="form.phone" placeholder="请输入手机号"></el-input>
</el-form-item>
<el-form-item label="备注" prop="desc">
<el-input v-model="form.desc" placeholder="请输入"></el-input>
</el-form-item>
<el-form-item label="绑定微信" :error="wx_error">
<qr-code v-if="!hasScan" action="bind" :size="100" @backData="backQrCodeData"></qr-code>
<div v-else class="avatar" @click="handleChangeWx">
<div class="bg">换绑</div>
<el-avatar :size="90" :src="form.avatar"></el-avatar>
</div>
</el-form-item>
<el-form-item>
<el-button
v-if="form.id != '0' && form.id !== '' && form.id !== undefined"
type="warning"
plain
@click="submitForm('ruleForm')"
>提交修改</el-button>
<el-button v-else type="success" plain @click="submitForm('ruleForm')">确认新增</el-button>
<el-button @click="resetForm()" plain>清空</el-button>
</el-form-item>
</el-form>
</template>
<script>
import QrCode from "@/components/QrCode/index.vue";
export default {
name: "contact_add",
components: { QrCode },
props: {
pushData: Object
},
data() {
return {
form: this.pushData,
hasScan: false,
wx_error: "",
rules: {
name: [{ required: true, message: "请输入姓名", trigger: "blur" }],
phone: [
{ required: true, message: "请输入手机号", trigger: "blur" },
{ min: 11, max: 11, message: "请输入正确的手机号", trigger: "blur" }
]
}
};
},
watch: {
pushData(val) {
this.init(val);
},
form(e) {
console.log("子form变化");
console.log(e);
}
},
methods: {
init(val) {
console.log("子组件初始");
console.log(val);
this.resetForm();
this.form = val;
if (this.form.avatar != "" && this.form.avatar !== undefined) {
this.hasScan = true;
}
},
// 更换微信
handleChangeWx() {
this.hasScan = false;
this.form.token = "";
this.form.avatar = "";
},
// 扫描二维码返回的token
backQrCodeData(e) {
console.log("back token.");
this.hasScan = true;
this.form.token = e.token;
this.form.avatar = e.avatar;
},
// 提交表格
submitForm(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
if (
(this.form.avatar == "" || this.form.avatar == undefined) &&
!this.form.token
) {
this.wx_error = "请先绑定微信";
return false;
}
this.$api.information.editContact(this.form).then(res => {
this.$message.success("操作成功");
this.$emit("backValue", res.id);
this.resetForm();
});
} else {
return false;
}
});
},
// 重置
resetForm() {
console.log("重置");
this.hasScan = false;
this.form = {
id: "",
name: "",
phone: "",
desc: ""
};
}
}
};
</script>
<!-- 添加 scoped 使得style仅作用于本组件 -->
<style scoped>
.avatar {
width: 100px;
height: 100px;
border-radius: 50%;
overflow: hidden;
position: relative;
cursor: pointer;
}
.avatar .bg {
display: none;
content: "点击更换";
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 2;
background: rgba(0, 0, 0, 0.8);
text-align: center;
color: #ffffff;
line-height: 100px;
}
.avatar:hover .bg {
display: block;
}
</style>
子组件2
<template>
<div
class="qr-code"
v-loading="codeLoading"
v-bind:style="{width:size + 'px',height:size + 'px'}"
>
<div class="has-scan" v-if="hasScan && hasScanRes">
<p class="icon">
<i class="el-icon-success"></i>
</p>
</div>
<div class="has-scan error" v-if="hasScan && !hasScanRes" @click="handleReload">
<p class="icon">
<i class="el-icon-warning"></i>
</p>
<p>扫描失败,点击刷新</p>
</div>
<img class="code-img" :src="codeImg" />
</div>
</template>
<script>
export default {
name: "QrCode",
props: {
action: String, // 获取二维码事件:bind 绑定,login 登录
size: Number // 大小
},
data() {
return {
codeLoading: true,
hasScan: false,
hasScanRes: true,
codeImg:
"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQHl8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAySGRHX0ozcUVmXzMxcXNMNU51MVAAAgTcBkVeAwTAqAAA",
socket: "" // websocket
};
},
created() {
//this.init();
// 演示效果,生产环境删除
console.log("code created.");
setTimeout(() => {
var d = new Date();
console.log(d.getTime());
this.$emit("backData", {
token: "DwAAAA" + d.getTime(),
avatar:
"https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
});
}, 3000);
},
methods: {
handleReload() {
this.codeLoading = true;
this.open();
},
init: function() {
if (typeof WebSocket === "undefined") {
this.$alert(
"您的浏览器版本过低,无法使用此功能!建议升级后再试。",
"提示",
{
confirmButtonText: "知道了"
}
);
} else {
// 定义地址
const url = "wss://";
// 实例化socket
this.socket = new WebSocket(url);
// 监听socket连接
this.socket.onopen = this.open;
// 监听socket错误信息
this.socket.onerror = this.error;
// 监听socket消息
this.socket.onmessage = this.getMessage;
}
},
open: function() {
console.log("socket连接成功");
// 组合参数
let data = {
controller: "getCode",
action: this.action
};
// 连接成功后发送参数
this.send(data);
},
error: function() {
console.log("连接错误");
},
getMessage: function(msg) {
console.log(msg.data);
let res = JSON.parse(msg.data); // 根据实际情况修改
if (res.action == "backImg") {
this.codeLoading = false;
this.codeImg = res.img;
return false;
} else if (res.action == "hasScan") {
this.hasScan = true;
this.hasScanRes = res.scanRes;
return false;
} else if (res.action == "success") {
this.$emit("backCallback", res.data);
this.socket.close();
return false;
} else {
return false;
}
},
send: function(params) {
this.socket.send(JSON.stringify(params));
}
}
};
</script>
<!-- 添加 scoped 使得style仅作用于本组件 -->
<style scoped>
.qr-code {
display: inline-block;
width: 100px;
height: 100px;
position: relative;
padding: 5px;
border: 1px solid #e8e8e6;
}
.has-scan {
position: absolute;
top: 0;
left: 0;
z-index: 2;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.9);
color: #06c242;
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
}
.has-scan.error {
color: #f23009;
}
.has-scan p {
width: 100%;
margin: 0;
padding: 0;
text-align: center;
font-size: 12px;
}
.has-scan .icon {
font-size: 28px;
line-height: 1.2;
}
.code-img {
width: 100%;
height: 100%;
}
</style>