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 相关文章推荐
js 屏蔽鼠标右键脚本附破解方法
Dec 03 Javascript
javascript数组去掉重复
May 12 Javascript
jQuery插件 selectToSelect使用方法
Oct 02 Javascript
jquery cookie的用法总结
Nov 18 Javascript
对table和ul实现js分页示例分享
Feb 24 Javascript
JSP中使用JavaScript动态插入删除输入框实现代码
Jun 13 Javascript
javascript将浮点数转换成整数的三个方法
Jun 23 Javascript
浅谈Jquery为元素绑定事件
Apr 27 Javascript
AngularJS ui-router (嵌套路由)实例
Mar 10 Javascript
Javascript面试经典套路reduce函数查重
Mar 23 Javascript
jQuery滚动条美化插件nicescroll简单用法示例
Apr 18 jQuery
小程序最新获取用户昵称和头像的方法总结
Sep 23 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的宝库目录--PEAR
2006/10/09 PHP
PHP函数超时处理方法
2016/02/14 PHP
PHP判断密码强度的方法详解
2017/05/26 PHP
Ecshop 后台添加新功能栏目及管理权限设置教程
2017/11/21 PHP
javascript动画算法实例分析
2015/07/31 Javascript
微信小程序 form组件详解及简单实例
2017/01/10 Javascript
jQuery.cookie.js实现记录最近浏览过的商品功能示例
2017/01/23 Javascript
js 获取图像缩放后的实际宽高,位置等信息
2017/03/07 Javascript
深究AngularJS如何获取input的焦点(自定义指令)
2017/06/12 Javascript
javascript  数组排序与对象排序的实例
2017/07/17 Javascript
vue小图标favicon不显示的解决方案
2017/09/19 Javascript
Vue-Access-Control 前端用户权限控制解决方案
2017/12/01 Javascript
如何理解Vue的v-model指令的使用方法
2018/07/19 Javascript
JavaScript设计模式之构造器模式(生成器模式)定义与用法实例分析
2018/07/26 Javascript
[59:35]DOTA2-DPC中国联赛定级赛 Aster vs DLG BO3第一场 1月8日
2021/03/11 DOTA
跟老齐学Python之玩转字符串(3)
2014/09/14 Python
简介Python中用于处理字符串的center()方法
2015/05/18 Python
windows下python 3.6.4安装配置图文教程
2018/08/21 Python
pandas ix &amp;iloc &amp;loc的区别
2019/01/10 Python
python实现转圈打印矩阵
2019/03/02 Python
Python使用dict.fromkeys()快速生成一个字典示例
2019/04/24 Python
python 求定积分和不定积分示例
2019/11/20 Python
Python-opencv 双线性插值实例
2020/01/17 Python
Python中文分词库jieba,pkusegwg性能准确度比较
2020/02/11 Python
Django模板标签{% for %}循环,获取制定条数据实例
2020/05/14 Python
Matlab中plot基本用法的具体使用
2020/07/17 Python
在vscode中启动conda虚拟环境的思路详解
2020/12/25 Python
python requests库的使用
2021/01/06 Python
CSS3 实现童年的纸飞机
2019/05/05 HTML / CSS
西班牙电子产品购物网站:Electronicamente
2018/07/26 全球购物
公益广告标语
2014/06/19 职场文书
学生实习证明范文
2014/09/28 职场文书
历史博物馆观后感
2015/06/05 职场文书
Mysql多层子查询示例代码(收藏夹案例)
2022/03/31 MySQL
Pandas数据结构之Series的使用
2022/03/31 Python
python playwright之元素定位示例详解
2022/07/23 Python