HTML5技术

Vue.js60分钟组件快速入门(下篇) - keepfool

字号+ 作者:H5之家 来源:博客园 2016-07-03 14:04 我要评论( )

概述 上一篇我们重点介绍了组件的创建、注册和使用,熟练这几个步骤将有助于深入组件的开发。另外,在子组件中定义props,可以让父组件的数据传递下来,这就好比子组件告诉父组件:“嘿,老哥,我开通了一个驿站,你把东西放到驿站我就可以拿到了。” 今天我

概述

上一篇我们重点介绍了组件的创建、注册和使用,熟练这几个步骤将有助于深入组件的开发。另外,在子组件中定义props,可以让父组件的数据传递下来,这就好比子组件告诉父组件:“嘿,老哥,我开通了一个驿站,你把东西放到驿站我就可以拿到了。”

今天我们将着重介绍slot和父子组件之间的访问和通信,slot是一个非常有用的东西,它相当于一个内容插槽,它是我们重用组件的基础。Vue的事件系统独立于原生的DOM事件,它用于组件之间的通信。

本文的主要内容如下:

  • 组件的编译作用域
  • 在组件template中使用<slot>标签作为内容插槽
  • 使用$children, $refs, $parent 实现父子组件之间的实例访问
  • 在子组件中,使用$dispatch向父组件派发事件;在父组件中,使用$broadcast向子组件传播事件
  • 结合这些基础知识,我们一步一步实现一个CURD的示例
  • Demo和源代码已放到GitHub,如果您觉得本篇内容不错,请点个赞,或在GitHub上加个星星!

    编译作用域

    尽管使用组件就像使用一般的HTML元素一样,但它毕竟不是标准的HTML元素,为了让浏览器能够识别它,组件会被解析为标准的HTML片段,然后将组件的标签替换为该HTML片段。

    <div> <my-component> </my-component> </div> <template> <div> <h2>{{ msg }}</h2> <button v-on:click="showMsg">Show Message</button> </div> </template> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', components: { 'my-component': { template: '#myComponent', data: function() { return { msg: 'This is a component!' } }, methods: { showMsg: function() { alert(this.msg) } } } } })

    这段代码定义了一个my-component组件,<my-component><my-component>不是标准的HTML元素,浏览器是不理解这个元素的。
    那么Vue是如何让浏览器理解<my-component><my-component>标签的呢?(下图是我个人的理解)

    image

    在创建一个Vue实例时,除了将它挂载到某个HTML元素下,还要编译组件,将组件转换为HTML片段。
    除此之外,Vue实例还会识别其所挂载的元素下的<my-component>标签,然后将<my-component>标签替换为HTML片段。

    实际上浏览器仍然是不理解<my-component>标签的,我们可以通过查看源码了解到这一点。

    image

    组件在使用前,经过编译已经被转换为HTML片段了,组件是有一个作用域的,那么组件的作用域是什么呢?
    你可以将它理解为组件模板包含的HTML片段,组件模板内容之外就不是组件的作用域了。
    例如,my-component组件的作用域只是下面这个小片段。

    image

    组件的模板是在其作用域内编译的,那么组件选项对象中的数据也应该是在组件模板中使用的。
    考虑下面的代码,在Vue实例和组件的data选项中分别追加一个display属性:

    new Vue({ el: '#app', data: { display: true }, components: { 'my-component': { template: '#myComponent', data: function() { return { msg: 'This is a component!', display: false } }, methods: { showMsg: function() { alert(this.msg) } } } } })然后在my-component标签上使用指令v-show="display",这个display数据是来源于Vue实例,还是my-component组件呢? <div> <my-component v-show="display"> </my-component> </div>

    答案是Vue实例。

    至此,我们应该认识到组件的作用域是独立的:

    父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译

    通俗地讲,在子组件中定义的数据,只能用在子组件的模板。在父组件中定义的数据,只能用在父组件的模板。如果父组件的数据要在子组件中使用,则需要子组件定义props。

    使用Slot

    为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个处理称为内容分发,Vue.js 实现了一个内容分发 API,使用特殊的 <slot> 元素作为原始内容的插槽。

    如果不理解这段话,可以先跳过,你只要知道<slot>元素是一个内容插槽。

    单个Slot

    下面的代码在定义my-component组件的模板时,指定了一个<slot></slot>元素。

    <div> <my-component> <h1>Hello Vue.js!</h1> </my-component> <my-component> </my-component> </div> <template> <div> <h2>This is a component!</h2> <slot>如果没有分发内容,则显示slot中的内容</slot> <p>Say something...</p> </div> </template> <script src="js/vue.js"></script> <script> Vue.component('my-component', { template: '#myComponent' }) new Vue({ el: '#app' }) </script>

    这段代码运行结果如下:

    image

    第一个<my-component>标签有一段分发内容<h1>Hello Vue.js!</h1>,渲染组件时显示了这段内容。

    image

    第二个<my-component>标签则没有,渲染组件时则显示了slot标签中的内容。

    View Demo

    指定名称的slot

    上面这个示例是一个匿名slot,它只能表示一个插槽。如果需要多个内容插槽,则可以为slot元素指定name属性。

    多个slot一起使用时,会非常有用。例如,对话框是HTML常用的一种交互方式。
    在不同的运用场景下,对话框的头部、主体内容、底部可能是不一样的。

    image

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • Omi树组件omi-tree编写指南 - 【当耐特】

      Omi树组件omi-tree编写指南 - 【当耐特】

      2017-05-02 15:04

    • 在Delphi下使用迅雷APlayer组件进行免注册开发 - Delphi力量

      在Delphi下使用迅雷APlayer组件进行免注册开发 - Delphi力量

      2017-04-28 15:00

    • JS组件系列——自己动手封装bootstrap-treegrid组件 - 懒得安分

      JS组件系列——自己动手封装bootstrap-treegrid组件 - 懒得安分

      2017-04-28 14:02

    • 表格组件神器:bootstrap table详细使用指南 - 流浪的诗人

      表格组件神器:bootstrap table详细使用指南 - 流浪的诗人

      2017-04-13 09:00

    网友点评
    )