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 相关文章推荐
发两个小东西,ASP/PHP 学习工具。 用JavaScript写的
Apr 12 Javascript
js中格式化日期时间型数据函数代码
Nov 08 Javascript
jquery实现翻动fadeIn显示的方法
Mar 05 Javascript
JavaScript 浏览器对象模型BOM使用介绍
Apr 13 Javascript
require.js的用法详解
Oct 20 Javascript
JS实现Select的option上下移动的方法
Mar 01 Javascript
Angular下H5上传图片的方法(可多张上传)
Jan 09 Javascript
vue下跨域设置的相关介绍
Aug 26 Javascript
浅析JS抽象工厂模式
Dec 14 Javascript
Vue 实时监听窗口变化 windowresize的两种方法
Nov 06 Javascript
浅谈小程序globalData的那些事儿
Nov 01 Javascript
微信小程序开发数据缓存基础知识辨析及运用实例详解
Nov 06 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中使用gettext解决国际化问题的例子(i18n)
2014/06/13 PHP
Yii2 中实现单点登录的方法
2018/03/09 PHP
Javascript日期对象的dateAdd与dateDiff方法
2008/11/18 Javascript
javascript showModalDialog 内跳转页面的问题
2010/11/25 Javascript
纯javascript实现自动发送邮件
2015/10/21 Javascript
Javascript简单实现面向对象编程继承实例代码
2015/11/27 Javascript
js阻止浏览器默认行为的简单实例
2016/05/15 Javascript
获取input标签的所有属性的方法
2016/06/28 Javascript
xmlplus组件设计系列之列表(4)
2017/04/26 Javascript
JS简单实现点击按钮或文字显示遮罩层的方法
2017/04/27 Javascript
vue中计算属性(computed)、methods和watched之间的区别
2017/07/27 Javascript
将jquery.qqFace.js表情转换成微信的字符码
2017/12/01 jQuery
NodeJs实现简单的爬虫功能案例分析
2018/12/05 NodeJs
微信小程序自定义键盘 内部虚拟支付
2018/12/20 Javascript
js实现GIF图片的分解和合成
2019/10/24 Javascript
Vue实现简易计算器
2020/02/25 Javascript
Vue + Scss 动态切换主题颜色实现换肤的示例代码
2020/04/27 Javascript
vue 防止页面加载时看到花括号的解决操作
2020/11/09 Javascript
vue 实现基础组件的自动化全局注册
2020/12/25 Vue.js
[03:04]DOTA2超级联赛专访ZSMJ “莫名其妙”的逆袭
2013/05/23 DOTA
python函数局部变量用法实例分析
2015/08/04 Python
Python判断以什么结尾以什么开头的实例
2018/10/27 Python
Python装饰器语法糖
2019/01/02 Python
python3实现字符串操作的实例代码
2019/04/16 Python
Python 实现交换矩阵的行示例
2019/06/26 Python
在python中用print()输出多个格式化参数的方法
2019/07/16 Python
Python+Tensorflow+CNN实现车牌识别的示例代码
2019/10/11 Python
利用Python裁切tiff图像且读取tiff,shp文件的实例
2020/03/10 Python
python可视化 matplotlib画图使用colorbar工具自定义颜色
2020/12/07 Python
python中spy++的使用超详细教程
2021/01/29 Python
一加手机美国官方网站:OnePlus美国
2019/09/19 全球购物
说明书怎么写
2014/05/06 职场文书
婚前协议书范本
2014/10/27 职场文书
保护校园环境倡议书
2015/04/28 职场文书
幼儿体育课教学反思
2016/02/16 职场文书
Win11 Build 22000.829更新补丁KB5015882发布(附更新修复内容汇总)
2022/07/15 数码科技