当我坐在那架破旧古钢琴旁边的时候,我对 最幸福的国王也不羡慕。—— 海顿

vue学习---组件(一)

组件

什么是组件?


组件是Vue最强大的功能之一.它们可以帮助你扩展基础的HTML元素,封装为可重用的代码.在较高层面上,组件是经过Vue编译后赋予了一些额外特性的自定义元素.在一些情况下,组件也可以是原生HTML元素的形式,以特殊的is属性扩展.

使用组件


注册

之前已经学过创建一个vue实例的方式:

new Vue({
  el: '#some-element',
  // options
})

注册成全局组件,我们可以使用Vue.component(tagName, options).例如:

Vue.component('my-component', {
  // options
})

注意:对于自定义元素标签名,Vue不强制要求遵循 W3C 规则(小写,并且包含一个'-'连字符),尽管遵循这个规则比较好。

一但注册后,组件便可以作为一个自定义元素在实例模板中使用(<my-component></my-component>).但要确保在初始化根实例之前注册该组件,以下是完整例子:

<div id="example">
  <my-component></my-component>
</div>
// register
Vue.component('my-component', {
  template: '<div>A custom component!</div>'
})
// create a root instance
new Vue({
  el: '#example'
})

最终会渲染成:

<div id="example">
  <div>A custom component!</div>
</div>

局部注册

不必在全局注册每个组件.可以通过使用组件实例选项进行注册,使组件仅在另一个实例/组件的作用域中可用(父组件):

var Child = {
  template: '<div>A custom component!</div>'
}
new Vue({
  // ...
  components: {
    // <my-component> will only be available in parent's template
    'my-component': Child
  }
})

这种封装也适用于其它可注册的 Vue 功能,如指令。

DOM模板解析说明

当使用DOM作为模板时(例如用el选项来挂载将要展示的内容),你将会受到一些HTML固有的限制,因为Vue只有在浏览器正确解析HTML的前提下才能获取模板内容. 尤其是像<ul>,<ol>,<table>,<select>这些只能出现在指定元素内部的标签. 比如<option>只能出现在其它元素内部.

当在自定义元素中使用这些带有限制的元素很可能就会导致问题,比如:

<table>
  <my-row>...</my-row>
</table>

自定义组件<my-row>被认为是无效的内容,会导致最终的渲染结果出错.当然,Vue提供了一个is的特殊属性(前面有提到)作为变动的方案。

<table>
  <tr is="my-row"></tr>
</table>

需要注意的是,如果使用以下几种字符串模板的来源,则不会有上述限制:

  • <script type="text/x-template">

  • JavaScript内联模版字符串

  • .vue 组件

所以还是推荐尽量使用上述几种方式😃

data 必须是函数

大多数能用在Vue构造器中的选项(options)也适用于component(组件)注册中,除了一个例外情况,那就是Data必须是一个函数,而不是一个键值对数据对象. 实际上,如果你尝试以下代码:

Vue.component('my-component', {
  template: '<span>{{ message }}</span>',
  data: {
    message: 'hello'
  }
})

Vue会直接中断执行并在控制台弹出警告--组件实例的data属性必须是一个函数.我们通过以下几个小例子来理解Vue中为什么会有这个规则限制:

<div id="example-2">
  <simple-counter></simple-counter>
  <simple-counter></simple-counter>
  <simple-counter></simple-counter>
</div>
var data = { counter: 0 }
Vue.component('simple-counter', {
  template: '<button v-on:click="counter += 1">{{ counter }}</button>',
  // data 是一个函数,因此 Vue 不会报警告,
  // 但是我们为每一个组件返回了同一个对象引用
  data: function () {
    return data
  }
})
new Vue({
  el: '#example-2'
})

在线DEMO

由于这三个组件共享了同一个 data , 因此每增加一次计数会影响所有组件!我们可以通过为每个组件返回新的 data 对象来解决这个问题:

data: function () {
  return {
    counter: 0
  }
}

现在每个 counter 都有它自己内部的状态了:

在线DEMO

构造组件

组件意味着协同工作,最常见的父子组件的关系中:组件A会在其模板中使用组件B.“老子和儿子”之间不可避免的需要相互通信。父组件需要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件。然而,通过定义良好的接口尽可能保持父子组件解耦是非常重要的。这保证了每个组件的代码可以在相对隔离的环境中编写和理解,从而使它们变得更具可维护性和可重用性。

在vue.js中,父子组件的关系可以概括为props down, events up.父组件通过props向下传递数据给子组件,子组件通过events给父组件发送消息。

让我们看下它们是如何工作的:

分享

分享本文章

文章来源
118310

2017-01-01

标签

vue

right left pencil2 css3 node design eye tags search rss back user pacman film