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 相关文章推荐
JQuery Ajax通过Handler访问外部XML数据的代码
Jun 01 Javascript
jQuery选择没有colspan属性的td的代码
Jul 06 Javascript
javascript仿qq界面的折叠菜单实现代码
Dec 12 Javascript
javascript 将共享属性迁移到原型中去的实现方法
Aug 31 Javascript
AngularJS实现动态编译添加到dom中的方法
Nov 04 Javascript
微信小程序 页面跳转传递值几种方法详解
Jan 12 Javascript
jquery实现提示语淡入效果
May 05 jQuery
JavaScript输入框字数实时统计更新
Jun 17 Javascript
微信小程序常见页面跳转操作简单示例
May 01 Javascript
vue实现绑定事件的方法实例代码详解
Jun 20 Javascript
解决layui数据表格Date日期格式的回显Object的问题
Sep 19 Javascript
Element DateTimePicker日期时间选择器的使用示例
Jul 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+xslt在windows平台上
2006/10/09 PHP
PHP 截取字符串 分别适合GB2312和UTF8编码情况
2009/02/12 PHP
php中的ini配置原理详解
2014/10/14 PHP
ThinkPHP整合百度Ueditor图文教程
2014/10/21 PHP
PHP翻页跳转功能实现方法
2020/11/30 PHP
JS获取字符串实际长度(包含汉字)的简单方法
2016/08/11 Javascript
快速移动鼠标触发问题及解决方法(ECharts外部调用保存为图片操作及工作流接线mouseenter和mouseleave)
2016/08/29 Javascript
火狐和ie下获取javascript 获取event的方法(推荐)
2016/11/26 Javascript
JavaScript下拉菜单功能实例代码
2017/03/01 Javascript
jquery拼接ajax 的json和字符串拼接的方法
2017/03/11 Javascript
基于JavaScript实现移动端无限加载分页
2017/03/27 Javascript
JS+Canvas绘制动态时钟效果
2017/11/10 Javascript
JS中双击和单击事件冲突的解决方法
2018/04/09 Javascript
js+HTML5 canvas 实现简单的加载条(进度条)功能示例
2019/07/16 Javascript
Postman无法正常返回结果问题解决
2020/08/28 Javascript
[03:05]《我与DAC》之xiao8:DAC与BG
2018/03/27 DOTA
python的迭代器与生成器实例详解
2014/07/16 Python
Python基于Matplotlib库简单绘制折线图的方法示例
2017/08/14 Python
Python数字图像处理之霍夫线变换实现详解
2018/01/12 Python
如何使用Python的Requests包实现模拟登陆
2018/04/27 Python
pycham查看程序执行的时间方法
2018/11/29 Python
python代码 输入数字使其反向输出的方法
2018/12/22 Python
python内存管理机制原理详解
2019/08/12 Python
keras 两种训练模型方式详解fit和fit_generator(节省内存)
2020/07/03 Python
使用css3绘制出各种几何图形
2016/08/17 HTML / CSS
CSS3 实现弹跳的小球动画
2020/10/26 HTML / CSS
澳大利亚最大的女装零售商:Millers
2017/09/10 全球购物
STAUD官方网站:洛杉矶独有的闲适风格
2019/04/11 全球购物
Hanky Panky官方网站:内衣和睡衣
2019/07/25 全球购物
临床医师个人自我评价
2014/04/06 职场文书
入党积极分子党支部意见
2015/06/02 职场文书
《清澈的湖水》教学反思
2016/02/17 职场文书
uniapp开发小程序的经验总结
2021/04/08 Javascript
Vue实现动态查询规则生成组件
2021/05/27 Vue.js
Nginx缓存设置案例详解
2021/09/15 Servers
mysql 联合索引生效的条件及索引失效的条件
2021/11/20 MySQL