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 相关文章推荐
jQuery的animate函数学习记录
Aug 08 Javascript
javascript实现滑动解锁功能
Dec 31 Javascript
jQuery插件实现控制网页元素动态居中显示
Mar 24 Javascript
JavaScript中this的9种应用场景及三种复合应用场景
Sep 12 Javascript
jQuery遍历DOM元素与节点方法详解
Apr 14 Javascript
jQuery.form插件的使用及跨域异步上传文件
Apr 27 Javascript
vue.js开发环境安装教程
Mar 17 Javascript
vuex中使用对象展开运算符的示例
Sep 25 Javascript
vue-router传参用法详解
Jan 19 Javascript
零基础之Node.js搭建API服务器的详解
Mar 08 Javascript
微信小程序实现张图片合成为一张并下载
Jul 16 Javascript
解决在Vue中使用axios用form表单出现的问题
Oct 30 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查询搜索引擎排名位置的代码
2010/01/05 PHP
PHP遍历XML文档所有节点的方法
2015/03/12 PHP
PHP常见过waf webshell以及最简单的检测方法
2019/05/21 PHP
为你的 Laravel 验证器加上多验证场景的实现
2020/04/07 PHP
javascript天然的迭代器
2010/10/29 Javascript
JavaScript定时器详解及实例
2013/08/01 Javascript
jquery操作select元素和option的实例代码
2016/02/03 Javascript
jquery.serialize() 函数语法及简单实例
2016/07/08 Javascript
Vue 页面状态保持页面间数据传输的一种方法(推荐)
2018/11/01 Javascript
ES6 Proxy实现Vue的变化检测问题
2019/06/11 Javascript
JavaScript的console命令使用实例
2019/12/03 Javascript
javascript设计模式 ? 原型模式原理与应用实例分析
2020/04/10 Javascript
[26:40]DOTA2上海特级锦标赛A组资格赛#1 Secret VS MVP.Phx第一局
2016/02/25 DOTA
Python multiprocessing.Manager介绍和实例(进程间共享数据)
2014/11/21 Python
Python的Flask框架中实现分页功能的教程
2015/04/20 Python
python3读取MySQL-Front的MYSQL密码
2017/05/03 Python
python 删除非空文件夹的实例
2018/04/26 Python
python pandas 对时间序列文件处理的实例
2018/06/22 Python
Python 数值区间处理_对interval 库的快速入门详解
2018/11/16 Python
Python3.5基础之变量、数据结构、条件和循环语句、break与continue语句实例详解
2019/04/26 Python
Python+Selenium使用Page Object实现页面自动化测试
2019/07/14 Python
python3中数组逆序输出方法
2020/12/01 Python
英国时尚优质的女装:Hope Fashion
2018/08/14 全球购物
新奥尔良珠宝:Mignon Faget
2020/11/23 全球购物
英文留学推荐信范文
2014/01/25 职场文书
房屋委托书范本
2014/04/04 职场文书
2014年教师党员公开承诺书
2014/05/28 职场文书
经典团队口号大全
2014/06/21 职场文书
拾金不昧锦旗标语
2014/06/27 职场文书
户籍证明格式
2014/09/15 职场文书
群众路线教育实践活动对照检查材料
2014/09/22 职场文书
综治维稳工作汇报
2014/10/27 职场文书
2015年小学师德师风建设工作总结
2015/10/23 职场文书
教师外出学习心得体会
2016/01/18 职场文书
MySQL提取JSON字段数据实现查询
2022/04/22 MySQL
索尼ICF-5900W收音机测评
2022/04/24 无线电