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 相关文章推荐
遍历DOM对象内的元素属性示例代码
Feb 08 Javascript
JQuery动画与特效实例分析
Feb 02 Javascript
jQuery获取上传文件的名称的正则表达式
May 21 Javascript
JavaScript中的时间处理小结
Feb 24 Javascript
js实现点击图片自动提交action的简单方法
Oct 16 Javascript
jquery submit()不能提交表单的解决方法
Apr 24 jQuery
JS实现仿饿了么在浏览器标签页失去焦点时网页Title改变
Jun 01 Javascript
JavaScript数组去重算法实例小结
May 07 Javascript
ionic4+angular7+cordova上传图片功能的实例代码
Jun 19 Javascript
Javascript组合继承方法代码实例解析
Apr 02 Javascript
Vue实现浏览器打印功能的代码
Apr 17 Javascript
小程序实现上传视频功能
Aug 18 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常量的详解
2013/06/09 PHP
php smarty模板引擎的6个小技巧
2014/04/24 PHP
js QQ客服悬浮效果实现代码
2014/12/12 Javascript
jQuery中on()方法用法实例
2015/01/19 Javascript
JavaScript对象反射用法实例
2015/04/17 Javascript
js中unicode转码方法详解
2015/10/09 Javascript
JS日期加减,日期运算代码
2015/11/05 Javascript
浅析node连接数据库(express+mysql)
2015/11/30 Javascript
jquery拖拽排序简单实现方法(效果增强版)
2016/02/16 Javascript
详解JavaScript实现设计模式中的适配器模式的方法
2016/05/18 Javascript
Vue数据驱动模拟实现2
2017/01/11 Javascript
基于JavaScript实现类名的添加与移除
2017/04/23 Javascript
在Debian(Raspberry Pi)树莓派上安装NodeJS的教程详解
2017/09/19 NodeJs
Vue不能检测到Object/Array更新的情况的解决
2018/06/26 Javascript
解决node-sass偶尔安装失败的方法小结
2018/12/05 Javascript
微信浏览器下拉黑边解决方案 wScroollFix
2020/01/21 Javascript
解决antd的Form组件setFieldsValue的警告问题
2020/10/29 Javascript
JavaScript实现浏览器网页自动滚动并点击的示例代码
2020/12/05 Javascript
Python的randrange()方法使用教程
2015/05/15 Python
举例详解Python中threading模块的几个常用方法
2015/06/18 Python
Scrapy框架使用的基本知识
2018/10/21 Python
Django REST framework视图的用法
2019/01/16 Python
ML神器:sklearn的快速使用及入门
2019/07/11 Python
业务部主管岗位职责
2014/01/29 职场文书
党课知识竞赛主持词
2014/04/01 职场文书
竞选副班长演讲稿
2014/04/24 职场文书
抗洪抢险事迹材料
2014/05/06 职场文书
医院搬迁方案
2014/06/14 职场文书
场地使用证明模板
2014/10/25 职场文书
天堂的孩子观后感
2015/06/11 职场文书
村主任当选感言
2015/08/01 职场文书
2016初一新生军训心得体会
2016/01/11 职场文书
小程序实现悬浮按钮的全过程记录
2021/10/16 HTML / CSS
redis中lua脚本使用教程
2021/11/01 Redis
flex布局中使用flex-wrap实现换行的项目实践
2022/06/21 HTML / CSS
win10+RTX3050ti+TensorFlow+cudn+cudnn配置深度学习环境的方法
2022/06/25 Servers