详解vue2.0组件通信各种情况总结与实例分析


Posted in Javascript onMarch 22, 2017

Props在vue组件中各种角色总结

在Vue中组件是实现模块化开发的主要内容,而组件的通信更是vue数据驱动的灵魂,现就四种主要情况总结如下:

使用props传递数据---组件内部

//html
<div id="app1">
  <i>注意命名规定:仅在html内使用my-message</i>
  <child my-message="组件内部数据传递"></child>
</div>
//js
<script>
  Vue.component('child', {
    props: ['myMessage'],
    template: '<mark>{{ myMessage }}<mark/>'
  });
  new Vue({
    el: '#app1'
  })
</script>

动态props通信---组件与根节点(父子之间)

<div id="app2">
  <input v-model="parentMsg">
  <br>
  <child :parent-msg="parentMsg"></child>
</div>
<script>
  Vue.component('child', {
    props: ['parentMsg'],
    template: '<mark>{{ parentMsg }}<mark/>'
  });
  new Vue({
    el: '#app2',
    data: {
      parentMsg: 'msg from parent!'
    }
  })
</script>

对比分析:

例子1:

<comp some-prop="1"></comp>
//组件内部数据传递,对应字面量语法:传递了一个字符串"1"

例子2:

<comp v-bind:some-prop="1"></comp>
//组件与根节点数据传递,对应动态语法:传递实际的数字:js表达式

单向数据流动特点:父组件属性变化时将传导给子组件,反之不可

两种改变prop情况

注意在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。

//定义一个局部data属性,并将 prop 的初始值作为局部数据的初始值
props: ['initialCounter'],
    data: function () {
    return { counter: this.initialCounter }
    }
//定义一个局部computed属性,此属性从 prop 的值计算得出
 props: ['size'],
    computed: {
    normalizedSize: function () {
    return this.size.trim().toLowerCase()
    }
    }

子组件索引

尽管有 props 和 events ,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 ref 为子组件指定一个索引 ID

<div id="parent">
<!-- vm.$refs.p will be the DOM node -->
<b ref="p">hello</b>
<!-- vm.$refs.child will be the child comp instance -->
<user-profile v-for='i in 3' ref="profile"></user-profile>
</div>
<script>
var userPf=Vue.component('user-profile',{
  template:'<div>hello $refs</div>'
});
var parent = new Vue({ el: '#parent' });
// 访问子组件
var child = parent.$refs.profile;
console.log(child[0]);
console.log(parent.$refs.p);
</script>

$refs 只在组件渲染完成后才填充,并且它是非响应式的。它仅仅作为一个直接访问子组件的应急方案——应当避免在模版或计算属性中使用 $refs 。

数据反传---自定义事件

自定义事件的根基在于每个vue实例都实现了事件接口(Event interface)

Vue的事件系统分离自浏览器的EventTarget API。尽管它们的运行类似,但是$on 和 $emit 不是addEventListener 和 dispatchEvent 的别名。

 父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件

  1. 监听:$on(eventName)
  2. 触发:$emit(eventName)
<div id="app3">
<p>Look at the parent's data: <mark>{{t}}</mark> & the child's data: <mark>{{childWords}}</mark></p>
<child v-on:add="pChange"></child>
<child v-on:add="pChange"></child>
<child v-on:click.native="native"></child>
</div>
<script>
Vue.component('child', {
  template: `<button @click="add">{{ c }}</button>`,
  data: function () {
    return {
      c: 0,
      msg: 'I am from child\'s data'
    }
  },
  methods: {
    add: function () {
      this.c += 1;
      this.$emit('add',this.msg);
    }
  },
});
new Vue({
  el: '#app3',
  data: {
    t: 0,
    childWords: ''
  },
  methods: {
    pChange: function (msg) {
      this.t += 1;
      this.childWords=msg;
    },
    native:function () {
      alert('I am a native event ,which comes from the root element!');
    }
  }
})
</script>

兄弟间通信---简单场景用bus,复杂场景用vuex

<div id="app4">
  <display></display>
  <increment></increment>
</div>
<script>
  var bus = new Vue();
  Vue.component('increment', {
    template: `<button @click="add">+</button>`,
    data: function () {
      return {count: 0}
    },
    methods: {
      add: function () {
        bus.$emit('inc', this.count+=1)
      }
    }
  });
  Vue.component('display', {
    template: `<span>Clicked: <mark>{{c}}</mark> times</span>`,
    data: function () {
      return {c: 0}
    },
    created: function () {
      var self=this;
//      bus.$on('inc', function (num) {
//        self.c = num
//      });
      bus.$on('inc', (num) =>
        this.c = num
      );
    }
  });
  vm = new Vue({
    el: "#app4",
  })
