详解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 相关文章推荐
jQuery EasyUI API 中文文档 - ComboGrid 组合表格
Oct 13 Javascript
javascript得到当前页的来路即前一页地址的方法
Feb 18 Javascript
jquery解析xml字符串简单示例
Apr 11 Javascript
对new functionName()定义一个函数的理解
May 22 Javascript
js预加载图片方法汇总
Jun 15 Javascript
javascript控制层显示或隐藏的方法
Jul 22 Javascript
jquery简单实现幻灯片的方法
Aug 03 Javascript
理解javascript中的Function.prototype.bind的方法
Feb 03 Javascript
webpack4的迁移的使用方法
May 25 Javascript
微信小程序实现指定显示行数多余文字去掉用省略号代替
Jul 25 Javascript
微信小程序实现跑马灯效果
Oct 21 Javascript
vue实现input输入模糊查询的三种方式
Aug 14 Vue.js
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
PHP类中Static方法效率测试代码
2010/10/17 PHP
PHP XML和数组互相转换详解
2016/10/26 PHP
Yii核心验证器api详解
2016/11/23 PHP
PHP实现的登录页面信息提示功能示例
2017/07/24 PHP
Laravel 5.5官方推荐的Nginx配置学习教程
2017/10/06 PHP
JS中的substring和substr函数的区别说明
2013/05/07 Javascript
如何使用jQUery获取选中radio对应的值(一句代码)
2013/06/03 Javascript
js控制表单操作的常用代码小结
2013/08/15 Javascript
js用正则表达式来验证表单(比较齐全的资源)
2013/11/17 Javascript
JS实现仿FLASH效果的竖排导航代码
2015/09/15 Javascript
理解javascript定时器中的单线程
2016/02/23 Javascript
Javascript 6里的4个新语法
2016/08/25 Javascript
理解AngularJs篇:30分钟快速掌握AngularJs
2016/12/23 Javascript
bootstrap Validator 模态框、jsp、表单验证 Ajax提交功能
2017/02/17 Javascript
JavaScript实现兼容IE6的收起折叠与展开效果实例
2017/09/20 Javascript
详解基于原生JS验证表单组件xy-form
2019/08/20 Javascript
javascript实现前端input密码输入强度验证
2020/06/24 Javascript
python实现汉诺塔递归算法经典案例
2021/03/01 Python
Python实现字符串格式化输出的方法详解
2017/09/20 Python
mac安装pytorch及系统的numpy更新方法
2018/07/26 Python
Python文件操作基础流程解析
2020/03/19 Python
Python学习之os模块及用法
2020/06/03 Python
python mock测试的示例
2020/10/19 Python
使用Python快速打开一个百万行级别的超大Excel文件的方法
2021/03/02 Python
屈臣氏越南官网:Watsons越南
2021/01/14 全球购物
银行实习的自我鉴定
2013/12/10 职场文书
合同专员岗位职责
2013/12/18 职场文书
优秀毕业生推荐信范文
2014/03/07 职场文书
《蚕姑娘》教学反思
2014/04/15 职场文书
煤矿安全知识竞赛活动总结
2014/07/07 职场文书
班级课外活动总结
2014/07/09 职场文书
2015年妇幼保健工作总结
2015/05/19 职场文书
电子表的操作介绍说明书
2019/10/28 职场文书
销区经理年终述职报告模板
2019/11/28 职场文书
Python基础之元组与文件知识总结
2021/05/19 Python
Vue3中的Refs和Ref详情
2021/11/11 Vue.js