Vue 学习笔记之入门2

2017-03-02  本文已影响27人  懒人成长

第一篇入门文章中对 Vue.js 有了一个初步的认识,并且能够使用已有的知识完成简单实例的开发尝试——Todo List,如果有兴趣可以到我的Github中查看,感觉小有成就感。

本文则继续入门学习,学习下Vue中重要的内容——组件

概述

组件是Vue中非常重要的部分,可以用来扩展HTML元素或者用于封装可复用代码,给开发带来更多的灵活性。

注册

组件在使用之前必须要先完成注册,注册有两种方式,全局注册和局部注册,通过全局注册的方式可以使组件在任意Vue实例中使用,而使用局部这次的方式则注册的组件只能用于当前Vue实例中。

全局注册

通过Vue.component(tagName, options)的方式来注册一个全局的组件。

// 注册
Vue.component('my-component', {
  template: '<div>A custom component!</div>'
})
// 创建根实例
new Vue({
  el: '#example'
})

// 使用
<div id="example">
  <my-component></my-component>
</div>

局部注册

在Vue实例创建时通过components属性来注册仅能在当前实例中使用的组件。

var Child = {
  template: '<div>A custom component!</div>'
}
new Vue({
  // ...
  components: {
    // <my-component> 将只在父模板可用
    'my-component': Child
  }
})

注意

由于HTML的一些限制,一些特殊的HTML标签对包裹的标签进行了限制,这使得使用自定义组件时,若添加在受限的标签内部的话,就会出现不能解析的情况,导致无效,例如<ul><ol><table><select>

在这种情况下,可以使用is属性来解决。

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

应当注意,如果您使用来自以下来源之一的字符串模板,这些限制将不适用:

因此,有必要的话请使用字符串模版。

父子组件间通信

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

父子组件通信.png

props

组件实例的作用域是独立的,可以使用props属性来对父组件开放自定义属性。

Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 就像 data 一样,prop 可以用在模板内
  // 同样也可以在 vm 实例中像 “this.message” 这样使用
  template: '<span>{{ message }}</span>'
})

// 父组件中使用子组件
<child message="hello!"></child>

// 父组件中使用v-bind的方式绑定props
<child :message="hello!"></child>

由于HTML中不区分大小写,若组件中定义含大写字符的属性名称,则在父组件中使用时需要将大写字母转成小写,并用-连接单词。

props是单向绑定的,父组件的数据变更会传递到子组件中,但是子组件的变更并不能传递回父组件。另外,每次父组件的变更都会带来子组件中所有props的更新。

props可以设定验证规则,Vue提供了一些默认的规则,当然也支持自定义验证规则。

Vue.component('example', {
  props: {
    // 基础类型检测 (`null` 意思是任何类型都可以)
    propA: Number,
    // 多种类型
    propB: [String, Number],
    // 必传且是字符串
    propC: {
      type: String,
      required: true
    },
    // 数字,有默认值
    propD: {
      type: Number,
      default: 100
    },
    // 数组/对象的默认值应当由一个工厂函数返回
    propE: {
      type: Object,
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        return value > 10
      }
    }
  }
})

events

父组件与子组件约定好事件名称,父组件使用$on(eventName)在自己的作用域中监听事件是否触发,子组件使用$emit(eventName)来触发事件,当父组件监听到事件后,就可以对子组件传递来的数据进行处理,更新自己的数据属性了。

<div id="counter-event-example">
  <p>{{ total }}</p>
  <button-counter v-on:increment="incrementTotal"></button-counter>
  <button-counter v-on:increment="incrementTotal"></button-counter>
</div>

Vue.component('button-counter', {
  template: '<button v-on:click="increment">{{ counter }}</button>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
    increment: function () {
      this.counter += 1
      this.$emit('increment')
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal: function () {
      this.total += 1
    }
  }
})

Slot内容分发

为了解决父组件内容与子组件自己模板混合的问题,Vue引入<slot>标签,通过该标签,就可以在子组件中定义承载父组件内容的插槽,当父组件对应位置有内容时,渲染父组件内容,没有内容时使用子组件自己定义的内容。

// 子组件 my-component 模板:
<div>
  <h2>我是子组件的标题</h2>
  <slot>
    只有在没有要分发的内容时才会显示。
  </slot>
</div>

// 父组件模版:
<div>
  <h1>我是父组件的标题</h1>
  <my-component>
    <p>这是一些初始内容</p>
    <p>这是更多的初始内容</p>
  </my-component>
</div>

// 渲染结果:
<div>
  <h1>我是父组件的标题</h1>
  <div>
    <h2>我是子组件的标题</h2>
    <p>这是一些初始内容</p>
    <p>这是更多的初始内容</p>
  </div>
</div>

可以通过对slot添加name属性的方式对其命名,这样就可以在一个模板中插入多个slot

// 子组件模板
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

// 父组件模版:
<app-layout>
  <h1 slot="header">这里可能是一个页面标题</h1>
  <p>主要内容的一个段落。</p>
  <p>另一个主要段落。</p>
  <p slot="footer">这里有一些联系信息</p>
</app-layout>

// 渲染结果为:
<div class="container">
  <header>
    <h1>这里可能是一个页面标题</h1>
  </header>
  <main>
    <p>主要内容的一个段落。</p>
    <p>另一个主要段落。</p>
  </main>
  <footer>
    <p>这里有一些联系信息</p>
  </footer>
</div>

特别注意事项

1. 字面量语法和动态语法

<!-- 传递了一个字符串"1" -->
<comp some-prop="1"></comp>

<!-- 传递实际的数字 -->
<comp v-bind:some-prop="1"></comp>

前者直接以字符串的形式进行了数据传递,后者则将值视为表达式计算后传递。

2. 编写可服用组件

Vue 组件的 API 来自三部分 - props, events 和 slots :

3.组件命名规则

上一篇下一篇

猜你喜欢

热点阅读