Vue实现自定义组件数据双向绑定
前言:使用Vue进行项目开发的时候,通常会用到Vue提供的组件化机制封装开发所需要的组件以达到开发项目的需求,大到项目中的一快筛选模块、数据表格,小到分页面板、级联面板、乃至一个小小的button按钮,之所以组件化也是为提高我们实际的开发效率,那到底什么是组件化呢?参考一张尤玉溪大大的图就会很快明白;简单来讲一个完整项目会分为很多部分,每个部分都会有各自独立的功能,每个独立的功能组件又是由...
前言:使用Vue进行项目开发的时候,通常会用到Vue提供的组件化机制封装开发所需要的组件以达到开发项目的需求,大到项目中的一快筛选模块、数据表格,小到分页面板、级联面板、乃至一个小小的button按钮,之所以组件化也是为提高我们实际的开发效率,那到底什么是组件化呢?参考一张尤玉溪大大的图就会很快明白;
简单来讲一个完整项目会分为很多部分,每个部分都会有各自独立的功能,每个独立的功能组件又是由很多小的组件构成,了解了什么是组件之后,就必须要明白组件之间的通讯方式。Vue官方为我们提供了子传父、父传子的方法以及属性,但是单纯使用这些是远远不能够满足我们的实际开发需求,因为很多时候我们需要父组件与子组件直接双向绑定数据,但是Vue中父子组件通信,都是单项的数据流,具体如下:
父组件:
<!-- 父组件 -->
<template>
<div class="Parent">
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<h2>Parent(父组件)</h2>
<el-button style="float: right; padding: 3px 0" type="text">查看详情</el-button>
</div>
<el-button type="primary" icon="el-icon-plus" circle @click.native="Add(off)"></el-button>
<Children :Data="off"></Children>
<el-col :span="12">
<span>来自子组件的数据:</span>
{{msg}}
</el-col>
</el-card>
</el-col>
</div>
</template>
子组件:
<!-- 子组件 -->
<template>
<div class="Children">
<el-dialog
width="30%"
top="15%"
title="Children(子组件)"
:visible.sync="off"
:before-close="handleClose"
modal-append-to-body="false"
append-to-body="false"
>
<el-input v-model="input" placeholder="请输入内容"></el-input>
<span slot="footer" class="dialog-footer">
<el-button @click="off = false">取 消</el-button>
<el-button type="primary" @click="off = false">提 交</el-button>
</span>
</el-dialog>
</div>
</template>
预览:
功能:父组件点击“+”按钮之后调用子组件,子组件提交数据、父组件蓝色部分显示子组件提交的数据;
思路:首先得明白子组件显示与否依赖于off,也就是点击"+"号之后,父组件必须改变子组件的off值(子组件数据),父组件data里必须也有个off值用于传递数据(父组件数据),从而达到父子组件数据双向绑定的需求;
接下来改造代码:
<!-- 父组件 -->
<template>
<div class="Parent">
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<h2>Parent(父组件)</h2>
<el-button style="float: right; padding: 3px 0" type="text">查看详情</el-button>
</div>
<el-button type="primary" icon="el-icon-plus" circle @click.native="Add()"></el-button>
<Children :Data="off" @GetData="GetData"></Children>
<el-col :span="12">
<span>来自子组件的数据:</span>
{{msg}}
</el-col>
</el-card>
</el-col>
</div>
</template>
<script>
import Children from "./Children"; //引入Children
export default {
components: {
Children
},
data() {
return {
msg: "暂无", //穿传递初始数据
off: false
};
},
methods: {
Add() {
this.off = true; //修改off 打开子组件
},
GetData(off,input) { //这里的off是接收子组件传递过来的值
this.off = off; //把子组件的数据同步到父组件中
this.msg = input; //同上
}
}
};
Parent解释:在父组件中引入子组件Children,使用v-bind绑定父组件的off传递给子组件,当点击“+”号之后执行Add方法改变off为true,使用自定义事件监听子组件事件是否触发,触发之后接收到来自子组件的数据并同步更新到父组件对应的状态;
<!-- 组件说明 -->
<template>
<div class="Children">
<el-dialog
width="30%"
top="15%"
title="Children(子组件)"
:visible.sync="off"
:modal-append-to-body="false"
:append-to-body="false"
>
<el-input v-model="input" placeholder="请输入内容"></el-input>
<span slot="footer" class="dialog-footer">
<el-button @click="Submit(0)">取 消</el-button>
<el-button type="primary" @click="Submit(1)">提 交</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
components: {},
data() {
return {
input: "",
off: this.Data //赋初始值 等价于off:false
};
},
props: ["Data"], //接收来自父组件的数据
watch: {
Data(N, O) {
this.off = N; //每次Props数据改变的时候同步更新到off
}
},
methods: {
Submit(key){
if(key){ //点击提交按钮
alert("提交!")
// if(....) //此处编写表单效验通过后的业务逻辑
this.off = false
}else if(!key){
alert("取消!") //点击取消按钮
this.off = false
}
this.$emit('GetData',this.off,this.input)
}
}
};
</script>
Children解释:props对象接收父组件数据,组件创建完毕之后第27行初始化来自父组件的数据(此处由于父组件中off值为false,所以第一次赋值也是false,注意这里只能赋初始值 后面的父组件传递的数据将不会改动,必须由watch监听变化再更新到data > off),取消/提交调用Submit方法,(38行kye==1 1隐式转换之后为true所以不用麻烦写if(key==1),42行同理),执行Submit之后改变off的值为false即关闭子组件,并且使用$emit创建自定义事件GetData (此处GetData必须与父组件中第11行绑定的方法一致才可以触发自定义事件),触发子组件的GetData事件并且同步更新到父组件中;
至此 结束,看一下效果!
更多推荐
所有评论(0)