Vue组件之单向数据流的解决方法


Posted in Javascript onNovember 10, 2018

子组件能够通过自身的props选项获取父组件上的数据,但是在默认情况下,props是单向绑定的---当父组件数据(属性)发生变化的时候会传递给子组件,引起子组件的变化,但不能反过来并且不允许子组件直接改变父组件的数据,会报错的。例如:

也就是说当通过一种方法改变父组件数据的时候,子组件与之相关联的props数据也会发生改变,从而影响子组件,但是子组件直接改变从父组件拿过来的props数据却不能影响父组件的原始数据。也就是说一般情况下只能是“父影响子,而不是子影响父”。

两种情况:

1.如果子组件想将从父组件获得的数据作为局部数据来使用,可以将其给保存到子组件的局部变量data中(子组件中的变量),不影响父组件的数据;例如:

data:function(){
                return {
                  weather:{
                    tempre:"22.3℃",
                    weth:"rain",
                    wind:this.ser
                  }
                }
              },

这里的this.sers就是来源于子组件的props数据。

2.如果子组件想修改数据并且同步更新到父组件,两种解决方式

第一种:使用.sync加上显式触发的一个事件this.$emit("update:你要更改的props数据", 改变后的值),也就是在一个事件触发的函数中通过this.$emit("update:你要更改的props数据", 改变后的值)来改变数据;例如:

HTML部分

<div id= "container" v-cloak>
    <my-compon></my-compon>
  </div>
  <!-- 父组件模板 -->
  <template id="myComp">
    <div>
      <h3>大家好,我是{{animal.name}}猫,我已经和Jerry斗争了{{animal.age}}年了</h3>
 给绑定的数据使用.sync修饰符
      <my-comp-son v-bind:animalage.sync="animal.age"></my-comp-son>
    </div>
  </template>
  <!-- 子组件模板 -->
  <template id="myCompSon">
    <div>
      <h4>一只皮毛是{{dog.hair}}色,身高是{{dog.height}}的狗狗,在散步。。。</h4>
      <h3>今天的天气:{{weather.weth}},风力{{weather.wind}},温度{{weather.tempre}},{{animalname}},{{animalage}}</h3>
      <button @click = "changeFatDaAge">点击父组件中的数据会跟着改变方式一</button> 
    </div> 
  </template>

JS部分

var app = new Vue({
      el:"#container",
      data:{
        house:{
          date:"2017-10-10",
          area:"144m²",
          floor:6,
        },
        carBrand:"Benzi"
      },
      components:{
        "my-compon":{//父组件
          template:"#myComp",
          data:function(){
            return {
              animal:{
                name:"Tom",
                age:3,
                skin:"black"
              },
              shoe:"鸿星尔克",
              dog:{
                hair:"brown",
                height:1.25
              }
            }
          },
          methods: {
            changeData:function () {//这里的this指的是当前父组件的实例
              this.animal.name = "Kitty"//改变父组件中的数据
            }
          },
          components:{
            "my-comp-son":{//子组件
              template:"#myCompSon",
              props:["animalname","animalage","dog"],//地位和data一样,获取方式也是一样
              data:function(){
                return {
                  weather:{
                    tempre:"22.3℃",
                    weth:"rain",
                    wind:"3级"
                  }
                }
              },
              methods:{
                // 给v-bind使用修饰符.sync,需要显式地触发一个更新事件(this.$emit("update:你要更改的props数据", 改变后的值))
                changeFatDaAge:function(){
                  // this.animalage = 19;
                  this.$emit("update:animalage", 19)//通过这个方法来改变子组件props数据,并引起父组件相应数据的改变
                }
              }
            }
          }
        }
      }
    })

当点击按钮的时候父组件上的原始数据也会发生改变,不过这种方式不常用,写法也太麻烦,不建议使用;

第二种:将父组件的数据包装成对象并绑定到子组件上,在子组件中修改对象的属性(其实并没有真正改变该对象,因为对象是引用类型的数据,虽然属性发生了变化,但指针并没有发生变化),常用。例如:

HTML部分:

<div id= "container" v-cloak>
    <my-compon></my-compon>
  </div>
  <!-- 父组件模板 -->
  <template id="myComp">
    <div>
      <h4>一只皮毛是{{dog.hair}}色,身高是{{dog.height}}的狗狗,在散步。。。</h4>
      <!-- 将父组件的数据包装成对象并绑定到子组件上,在子组件中修改对象的属性,在这是dog -->
      <my-comp-son :dog = "dog"></my-comp-son>
    </div>
  </template>
  <!-- 子组件模板 -->
  <template id="myCompSon">
    <div>
      <h4>一只皮毛是{{dog.hair}}色,身高是{{dog.height}}的狗狗,在散步。。。</h4>
      <button @click="changeFondata">点击父组件中的数据会跟着改变方式二</button>
    </div> 
  </template>

JS部分

