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下通过$.browser来判断浏览器.
Apr 05 Javascript
读jQuery之二(两种扩展)
Jun 11 Javascript
用JavaScript计算在UTF-8下存储字符串占用字节数
Aug 08 Javascript
jquery插件之定时查询待处理任务数量
May 01 Javascript
一个不错的仿携程自定义数据下拉选择select
Sep 01 Javascript
不定义JQuery插件 不要说会JQuery
Mar 07 Javascript
浅谈Javascript事件对象
Feb 05 Javascript
如何在Angular2中使用jQuery及其插件的方法
Feb 09 Javascript
实例讲解javascript实现异步图片上传方法
Dec 05 Javascript
JavaScript实现JSON合并操作示例【递归深度合并】
Sep 07 Javascript
react实现antd线上主题动态切换功能
Aug 12 Javascript
JQuery获得内容和属性方法解析
May 30 jQuery
详解如何制作并发布一个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答题类应用接口实例
2015/02/09 PHP
php实现在多维数组中查找特定value的方法
2015/07/29 PHP
PHP邮件群发机实现代码
2016/02/16 PHP
PHP缓存工具XCache安装与使用方法详解
2018/04/09 PHP
深入学习微信网址链接解封的防封原理visit_type
2019/08/15 PHP
精解window.setTimeout()&amp;window.setInterval()使用方式与参数传递问题!
2007/11/23 Javascript
javascript 添加和移除函数的通用方法
2009/10/20 Javascript
JavaScript的eval JSON object问题
2009/11/15 Javascript
js的表单操作 简单计算器
2011/12/29 Javascript
JQueryiframe页面操作父页面中的元素与方法(实例讲解)
2013/11/19 Javascript
超级简单的jquery操作表格方法
2014/12/15 Javascript
JavaScript用select实现日期控件
2015/07/17 Javascript
浅析jQuery Ajax请求参数和返回数据的处理
2016/02/24 Javascript
JavaScript中的一些隐式转换和总结(推荐)
2017/12/22 Javascript
浅谈layui分页控件field参数接收对象的问题
2019/09/20 Javascript
jQuery单页面文字搜索插件jquery.fullsearch.js的使用方法
2020/02/04 jQuery
详解JavaScript中的this指向问题
2021/02/05 Javascript
[04:44]显微镜下的DOTA2第二期——你所没有注意到的细节
2014/06/20 DOTA
Cython 三分钟入门教程
2009/09/17 Python
对Python3.6 IDLE常用快捷键介绍
2018/07/16 Python
Anaconda下配置python+opencv+contribx的实例讲解
2018/08/06 Python
python hook监听事件详解
2018/10/25 Python
Appium+python自动化怎么查看程序所占端口号和IP
2019/06/14 Python
Pandas操作CSV文件的读写实现方法
2019/11/13 Python
让IE支持CSS3的不完全兼容方案
2014/09/19 HTML / CSS
使用phonegap检测网络状态的方法
2017/03/30 HTML / CSS
护士毕业自我鉴定
2014/02/07 职场文书
2014年3.15团委活动总结
2014/03/16 职场文书
过程装备与控制工程专业求职信
2014/07/02 职场文书
干部作风整顿自我剖析材料和整改措施
2014/09/18 职场文书
“四风”问题整改措施和努力方向
2014/09/20 职场文书
单位婚育证明范本
2014/11/21 职场文书
2016党员党课心得体会
2016/01/07 职场文书
2016年大学光棍节活动总结
2016/04/05 职场文书
详解Laravel服务容器的优势
2021/05/29 PHP
使用Vue3+Vant组件实现App搜索历史记录功能(示例代码)
2021/06/09 Vue.js