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例子返回值详解
Sep 11 Javascript
30分钟就入门的正则表达式基础教程
Feb 25 Javascript
多个datatable共存造成多个表格的checkbox都被选中
Jul 11 Javascript
jquery 简单应用示例总结
Aug 09 Javascript
JS实现清除指定cookies的方法
Sep 20 Javascript
浏览器兼容的JS写法总结
Apr 27 Javascript
更靠谱的H5横竖屏检测方法(js代码)
Sep 13 Javascript
Angular2中Bootstrap界面库ng-bootstrap详解
Oct 18 Javascript
JS实现获取图片大小和预览的方法完整实例【兼容IE和其它浏览器】
Apr 24 Javascript
angularJs使用ng-repeat遍历后选中某一个的方法
Sep 30 Javascript
Node.js Domain 模块实例详解
Mar 18 Javascript
深入讲解Vue中父子组件通信与事件触发
Mar 22 Vue.js
详解如何制作并发布一个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
做一个有下拉功能的留言版
2006/10/09 PHP
简单PHP上传图片、删除图片实现代码
2010/05/12 PHP
Yii实现自动加载类地图的方法
2015/04/01 PHP
php实现的验证码文件类实例
2015/06/18 PHP
jquery多浏览器捕捉回车事件代码
2010/06/22 Javascript
理解JavaScript中的对象 推荐
2011/01/09 Javascript
jquery入门—访问DOM对象方法
2013/01/07 Javascript
JS获取并操作iframe中元素的方法
2013/03/21 Javascript
js 上下左右键控制焦点(示例代码)
2013/12/14 Javascript
yepnope.js使用详解及示例分享
2014/06/23 Javascript
jQuery实现ichat在线客服插件
2014/12/29 Javascript
Grunt入门教程(自动任务运行器)
2015/08/06 Javascript
JS实现不使用图片仿Windows右键菜单效果代码
2015/10/22 Javascript
基于nodejs+express(4.x+)实现文件上传功能
2015/11/23 NodeJs
WEB前端实现裁剪上传图片功能
2016/10/17 Javascript
简单理解vue中track-by属性
2016/10/26 Javascript
js实现符合国情的日期插件详解
2017/01/19 Javascript
jQuery插件simplePagination的使用方法示例
2020/04/28 jQuery
我所理解的JavaScript中的this指向
2020/09/04 Javascript
python调用外部程序的实操步骤
2019/03/04 Python
tensorflow ckpt模型和pb模型获取节点名称,及ckpt转pb模型实例
2020/01/21 Python
python将logging模块封装成单独模块并实现动态切换Level方式
2020/05/12 Python
深入了解NumPy 高级索引
2020/07/24 Python
通过代码实例了解Python异常本质
2020/09/16 Python
详解Open Folder as PyCharm Project怎么添加的方法
2020/12/29 Python
关于python中remove的一些坑小结
2021/01/04 Python
员工晚婚的请假条
2014/02/08 职场文书
教师四风问题对照检查材料
2014/09/26 职场文书
党员四风问题个人对照检查材料
2014/10/26 职场文书
中班下学期个人总结
2015/02/12 职场文书
自我检讨书怎么写
2015/05/07 职场文书
党支部半年考察意见
2015/06/01 职场文书
暂住证明怎么写
2015/06/19 职场文书
2016年第16个全民国防教育日宣传活动总结
2016/04/05 职场文书
24年收藏2000多部退役军用电台
2022/02/18 无线电
Python 视频画质增强
2022/04/28 Python