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 相关文章推荐
javascript确认框的三种使用方法
Dec 17 Javascript
JavaScript设计模式之原型模式(Object.create与prototype)介绍
Dec 28 Javascript
详解Angular中$cacheFactory缓存的使用
Aug 19 Javascript
用AngularJS的指令实现tabs切换效果
Aug 31 Javascript
一个极为简单的requirejs实现方法
Oct 20 Javascript
Angular.js前台传list数组由后台spring MVC接收数组示例代码
Jul 31 Javascript
Node.js  事件循环详解及实例
Aug 06 Javascript
seajs中最常用的7个功能、配置示例
Oct 10 Javascript
Vue项目使用localStorage+Vuex保存用户登录信息
May 27 Javascript
JS设置自定义快捷键并实现图片上下左右移动
Oct 17 Javascript
微信小程序实现下滑到底部自动翻页功能
Mar 07 Javascript
VueX模块的具体使用(小白教程)
Jun 05 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
如何限制访问者的ip(PHPBB的代码)
2006/10/09 PHP
用PHP制作的意见反馈表源码
2007/03/11 PHP
PHP调用.NET的WebService 简单实例
2015/03/27 PHP
Laravel 5.5基于内置的Auth模块实现前后台登陆详解
2017/12/21 PHP
jquery 多行滚动代码(附详细解释)
2010/06/17 Javascript
基于jquery的jqDnR拖拽溢出的修改
2011/02/12 Javascript
js 实现菜单左右滚动显示示例介绍
2013/11/21 Javascript
单元选择合并变色示例代码
2014/05/26 Javascript
jquery+php实现搜索框自动提示
2014/11/28 Javascript
七夕情人节丘比特射箭小游戏
2015/08/20 Javascript
JavaScript时间操作之年月日星期级联操作
2016/01/15 Javascript
JS解决iframe之间通信和自适应高度的问题
2016/08/24 Javascript
JS实现的Unicode编码转换操作示例
2017/04/28 Javascript
使用socket.io制做简易WEB聊天室
2018/01/02 Javascript
nodejs结合socket.io实现websocket通信功能的方法
2018/01/12 NodeJs
JS中Map和ForEach的区别
2018/02/05 Javascript
JavaScript数组去重算法实例小结
2018/05/07 Javascript
在vue中使用G2图表的示例代码
2019/03/19 Javascript
javascript/jquery实现点击触发事件的方法分析
2019/11/11 jQuery
jQuery实现飞机大战小游戏
2020/07/05 jQuery
python计算方程式根的方法
2015/05/07 Python
python正则表达式爬取猫眼电影top100
2018/02/24 Python
python 保存float类型的小数的位数方法
2018/10/17 Python
python3中eval函数用法使用简介
2019/08/02 Python
基于python实现地址和经纬度转换
2020/05/19 Python
python 3.8.3 安装配置图文教程
2020/05/21 Python
Python+PyQt5实现灭霸响指功能
2020/05/25 Python
重构Python代码的六个实例
2020/11/25 Python
去除python中的字符串空格的简单方法
2020/12/22 Python
利用CSS3的flexbox实现水平垂直居中与三列等高布局
2016/09/12 HTML / CSS
HTML5播放实现rtmp流直播
2020/06/16 HTML / CSS
摩托车和ATV零件、配件和服装的首选在线零售商:MotoSport
2017/12/22 全球购物
本科生个人求职自荐信
2013/09/26 职场文书
工艺工程师工作职责
2013/11/23 职场文书
大宝sod蜜广告词
2014/03/21 职场文书
2015年市场营销工作总结
2015/07/23 职场文书