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中Date.toSource()方法的使用教程
Jun 12 Javascript
使用Node.js配合Nginx实现高负载网络
Jun 28 Javascript
JS实现很实用的对联广告代码(可自适应高度)
Sep 18 Javascript
jquery仿ps颜色拾取功能
Mar 08 Javascript
jQuery序列化后的表单值转换成Json
Jun 16 jQuery
微信小程序三级联动地址选择器的实例代码
Jul 12 Javascript
layui实现table加载的示例代码
Aug 14 Javascript
Angular6 用户自定义标签开发的实现方法
Jan 08 Javascript
Vue.js样式动态绑定实现小结
Jan 24 Javascript
个人小程序接入支付解决方案
May 23 Javascript
js实现提交前对列表数据的增删改查
Jan 16 Javascript
详解使用mocha对webpack打包的项目进行&quot;冒烟测试&quot;的大致流程
Apr 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实现微信公众平台音乐点播
2014/03/20 PHP
php进行支付宝开发中return_url和notify_url的区别分析
2014/12/22 PHP
php支付宝在线支付接口开发教程
2016/09/19 PHP
用jquery ajax获取网站Alexa排名的代码
2009/12/12 Javascript
Javascript图像处理—亮度对比度应用案例
2013/01/03 Javascript
js中匿名函数的创建与调用方法分析
2014/12/19 Javascript
javascript中类的定义方式详解(四种方式)
2015/12/22 Javascript
AngularJS通过$location获取及改变当前页面的URL
2016/09/23 Javascript
基于bootstrap风格的弹框插件
2016/12/28 Javascript
jQuery实现html双向绑定功能示例
2017/10/09 jQuery
微信小程序支付之c#后台实现方法
2017/10/19 Javascript
详解Node 定时器
2018/02/26 Javascript
javascript json字符串到json对象转义问题
2019/01/22 Javascript
小程序实现多列选择器
2019/02/15 Javascript
详解React 元素渲染
2020/07/07 Javascript
Element-ui 自带的两种远程搜索(模糊查询)用法讲解
2021/01/29 Javascript
Python爬取国外天气预报网站的方法
2015/07/10 Python
python连接mysql实例分享
2016/10/09 Python
Python中装饰器兼容加括号和不加括号的写法详解
2017/07/05 Python
用Python进行简单图像识别(验证码)
2018/01/19 Python
Python3实现爬取简书首页文章标题和文章链接的方法【测试可用】
2018/12/11 Python
python遍历小写英文字母的方法
2019/01/02 Python
Python查找最长不包含重复字符的子字符串算法示例
2019/02/13 Python
Django框架文件上传与自定义图片上传路径、上传文件名操作分析
2019/05/10 Python
解决django的template中如果无法引用MEDIA_URL问题
2020/04/07 Python
中国旅游网站:同程旅游
2016/09/11 全球购物
Book Depository欧盟:一家领先的国际图书零售商
2019/05/21 全球购物
社区敬老月活动实施方案
2014/02/17 职场文书
建议书标准格式
2014/03/12 职场文书
学校火灾防控方案
2014/06/09 职场文书
2015年仓管员工作总结
2015/04/21 职场文书
2015年话务员工作总结
2015/04/29 职场文书
当幸福来敲门英文观后感
2015/06/01 职场文书
家访教师心得体会
2016/01/23 职场文书
2016年小学感恩节活动总结
2016/04/01 职场文书
2019秋季运动会口号
2019/06/25 职场文书