# 5.组件

1.组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以is 特性扩展。

2.组件注册

Vue.component('componentname',options)options是包含data、template、props、methods。注册之后使用该组件的方式有两种,通过is属性或者以组件名为标签

<div id="example">
  <my-componnet></my-componnet>
  <div is="my-component"></div>
</div>

通过 Vue 构造器传入的各种选项大多数都可以在组件里用。 data是一个例外,它必须是函数,并且这个函数返回的是一个对象。

3.构成组件

组件实例的作用域是孤立的。要让子组件使用父组件的数据,需要通过子组件的props选项。 字面prop,它的值是字符串 "1" 而不是number。如果想传递一个实际的number,需要使用v-bind,从而让它的值被当作 JavaScript 表达式计算

<comp some-prop="1"></comp> <comp v-bind:some-prop="1"></comp>

4.使用v-on绑定自定义事件

使用 $on(eventName) 监听事件 使用 $emit(eventName) 触发事件,触发事件直接写在模板中,事件名必须加斜杠转义,如下

Vue.component('todo', {
  props: ['title'],
  template: '<li>{{title}}<button @click="$emit(\'remove\')">X</button></li>',
})

WARNING

不能用$on 侦听子组件抛出的事件,而必须在模板里直接用 v-on 绑定

<div id="example">
  <p>{{total}}</p>
  <btncounterone @increament="increamentTotal"></btncounterone>
  <btncounterone @increament="increamentTotal"></btncounterone>
</div>

高级技巧

一般使用在组件库中,如element-ui

this.$parent.$emit('emit-by-parent')this.$refs.xxx.$emit('custom-event')

高级技巧

子组件内部任何值的改变都可以用$emit('input',val)对外传递,然后父组件用v-model来接收传递出来的值,如果有多个值传递,把这些值都封装在一个{}里面

  1. 父子组件

父组件:写在 html 里的内容,子组件:被嵌套的标签

父组件模板的内容在父组件作用域内编译,子组件模板的内容在子组件作用域内编译。父组件通过props向下传递数据给子组件,子组件通过events给父组件发送消息。子组件要显式地用 props 选项声明它期待获得的数据,props可以是[]{},父组件引用多个子组件则用{}来注册,如果方法里面要用到props的某一个,直接用this.xxx调用即可

  1. 单个slot及具名slot

slot标签定义在组件模板中,要插入内容的地方添加slot标签。应用了组件模板之后要插入的内容用组件名称包含即可,注意slot标签要被其他标签包围。

7.动态组件

通过使用保留的 <component> 元素,动态(要用v-bind)地绑定到它的is特性,我们让多个组件可以使用同一个挂载点,并动态切换。

<component :is="currentView"></componnet>

8.keep-alive

如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个keep-alive指令参数把要切换的组件包围起来

WARNING

keep-alive标签上添加includeexclude时,被匹配的组件内部要添加name选项。

<keep-alive>
  <componnet :is="currentView" />
</keep-alive>

9.组件命名格式

推荐用连字符,如果组件未经slot元素传递内容,你甚至可以在组件名后使用/使其自闭合(只在字符串模版中有效,字符串模板即是用反引号包含的模板``)

  1. 递归组件

组件在它的模板内可以递归地调用自己,不过,只有当它有name选项时才可以

  1. v-once

对低开销的静态组件使用v-once,即渲染一次后再 actived 从内存中取该组件。

Vue.component('once-component', {
  tempate: `<div v-once>...a lot of static content...</div>`,
})

12.name选项的作用

三个作用:递归使用自身、keep-alive标签匹配、vue devtools名字展示。