【vue】组件通信:用prop交流

组件之间实现通信的方式主要有三种,这里记录的是使用props进行通信的方式。这种通信方式适合用于父子组件之间的通信。有时候需要在一个组件内需要引入另一个组件,我这里说的是这种情况,具体的可以看代码(网上有很多父子组件的说法,我也没理解 ╮(╯▽╰)╭ )。

父组件向子组件传递数据,是单向的,也就是,父组件传递给子组件的数据(变量),子组件不能原路修改,不能在自己的领域内修改父组件的数据(变量)。

如果父组件传递给组件的数据放在变量 name 中, 子组件不能向修改自己页面 data() 中定义的变量那样,直接修改 name (可以显示数据)。那么如果想要修改父组件传过来的数据,有哪些方式呢。

自然,通过props通信,还是有两种方式可以进行修改:

  • 把父组件的数据拷贝一份到自己的领域中,然后进行其他操作。这种方式不会影响父组件中的数据。
  • 就是要改父组件的数据。这种方式自然会影响父组件中的数据。

1. 修改子组件的变量

这种方式,类似于父组件给子组件一份文件,子组件拿着文件的备份,随意的进行操作。

父组件传递给子组件一个变量 name ,子组件将变量 name , 赋值给自己的变量 localName 。拿到父组件给的值后,子组件通过操作 localName 在页面上进行显示、修改等操作。

这种方式,对 localName 的修改不会影响父组件传递给子组件的变量 name ,在父组件页面中变量不会受子组件中值的改变而受到影响。

这种方式的核心代码是下面一行代码:

localName: this.name

在子组件中将父组件给的数据 name 赋值给子组件自己的变量 localName

1.1 父组件

下面的测试代码,在父组件 Father 中引入了子组件 Child1。父组件 Father 向子组件 Child1 传递的数据放在变量 childName 中,父组件 Father 和子组件 Child1 通信的桥梁是 name,子组件 Child1props 中接收的也是 name , 而不是放数据的变量 childName

父组件的代码如下:

<template>
    <div class="father-container">
        <h1>这是父组件页面</h1>
        <el-divider/>
        <child1 :name="childName"/>
    </div>
</template>

<script>
    import Child1 from "./Child1";

    export default {
        name: "Father",
        components: {
            Child1
        },
        data() {
            return {
                // 父组件要传递给子组件的变量
                childName: '父组件传递给子组件1的值',
            }
        },
        watch: {
            // 监控变量 childName 的改变
            childName: function () {
               console.log('childName:', this.childName)
            }
        }
    }
</script>

<style scoped>
    .father-container h1 {
        text-align: center;
    }
</style>

1.2 子组件

子组件通过 props 接收父组件给的数据, 接收的变量是 name , 而不是放数据的变量 childName 。拿到数据之后会把 name 中的数据赋值到子组件中的变量 localName

子组件的测试代码如下:

<template>
    <div class="child-container">
        <h2>子组件: 修改子组件中的变量</h2>
        <p>这种方式,修改子组件中变量的值,父组件传递给子组件的变量 name 的值不会改变</p>
     	<p>name: {{name}}</p>
        <p>localName: {{localName}}</p>
        <el-button type="primary" @click="handleButtonClick">点击改变子组件名称(只能改变一次)</el-button>
    </div>
</template>

<script>
    export default {
        name: "Child1",
        props: {
            name: String
        },
        data() {
            return {
                // 将父组件传递到子组件中的值赋给子组件中的变量
                localName: this.name
            }
        },
        methods: {
            // 点击按钮后,修改子组件中的变量,而不是修改父组件传递过来的 name 变量
            handleButtonClick() {
                this.localName = '修改之后的名称';
            },
        }
    }
</script>

1.3 查看父组件中变量是否变化

在上面父组件的代码中,包含了对变量的监控。相关代码如下:

watch: {
    childName: function () {
        console.log('childName:', this.childName)
    },
}

父组件监控了变量 childName 的值,一旦 childName 的值变化,会在浏览器终端输出提示信息。运行程序后,打开浏览器终端,可以看到没有任何输出。这是因为 watch 中监控的变量,只有改变了才会触发 watch

2. 修改父组件的变量

这种方式,类似于父组件给子组件一份文件,子组件拿着文件的原件进行操作,子组件的操作会影响到父组件。

在上面代码的基础之上,增加子组件2的测试。这种方式的重点是下面两行代码

<child2 :name.sync="childName2"/>

父组件传递给子组件的变量后加上 .sync

 this.$emit('update:name', '【子组件2】修改之后的值')

子组件通过 this.$emit('update:[变量名]', [变量值]) 将改变后的值传递给父组件

2.1 父组件

下面的测试代码,在父组件 Father 中引入了子组件 Child2。父组件 Father 向子组件 Child2 传递的数据放在变量 childName2 中,父组件 Father 和子组件 Child2 通信的桥梁是 name,子组件 Child2在 props 中接收的也是 name , 而不是放数据的变量 childName2 。这里多的一点就是 :name 变成了 :name.sync

<template>
    <div class="father-container">
        <h1>这是父组件页面</h1>
        <el-divider/>
        <child2 :name.sync="childName2"/>
    </div>
</template>

<script>
    import Child2 from "./Child2";

    export default {
        name: "Father",
        components: {
            Child2
        },
        data() {
            return {
                childName2: '父组件传递给子组件2的值'
            }
        },
        watch: {
            childName2: function () {
                console.log('childName2:',this.childName2)
            }
        }
    }
</script>

同样在父组件中监控变量 childName2 的变化。

2.2 子组件

子组件通过 props 接收父组件给的数据, 接收的变量是 name , 而不是放数据的变量 childName2 。点击按钮后,子组件会向父组件发送一个以 update: 开头的事件,并将修改之后的数据一块发送过去。父组件会自动修改它 name 所绑定的变量 childName2childName2 改变之后,子组件收到的值也会相应的改变。

子组件的测试代码如下:

<template>
    <div class="child-container">
        <h2>子组件2:修改父组件中的变量 </h2>
        <p>这种方式,修改父组件中变量 name 的值,子组件的值也会相应的改变</p>
        <p>name: {{name}}</p>
        <el-button type="primary" @click="handleButtonClick">点击改变子组件名称(只能改变一次)</el-button>
    </div>
</template>

<script>
    export default {
        name: "Child2",
        props: {
            name: String
        },
        methods: {
            // 修改父组件中传递给子组件的变量的值,修改父组件中的值后,组件中的值也会相应的改变
            handleButtonClick() {
                // 修改父组件中的变量
                this.$emit('update:name', '【子组件2】修改之后的值')
            },
        }
    }
</script>

2.3 查看父组件中变量是否变化

在上面父组件的代码中,包含了对变量的监控。相关代码如下:

watch: {    
	childName2: function () {        
		console.log('childName2:', this.childName2)    
	}
}

父组件监控了变量 childName2 的值,一旦 childName2 的值变化,会在浏览器终端输出提示信息。运行程序后,打开浏览器终端,可以看到 childName2 的值改变了。

完整的代码地址:

https://github.com/witheredwood/vue-study

下载项目后在项目终端中输入命令:npm run serve 启动项目

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值