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 相关文章推荐
使Ext的Template可以解析二层的json数据的方法
Dec 22 Javascript
File文件控件,选中文件(图片,flash,视频)即立即预览显示
Apr 09 Javascript
javascript中apply和call方法的作用及区别说明
Feb 14 Javascript
纯js实现无限空间大小的本地存储
Jun 18 Javascript
基于jquery实现省市联动效果
Nov 23 Javascript
学习javascript面向对象 javascript实现继承的方式
Jan 04 Javascript
微信jssdk在iframe页面失效问题的解决措施
Mar 03 Javascript
总结Javascript中的隐式类型转换
Aug 24 Javascript
Bootstrap中data-target 到底是什么
Feb 14 Javascript
JavaScript中Hoisting详解 (变量提升与函数声明提升)
Aug 18 Javascript
Vue 路由 过渡动效 数据获取方法
Jul 31 Javascript
vue axios数据请求及vue中使用axios的方法
Sep 10 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
PHP4实际应用经验篇(8)
2006/10/09 PHP
php数组函数序列之prev() - 移动数组内部指针到上一个元素的位置,并返回该元素值
2011/10/31 PHP
PHP写UltraEdit插件脚本实现方法
2011/12/26 PHP
php处理restful请求的路由类分享
2014/02/27 PHP
关于Yii2框架跑脚本时内存泄漏问题的分析与解决
2019/12/01 PHP
Javascript valueOf 使用方法
2008/12/28 Javascript
原生javascript获取元素样式
2014/12/31 Javascript
JQuery动态添加和删除表格行的方法
2015/03/09 Javascript
介绍JavaScript的一个微型模版
2015/06/24 Javascript
原生JS实现仿淘宝网左侧商品分类菜单效果代码
2015/09/10 Javascript
JS使用正则表达式实现关键字替换加粗功能示例
2016/08/03 Javascript
bootstrap监听滚动实现头部跟随滚动
2016/11/08 Javascript
jQuery实现手机上输入后隐藏键盘功能
2017/01/04 Javascript
Android中Okhttp3实现上传多张图片同时传递参数
2017/02/18 Javascript
Bootstrap输入框组件使用详解
2017/06/09 Javascript
jQuery 改变P标签文本值方法
2018/02/24 jQuery
详解node.js的http模块实例演示
2018/07/12 Javascript
vuejs 制作背景淡入淡出切换动画的实例
2018/09/01 Javascript
JS学习笔记之数组去重实现方法小结
2019/05/29 Javascript
浅谈Vue为什么不能检测数组变动
2019/10/14 Javascript
写一个Vue loading 插件
2020/11/09 Javascript
python 获取et和excel的版本号
2009/04/09 Python
用 Python 连接 MySQL 的几种方式详解
2018/04/04 Python
PyCharm+PySpark远程调试的环境配置的方法
2018/11/29 Python
解决Python计算矩阵乘向量,矩阵乘实数的一些小错误
2019/08/26 Python
Python中if有多个条件处理方法
2020/02/26 Python
Nayomi官网:沙特阿拉伯王国睡衣和内衣品牌
2020/12/19 全球购物
宝信软件JAVA工程师面试经历
2012/08/19 面试题
办理护照介绍信
2014/01/16 职场文书
教师对学生的评语
2014/04/28 职场文书
党的群众路线教育实践活动学习计划
2014/11/03 职场文书
交通事故死亡赔偿协议书
2014/12/03 职场文书
调解协议书范本
2016/03/21 职场文书
2019奶茶店创业计划书范本,值得你借鉴
2019/08/14 职场文书
创业计划书之小型广告公司
2019/10/22 职场文书
使用Spring处理x-www-form-urlencoded方式
2021/11/02 Java/Android