在上一篇中讲解了父子组件之间是如何传值的,如果子组件需要改变传过来的数据供自己使用,或者想在子组件中改变传过来的数据并同步到父组件,那么直接改肯定是不行的,如果你这么做了,Vue 会在控制台给出警告。

对应这两种情况,解决方式如下:

先创建项目并运行

vue init webpack-simple template
cd template
npm i
npm run dev

一、 子组件需要改变传过来的数据供自己使用
1. 定义一个局部变量,并用 props 的值来初始化它

在 App.vue 中

<template>
<div class="hello">
<h3>我是 App 父组件</h3>
<h4>访问自己的数据:{{msg}},{{name}},{{user.id}}</h4>
<hr>
<!-- 1. 在调用子组件时,绑定想要获取的父组件中的数据 -->
<Hello :message="msg"></Hello>
</div>
</template> <script>
// 引入 Hello 组件
import Hello from './assets/components/Hello.vue'
export default {
data(){
return {
msg:'父组件',
name:'tom',
age:'22',
user:{
id:1234,
userName:'Jack'
}
}
},
// 注册 Hello 组件
components:{
Hello
}
}
</script>

在 Hello.vue 中

<template>
<div class="hello">
<h3>我是 hello 子组件</h3>
<!-- 在页面中直接渲染即可 -->
<h4>访问父组件中的数据: {{msg}}</h4>
<button @click="change">改变父组件的数据</button>
</div>
</template> <script>
export default {
// 2. 在子组件内部,使用 props 选项声明获取的数据,即接收来自父组件中的数据
props:['message'],
data(){
return {
// 定义一个局部变量,并用 props 的值来初始化它
msg:this.message
}
},
methods:{
// 定义一个方法,来触发改变父组件的数据
change(){
this.msg = '我改变了父组件的数据'
}
}
}
</script>

效果图:

 
子组件改变父组件的数据
2. 定义一个计算属性,处理 prop 的值并返回:

在 Hello.vue 中改动

<script>
export default {
// 2. 在子组件内部,使用 props 选项声明获取的数据,即接收来自父组件中的数据
props:['message'],
data(){
return {
// 定义一个局部变量,并用 props 的值来初始化它
msg:this.message
}
},
computed:{
// 定义一个方法,来触发改变父组件的数据
change(){
return this.msg = '我改变了父组件的数据'
}
}
}
</script>

当页面渲染成功自动完成计算

 
 
二、子组件中改变传过来的数据并同步到父组件
1. 使用 sync 修饰符,它会被扩展为一个自动更新父组件属性的 v-on 监听器

在 App.vue 中把 template 的内容更改为

<template>
<div class="hello">
<h3>我是 App 父组件</h3>
<h4>访问自己的数据:{{msg}}</h4>
<hr>
<!-- 1. 在调用子组件时,绑定想要获取的父组件中的数据 -->
<!-- .sync 会被扩展为一个自动更新父组件属性的 v-on 监听器 -->
<Hello :message.sync="msg"></Hello>
</div>
</template>

在 Hello.vue 中更改为

<template>
<div class="hello">
<h3>我是 hello 子组件</h3>
<!-- 在页面中直接渲染即可 -->
<h4>访问父组件中的数据: {{message}}</h4>
<button @click="change">改变父组件的数据</button>
</div>
</template> <script>
export default {
// 2. 在子组件内部,使用 props 选项声明获取的数据,即接收来自父组件中的数据
props:['message'],
methods:{
change(){
// 使用 .sync 时,需要显式的触发一个更新事件
// update 为固定写法,后面跟将要被改变的数据对象,接着写替换的数据
this.$emit('update:message','我改变了父组件的数据')
}
}
}
</script>

效果为:

 
 
2. 可以将父组件中的数据包装成对象或数组,然后在子组件中修改对象的属性

在 App.vue 中

<template>
<div class="hello">
<h3>我是 App 父组件</h3>
<h4>访问自己的数据:{{user.userName}}</h4>
<hr>
<!-- 2. 在调用子组件时,绑定想要获取的父组件中的数据 -->
<Hello :user="user"></Hello>
</div>
</template> <script>
// 引入 Hello 组件
import Hello from './assets/components/Hello.vue'
export default {
data(){
return {
// 1. 在父组件中把数据写成对象的形式
user:{
id:1234,
userName:'Jack'
}
}
},
// 注册 Hello 组件
components:{
Hello
}
}
</script>

在 Hello.vue 中

<template>
<div class="hello">
<h3>我是 hello 子组件</h3>
<!-- 5. 在页面中直接渲染即可 -->
<h4>访问父组件中的数据: {{user.userName}}</h4>
<button @click="change">改变父组件的数据</button>
</div>
</template> <script>
export default {
// 3. 在子组件内部,使用 props 选项声明获取的数据,即接收来自父组件中的数据
props:['message','user'],
methods:{
// 4.直接修改 user 对象中的数据
change(){
this.user.userName = 'Tom'
}
}
}
</script>

效果如下:

 
 

我们是不允许直接修改父组件传过来的数据或对象的,而这种方法更改的是对象中的属性,因为对象是引用类型,指向同一内存空间,所以可以实现此效果。推荐使用该方式