</script>

总结:Vue中关于组件间及组件与根节点间通信都可以人为是父子兄弟间的通信,另外父子关系是相对的即与上下文有关(比如A组件的父组件可能是B组件的子组件);上述四个例子分别演示了不同组件通信的机制。

澄清了上述问题不难理这句话:

编译作用域---父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。分发内容是在父组件作用域内编译

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
URI、URL和URN之间的区别与联系
Dec 20 Javascript
javascript中的几个运算符
Jun 29 Javascript
js实现基于正则表达式的轻量提示插件
Aug 29 Javascript
javascript随机抽取0-100之间不重复的10个数
Feb 25 Javascript
JQuery点击事件回到页面顶部效果的实现代码
May 24 Javascript
Servlet实现文件上传,可多文件上传示例
Dec 05 Javascript
原生js实现手风琴功能(支持横纵向调用)
Jan 13 Javascript
js实现导航栏中英文切换效果
Jan 16 Javascript
Ionic 2 实现列表滑动删除按钮的方法
Jan 22 Javascript
AngularJS中重新加载当前路由页面的方法
Mar 09 Javascript
详解vue-cli 构建项目 vue-cli请求后台接口 vue-cli使用axios、sass、swiper
May 28 Javascript
详解Vue-cli3 项目在安卓低版本系统和IE上白屏问题解决
Apr 14 Javascript
JS简单封装的图片无缝滚动效果示例【测试可用】
Mar 22 #Javascript
Vue计算属性的学习笔记
Mar 22 #Javascript
Angular2实现自定义双向绑定属性
Mar 22 #Javascript
Bootstrap如何激活导航状态
Mar 22 #Javascript
Bootstrap超大屏幕的实现代码
Mar 22 #Javascript
Bootstrap缩略图的创建方法
Mar 22 #Javascript
JS+DIV实现的卷帘效果示例
Mar 22 #Javascript
You might like
珊瑚虫IP库浅析
2007/02/15 PHP
php自动获取字符串编码函数mb_detect_encoding
2011/05/31 PHP
Codeigniter出现错误提示Error with CACHE directory的解决方案
2014/06/12 PHP
PHP清除数组中所有字符串两端空格的方法
2014/10/20 PHP
Laravel中如何增加自定义全局函数详解
2017/05/09 PHP
使用 laravel sms 构建短信验证码发送校验功能
2017/11/06 PHP
jquery 简单导航实现代码
2009/09/11 Javascript
jQuery 使用手册(四)
2009/09/23 Javascript
基于JQuery的一句代码实现表格的简单筛选
2010/07/26 Javascript
jquery中加载图片自适应大小主要实现代码
2013/08/23 Javascript
全面兼容的javascript时间格式化函数(比较实用)
2014/05/14 Javascript
JS倒计时代码汇总
2014/11/25 Javascript
Js中使用hasOwnProperty方法检索ajax响应对象的例子
2014/12/08 Javascript
TypeError document.getElementById(...) is null错误原因
2015/05/18 Javascript
浅谈JavaScript中null和undefined
2015/07/09 Javascript
利用jQuery中的ajax分页实现代码
2016/02/25 Javascript
AngularJs expression详解及简单示例
2016/09/01 Javascript
巧用Vue.js+Vuex制作专门收藏微信公众号的app
2016/11/03 Javascript
jstree单选功能的实现方法
2017/06/07 Javascript
详解设置Webstorm 利用babel将ES6自动转码成ES5
2017/12/20 Javascript
JavaScript实现表单注册、表单验证、运算符功能
2018/10/15 Javascript
JavaScript如何把两个数组对象合并过程解析
2019/10/10 Javascript
JavaScript代码异常监控实现过程详解
2020/02/17 Javascript
[00:11]战神迅矛
2019/03/06 DOTA
Python编写电话薄实现增删改查功能
2016/05/07 Python
Python用于学习重要算法的模块pygorithm实例浅析
2018/08/16 Python
python中的for循环
2018/09/28 Python
Python实现繁?转为简体的方法示例
2018/12/18 Python
Python multiprocess pool模块报错pickling error问题解决方法分析
2019/03/20 Python
python GUI库图形界面开发之PyQt5 Qt Designer工具(Qt设计师)详细使用方法及Designer ui文件转py文件方法
2020/02/26 Python
django自定义非主键自增字段类型详解(auto increment field)
2020/03/30 Python
在Sublime Editor中配置Python环境的详细教程
2020/05/03 Python
Django静态文件加载失败解决方案
2020/08/26 Python
世界最大的私人旅行指南出版商:孤独星球
2016/08/23 全球购物
在校生证明
2015/06/17 职场文书
python中super()函数的理解与基本使用
2021/08/30 Python