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 中多条件选择器,相对选择器,层次选择器的区别
Jul 03 Javascript
jquery实现excel导出的方法
Apr 04 Javascript
js禁止页面刷新禁止用F5键刷新禁止右键的示例代码
Sep 23 Javascript
当前流行的JavaScript代码风格指南
Sep 10 Javascript
jquery实现仿JqueryUi可拖动的DIV实例
Jul 31 Javascript
实例详解AngularJS实现无限级联动菜单
Jan 15 Javascript
JavaScript实现倒计时跳转页面功能【实用】
Dec 13 Javascript
浅谈angular.js跨域post解决方案
Aug 30 Javascript
vue实现登陆登出的实现示例
Sep 15 Javascript
webpack项目调试以及独立打包配置文件的方法
Feb 28 Javascript
详解js静态检查工具eslint配置文件
Nov 23 Javascript
vue.js watch经常失效的场景与解决方案
Jan 07 Vue.js
详解如何制作并发布一个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
解决163/sohu/sina不能够收到PHP MAIL函数发出邮件的问题
2009/03/13 PHP
PHP $_FILES中error返回值详解
2014/01/30 PHP
浅谈PHP中单引号和双引号到底有啥区别呢?
2015/03/04 PHP
判断是否输入完毕再激活提交按钮
2006/06/26 Javascript
基于jquery的bankInput银行卡账号格式化
2012/08/22 Javascript
jquery $(document).ready()和window.onload的区别浅析
2015/02/04 Javascript
jQuery构造函数init参数分析
2015/05/13 Javascript
JavaScript识别网页关键字并进行描红的方法
2015/11/09 Javascript
Easyui 之 Treegrid 笔记
2016/04/29 Javascript
Canvas + JavaScript 制作图片粒子效果
2017/02/08 Javascript
JS简单实现点击跳转登陆邮箱功能的方法
2017/10/31 Javascript
在vue中添加Echarts图表的基本使用教程
2017/11/22 Javascript
Vue 中mixin 的用法详解
2018/04/23 Javascript
一个Vue页面的内存泄露分析详解
2018/06/25 Javascript
vue+Element-ui实现分页效果
2020/11/15 Javascript
[03:24]DOTA2超级联赛专访hao 大翻盘就是逆袭
2013/05/24 DOTA
布同自制Python函数帮助查询小工具
2011/03/13 Python
python计算文本文件行数的方法
2015/07/06 Python
解决python2.7用pip安装包时出现错误的问题
2017/01/23 Python
python opencv3实现人脸识别(windows)
2018/05/25 Python
解决新django中的path不能使用正则表达式的问题
2018/12/18 Python
Python线上环境使用日志的及配置文件
2019/07/28 Python
django 链接多个数据库 并使用原生sql实现
2020/03/28 Python
python上传时包含boundary时的解决方法
2020/04/08 Python
pandas分批读取大数据集教程
2020/06/06 Python
Python实现给PDF添加水印的方法
2021/01/25 Python
HTML5 语义化结构化规范化
2008/10/17 HTML / CSS
Shopee马来西亚:随拍即卖,最佳行动电商拍卖平台
2017/06/05 全球购物
Expedia加拿大官方网站:加拿大最大的在线旅游提供商
2017/12/31 全球购物
信息技术专业个人自我评价
2013/12/11 职场文书
司法建议书范文
2014/05/13 职场文书
2015年六一儿童节演讲稿
2015/03/19 职场文书
2016教师暑期培训学习心得体会
2016/01/09 职场文书
周一早安温馨问候祝福语!
2019/07/15 职场文书
python套接字socket通信
2022/04/01 Python
苹果可能正在打击不进行更新的 App
2022/04/24 数码科技