NO17--vue父子组件间单向数据流的解决办法的更多相关文章

  1. vue组件定义方式,vue父子组件间的传值

    vue组件定义方式,vue父子组件间的传值 <!DOCTYPE html> <html lang="zh-cn"> <head> <met ...

  2. vue:父子组件间通信,父组件调用子组件方法进行校验子组件的表单

    参考: ElementUI多个子组件表单的校验管理:https://www.jianshu.com/p/541d8b18cf95 Vue 子组件调用父组件方法总结:https://juejin.im/ ...

  3. Vue 父子组件间的通信

    前言 在 Vue 项目中父子组件的通信是非常常见的,最近做项目的时候发现对这方面的知识还不怎么熟练,在这边做一下笔记,系统学习一下吧. 1 父组件传值给子组件 1.1 传值写法 父组件传值给子组件,这 ...

  4. vue -- 父子组件间的事件触发

    1.父组件触发子组件事件 Parent.vue <child ref="child"></child> <div @click="fn&qu ...

  5. Vue父子组件间的通信

    父组件通过 props 向下传递数据给子组件,子组件通过 events 向上给父组件发送消息. 父组件: <div> <div style="background:#344 ...

  6. vue——父子组件间传值

    (1)父组件给子组件传值(商品详情页): 根据订单类型,判断显示立即购买/立即拼单: 通过props来传递参数 父组件(商品详情页) 父组件调用子组件,在子组件的标签中,通过:数据名称=”数据”的形式 ...

  7. Vue中组件间通信的方式

    Vue中组件间通信的方式 Vue中组件间通信包括父子组件.兄弟组件.隔代组件之间通信. props $emit 这种组件通信的方式是我们运用的非常多的一种,props以单向数据流的形式可以很好的完成父 ...

  8. vue第九单元(非父子通信 events 单向数据流)

    第九单元(非父子通信 events 单向数据流) #课程目标 了解非父子组件通信的原理,熟练实现非父子组件间的通信(重点) 了解单向数据流的含义,并且明白单向数据流的好处 #知识点 #1.非父子组件间 ...

  9. vue之父子组件间通信实例讲解(props、$ref、$emit)

       组件间如何通信,也就成为了vue中重点知识了.这篇文章将会通过props.$ref和 $emit 这几个知识点,来讲解如何实现父子组件间通信. 组件是 vue.js 最强大的功能之一,而组件实例 ...

随机推荐

  1. redis开启远程连接访问和需要密码的方法

    redis默认是不能远程访问的,如果希望多台机子共用redis数据库,那就需要开启redis远程连接访问.既然可以远程连接了,那就需要密码登陆,否则不安全.下面是具体的方法,按照步骤一步一步来就OK了 ...

  2. koa2怎么自定义一个中间件

    首先定义一个方法 function test(ctx){ global.console.log('m1') } 把这个中间件导出去 module.exports=function(){ return ...

  3. 【转】numpy中 meshgrid 和 mgrid 的区别和使用

    转自:https://www.cnblogs.com/shenxiaolin/p/8854197.html 一.meshgrid函数 meshgrid函数通常使用在数据的矢量化上. 它适用于生成网格型 ...

  4. new的三种形态

    C++语言一直被认为是复杂编程语言中的杰出代表之一,不仅仅是因为其繁缛的语法规则,还因为其晦涩的术语.下面要讲的就是你的老熟人—new: 它是一个内存管理的操作符,能够从堆中划分一块区域,自动调用构造 ...

  5. 关于ESP8266EX的一些资料

    乐鑫智能互联平台 ESP8266EX 拥有高性能无线 SOC,给移动平台设计师带来福⾳音,它以最低成本提供最大实用性,为 WiFi 功能嵌入其他系统提供无限可能. ESP8266EX 是⼀一个完整且⾃ ...

  6. nagios-4.0.8 安装部署

    1.Nagios工作原理 Nagios周期性调用插件检测服务器状态,并维持一个队列,所有插件返回状态信息都进入队列,Nagios每次从队首开始读取信息,并把状态通过web显示. 安装完成后,在nagi ...

  7. 通过ReentrantLock简单了解下并发包中的锁

    ReentrantLock在进行实例化时,可以通过构造函数的参数选择是否使用公平锁FairSync或者非公平锁NonfairSync,两者的区别比较简单,如果是公平锁则新来的线程会先检测同步队列中是否 ...

  8. Manifest XML signature is not valid(安装ClickOnce签名未通过验证)

    转载:http://stackoverflow.com/questions/12826798/manifest-xml-signature-is-not-valid 安装时,我的问题:  PLATFO ...

  9. Oracle透明网关访问SQLServer数据库

    针对oracle数据库不同实例之间的数据访问,我们可以直接通过dblink访问,如果oracle数据库想访问mysql/sqlserver等数据库的数据,我们可以通过配置oracle透明网关实现异构数 ...

  10. Hadoop(18)-MapReduce框架原理-WritableComparable排序和GroupingComparator分组

    1.排序概述 2.排序分类 3.WritableComparable案例 这个文件,是大数据-Hadoop生态(12)-Hadoop序列化和源码追踪的输出文件,可以看到,文件根据key,也就是手机号进 ...