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内核之基本概念
Oct 21 Javascript
jQuery学习笔记 操作jQuery对象 属性处理
Sep 19 Javascript
鼠标选择动态改变网页背景颜色的JS代码
Dec 10 Javascript
DOM基础教程之使用DOM + Css
Jan 20 Javascript
AngularJS入门教程之AngularJS模型
Apr 18 Javascript
Ext JS框架程序中阻止键盘触发回退或者刷新页面的代码分享
Jun 07 Javascript
第一篇初识bootstrap
Jun 21 Javascript
详解VUE的状态控制与延时加载刷新
Mar 27 Javascript
vue2.0在table中实现全选和反选的示例代码
Nov 04 Javascript
微信小程序实现时间预约功能
Nov 27 Javascript
Next.js项目实战踩坑指南(笔记)
Nov 29 Javascript
node.js命令行教程图文详解
May 27 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 处理图片的类实现代码
2009/10/23 PHP
php连接Access数据库错误及解决方法
2013/06/20 PHP
php定时执行任务设置详解
2015/02/06 PHP
php将图片文件转换成二进制输出的方法
2015/06/10 PHP
PHP Web木马扫描器代码分享
2015/09/06 PHP
注释PHP和html混合代码的小技巧(分享)
2016/11/03 PHP
PHP SESSION跨页面传递失败解决方案
2020/12/11 PHP
不使用XMLHttpRequest实现异步加载 Iframe和script
2012/10/29 Javascript
jQuery实现的Tab滑动选项卡及图片切换(多种效果)小结
2015/09/14 Javascript
使用纯JS代码判断字符串中有多少汉字的实现方法(超简单实用)
2016/11/12 Javascript
jQuery的事件预绑定
2016/12/05 Javascript
关于TypeScript中import JSON的正确姿势详解
2017/07/25 Javascript
微信小程序按钮去除边框线分享页面功能
2018/08/27 Javascript
新版小程序登录授权的方法
2018/12/12 Javascript
优化Vue项目编译文件大小的方法步骤
2019/05/27 Javascript
Vue+iview+webpack ie浏览器兼容简单处理
2019/09/20 Javascript
关于小程序优化的一些建议(小结)
2020/12/10 Javascript
python中文编码问题小结
2014/09/28 Python
python如何让类支持比较运算
2018/03/20 Python
python dataframe向下向上填充,fillna和ffill的方法
2018/11/28 Python
在python里从协程返回一个值的示例
2019/02/19 Python
wxPython实现分隔窗口
2019/11/19 Python
python 如何去除字符串头尾的多余符号
2019/11/19 Python
mac使用python识别图形验证码功能
2020/01/10 Python
Python基于Dlib的人脸识别系统的实现
2020/02/26 Python
python 数据分析实现长宽格式的转换
2020/05/18 Python
keras 自定义loss model.add_loss的使用详解
2020/06/22 Python
python实现控制台输出颜色
2021/03/02 Python
美国百货齐全的精品网站,提供美式风格的产品:Overstock.com
2016/07/22 全球购物
酒店管理专业学生求职信
2013/09/27 职场文书
歌颂祖国的演讲稿
2014/05/04 职场文书
2014年班主任工作总结
2014/11/08 职场文书
自我工作评价范文
2015/03/06 职场文书
Windows中Redis安装配置流程并实现远程访问功能
2021/06/07 Redis
MongoDB使用场景总结
2022/02/24 MongoDB
Spring Boot 的创建和运行示例代码详解
2022/07/23 Java/Android