var app = new Vue({
      el:"#container",
      data:{
        house:{
          date:"2017-10-10",
          area:"144m²",
          floor:6,
        },
        carBrand:"Benzi"
      },
      components:{
        "my-compon":{//父组件
          template:"#myComp",
          data:function(){
            return {
              animal:{
                name:"Tom",
                age:3,
                skin:"black"
              },
              shoe:"鸿星尔克",
              dog:{
                hair:"brown",
                height:1.25
              }
            }
          },
          methods: {
            changeData:function () {//这里的this指的是当前父组件的实例
              this.animal.name = "Kitty"//改变父组件中的数据
            }
          },
          components:{
            "my-comp-son":{//子组件
              template:"#myCompSon",
              props:["animalname","animalage","dog"],//地位和data一样,获取方式也是一样
              data:function(){
                return {
                  weather:{
                    tempre:"22.3℃",
                    weth:"rain",
                    wind:"3级"
                  }
                }
              },
              methods:{
                //在子组件中修改对象的属性
                changeFondata:function(){
                  this.dog.hair = "红"
                }
              }
            }
          }
        }
      }
    })

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
慎用 somefunction.prototype 分析
Jun 02 Javascript
Jquery Autocomplete 结合asp.net使用要点
Oct 29 Javascript
js设置控件的隐藏与显示的两种方法
Aug 21 Javascript
6种javascript显示当前系统时间代码
Dec 01 Javascript
BootStrap初学者对弹出框和进度条的使用感觉
Jun 27 Javascript
jQuery编写网页版2048小游戏
Jan 06 Javascript
js实现自动轮换选项卡
Jan 13 Javascript
ES6(ECMAScript 6)新特性之模板字符串用法分析
Apr 01 Javascript
jQuery菜单实例(全选,反选,取消)
Aug 28 jQuery
详解VSCode配置启动Vue项目
May 14 Javascript
Moment.js实现多个同时倒计时
Aug 26 Javascript
详细分析Node.js 模块系统
Jun 28 Javascript
详解如何制作并发布一个vue的组件的npm包
Nov 10 #Javascript
如何在基于vue-cli的项目自定义打包环境
Nov 10 #Javascript
Vue项目报错:Uncaught SyntaxError: Unexpected token
Nov 10 #Javascript
node+express框架中连接使用mysql(经验总结)
Nov 10 #Javascript
vue axios请求频繁时取消上一次请求的方法
Nov 10 #Javascript
微信小程序实现跑马灯效果
Oct 21 #Javascript
微信小程序使用scroll-view标签实现自动滑动到底部功能的实例代码
Nov 09 #Javascript
You might like
请php正则走开
2008/03/15 PHP
PHP数据类型之整数类型、浮点数的介绍
2013/04/28 PHP
php获取当月最后一天函数分享
2015/02/02 PHP
ZF框架实现发送邮件的方法
2015/12/03 PHP
PHP使用mysqli操作MySQL数据库的简单方法
2017/02/04 PHP
JavaScript基本对象
2007/01/11 Javascript
JavaScript具有类似Lambda表达式编程能力的代码(改进版)
2010/09/14 Javascript
javascript校验价格合法性实例(必须输入2位小数)
2014/05/05 Javascript
EasyUI布局 高度自适应
2016/06/04 Javascript
JavaScript中值类型和引用类型的区别
2017/02/23 Javascript
jQuery实现radio第一次点击选中第二次点击取消功能
2017/05/15 jQuery
JS实现DOM删除节点操作示例
2018/04/04 Javascript
JS使用遮罩实现点击某区域以外时弹窗的弹出与关闭功能示例
2018/07/31 Javascript
Js 利用正则表达式和replace函数获取string中所有被匹配到的文本(推荐)
2018/10/28 Javascript
小程序二次贝塞尔曲线实现购物车商品曲线飞入效果
2019/01/07 Javascript
Vue实现将数据库中带html标签的内容输出(原始HTML(Raw HTML))
2019/10/28 Javascript
vue实现数字动态翻牌的效果(开箱即用)
2019/12/08 Javascript
微信小程序基于movable-view实现滑动删除效果
2020/01/08 Javascript
[01:59][TI9趣味视频] 全明星赛奖励
2019/08/23 DOTA
Python中实现对Timestamp和Datetime及UTC时间之间的转换
2015/04/08 Python
Python itertools模块详解
2015/05/09 Python
Python 一句话生成字母表的方法
2019/01/02 Python
对Python3 goto 语句的使用方法详解
2019/02/16 Python
通过实例了解python property属性
2019/11/01 Python
python pyqtgraph 保存图片到本地的实例
2020/03/14 Python
基于K.image_data_format() == 'channels_first' 的理解
2020/06/29 Python
免费获得微软MCSD证书赶快行动吧!
2012/11/13 HTML / CSS
罗兰·穆雷官网:Roland Mouret
2018/09/28 全球购物
彪马西班牙官网:PUMA西班牙
2019/06/18 全球购物
ddl,dml和dcl的含义
2016/05/08 面试题
初级会计求职信范文
2014/02/15 职场文书
《观舞记》教学反思
2014/04/16 职场文书
地球一小时宣传标语
2014/06/24 职场文书
妇女工作先进事迹
2014/08/17 职场文书
初中生散播谣言检讨书
2014/11/17 职场文书
小学运动会加油稿
2015/07/22 职场文书