每次写父组件到子组件传值和双向数据绑定都会忘,记下……
单项数据流Vue.js介绍
父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。
这意味着你不应该在一个子组件内部改变 prop
。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
注意在 JavaScript 中
对象和数组
是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。
computed
和$emit()
父组件:
<template>
<div class="">
<a-button type="primary" @click="openChild">打开和关闭弹窗a-button>
<Son :isVisible="isShowSon" @close="closeDialog" :title="title" @changeTitle="change">Son>
div>
template>
<script>
// 引入子组件
import Son from "@/views/components/Son";
export default {
name: "Parent",
components: {Son},
data() {
return {
isShowSon: false, //是否显示子组件
title:''
};
},
methods: {
// 打开弹窗,并向子组件传递title值
openChild() {
this.isShowSon = true;
this.title='你笑起来真好看'
},
// 打开或关闭弹窗
closeDialog(val) {
this.isShowSon = val;
},
// 改变title
change(val){
this.title=val
}
},
};
script>
子组件:
使用computed
接收父组件的值,并使用$emit
方法向父组件传值。
<template>
<div class="main" >
<a-modal v-model="visible" title="新增表单" @ok="handleOk" @cancel="handleCancel">
子组件接收的值为: <a-tag color="orange" @click="changeTitle">{{title}}a-tag>
a-modal>
div>
template>
<script>
export default {
name: "Son",
props:{
//父组件传递的值,要改变的
isVisible:{
type:Boolean,
default:false
},
//常规数据
title:{
type:String,
default:''
}
},
computed: {
/* visible用来接收和改变父组件的值:isVisible */
visible:{
get(){
if(this.isVisible){this.init()}//打开弹窗的时候直接去初始化,不知道写在哪里了啊
return this.isVisible //接收父组件传递的值
},
set(val){
// 使用$emit方法去改变父组件传递的isVisible值,父组件使用close方法接收,val是当前传递的值
this.$emit('close',val)
}
}
},
methods: {
handleOk(e) {
// 不能直接修改父组件中的值,父->子:单向数据流 this.isVisible = false;会有警告
this.visible=false
},
handleCancel(e) {
this.visible=false
},
init(){
console.log('可以做初始化数据了----');
},
changeTitle(){
this.$emit('changeTitle','哦,不想写了啊啊啊')
}
},
};
script>
sync
修饰参数,子组件中使用this.$emit('update:isVisible',val)
向父组件传值。父组件
<template>
<div class="">
<a-button type="primary" @click="openChild">打开和关闭弹窗a-button>
<Son :isVisible.sync="isShowSon" :title.sync="title">Son>
div>
template>
<script>
// 引入子组件
import Son from "@/views/components/Son";
export default {
name: "Parent",
components: {Son},
data() {
return {
isShowSon: false, //是否显示子组件
title:''
};
},
methods: {
openChild() {
this.isShowSon = true;
this.title='你笑起来真好看啊'
},
},
};
script>
子组件
:在computed
中同步更新父组件中isVisible
值
<template>
<div class="" >
<a-modal v-model="visible" title="新增表单" @ok="handleOk" @cancel="handleCancel">
子组件接收的值为: <a-tag color="orange" @click="changeTitle">{{title}}a-tag>
a-modal>
div>
template>
<script>
export default {
name: "Son",
props:{
isVisible:{
type:Boolean,
default:false
},
title:{
type:String,
default:''
}
},
computed: {
visible:{
get(){
if(this.isVisible){this.init()}
return this.isVisible
},
set(val){
//更新父组件中的isVisible
this.$emit('update:isVisible',val)
}
}
},
methods: {
handleOk(e) {
this.visible=false
},
handleCancel(e) {
this.visible=false
},
init(){
console.log('可以做初始化数据了----');
},
changeTitle(){
this.$emit('update:title','哦,不想写了啊啊啊')
}
},
};
script>
refs
,可以直接修改子组件中的属性方法。子组件就像正常组件那样写就行了。父组件
<template>
<div class="">
<a-button type="primary" @click="openChild">打开和关闭弹窗a-button>
<Son ref="son">Son>
div>
template>
<script>
// 引入子组件
import Son from "@/views/components/Son";
export default {
name: "Parent",
components: {Son},
methods: {
// 打开弹窗,$refs可以直接操作子组件中值和方法等
openChild() {
this.$refs.son.visible=true
this.$refs.son.title='你笑起来真好看'
this.$refs.son.init(1234) //调用子组件中的方法
},
},
};
script>
子组件
<template>
<div class="">
<a-modal v-model="visible" title="新增表单" @ok="handleOk" @cancel="handleCancel">
子组件接收的title为: <a-tag color="orange">{{title}}a-tag>
a-modal>
div>
template>
<script>
export default {
name: "Son",
data(){
return{
title:'',
visible:false
}
},
methods: {
handleOk(e) {
this.visible=false
},
handleCancel(e) {
this.visible=false
},
// 初始化数据一般情况
init(id){
console.log('拿到了ID可以请求其他数据了',id);
}
},
};
script>