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中的几个运算符
Jun 29 Javascript
图片自动缩小 点击放大
Jul 07 Javascript
Javascript this关键字使用分析
Oct 21 Javascript
javascript实现Table间隔色以及选择高亮(和动态切换数据)的方法
May 14 Javascript
浅析JS运动
Dec 28 Javascript
浅谈JavaScript 中有关时间对象的方法
Aug 15 Javascript
基于JQuery实现的跑马灯效果(文字无缝向上翻动)
Dec 02 Javascript
JS实现密码框的显示密码和隐藏密码功能示例
Dec 26 Javascript
JavaScript基础之this详解
Jun 04 Javascript
Vue 第三方字体图标引入 Font Awesome的方法
Sep 28 Javascript
微信小程序tabbar底部导航
Nov 05 Javascript
vuex刷新后数据丢失的解决方法
Oct 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
ThinkPHP模版引擎之变量输出详解
2014/12/05 PHP
php实现可用于mysql,mssql,pg数据库操作类
2014/12/13 PHP
用YUI做了个标签浏览效果
2007/02/20 Javascript
原生Js实现按的数据源均分时间点幻灯片效果(已封装)
2010/12/28 Javascript
jQuery实现form表单reset按钮重置清空表单功能
2012/12/18 Javascript
jquery submit ie6下失效的原因分析及解决方法
2013/11/15 Javascript
查询json的数据结构的8种方式简介
2014/03/10 Javascript
JavaScript italics方法入门实例(把字符串显示为斜体)
2014/10/17 Javascript
详解JavaScript中的4种类型识别方法
2015/09/14 Javascript
JS实现密码框根据焦点的获取与失去控制文字的消失与显示效果
2015/11/26 Javascript
Bootstrap3 datetimepicker控件使用实例
2016/12/13 Javascript
微信小程序 解决swiper不显示图片的方法
2017/01/04 Javascript
vue使用Axios做ajax请求详解
2017/06/07 Javascript
jQuery获取所有父级元素及同级元素及子元素的方法(推荐)
2018/01/21 jQuery
jQuery中图片展示插件highslide.js的简单dom
2018/04/22 jQuery
vue实现密码显示与隐藏按钮的自定义组件功能
2019/04/23 Javascript
为vue项目自动设置请求状态的配置方法
2019/06/09 Javascript
下载安装setuptool和pip linux安装pip    
2014/01/24 Python
Django的数据模型访问多对多键值的方法
2015/07/21 Python
Python 3.x 连接数据库示例(pymysql 方式)
2017/01/19 Python
Python实现生成随机数据插入mysql数据库的方法
2017/12/25 Python
基于python2.7实现图形密码生成器的实例代码
2019/11/05 Python
python批量修改xml属性的实现方式
2020/03/05 Python
python3通过qq邮箱发送邮件以及附件
2020/05/20 Python
Django后端按照日期查询的方法教程
2021/02/28 Python
谈一谈HTML5本地存储技术
2016/03/02 HTML / CSS
HTML5 canvas实现移动端上传头像拖拽裁剪效果
2016/03/14 HTML / CSS
彼得罗夫美国官网:Peter Thomas Roth美国(青瓜面膜)
2017/11/05 全球购物
北京英文导游词
2015/02/12 职场文书
《秋天的图画》教学反思
2016/02/19 职场文书
经典励志格言:每日一句,让你每天充满能量
2019/08/16 职场文书
详解CSS开发过程中的20个快速提升技巧
2021/05/21 HTML / CSS
Java用自带的Image IO给图片添加水印
2021/06/15 Java/Android
详解Spring Boot使用系统参数表提升系统的灵活性
2021/06/30 Java/Android
python实现手机推送 代码也就10行左右
2022/04/12 Python
win11开机发生死循环重启怎么办?win11开机发生死循环重启解决方法
2022/08/05 数码科技