0x9 精读Vue官方文档 – 组件基础

精读 Vue 官方文档系列 ?

组件的本质与作用

  • 组件实际上就是一个独立的 Vue 实例。
  • 组件的作用就是为了功能与 UI 的复用。

data 必须是一个函数

为了避免多个组件共享同一份响应式数据,Vue 特意规定组件的 data 选项必须是一个函数,用来返回独立的对象。

var common = {count:0};
Vue.component('comp-1', {
    data(){
        return common;
    },
    template:`<button @click="count++">click count items {{count}}</button>`
});
Vue.component('comp-2', {
    data(){
        return common;
    },
    template:`<button @click="count++">click count items {{count}}</button>`
});
复制代码

例如上例的两个组件中虽然 data 属性是一个函数,但是返回的仍然是同一个对象的引用,所以此时两个组件共享同一份响应式数据。

组件的组织

应用 是通过组件树的嵌套组织体现的。

image.png

例如,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。

组件的注册主要有:

  • 全局注册:Vue.component(name, option)
  • 局部注册: {components:{}}

通过 Prop 向子组件传递数据

如果传递的是静态数据/静态字符串那么直接在组件上使用普通的 HTML Attribute 即可。

<comp-1 name="comp-1" title="comp-1 component example"></comp-1>
复制代码

但是如果要传递的数据是动态数据/响应式数据那么必须要使用 v-bind 指令进行属性的绑定。

<comp-1 :post="dataItem.post"></comp-1>
复制代码

其中 dataItem.post 是一个变量。

单个根元素

组件必须要有一个唯一的根节点来包裹所有内容。

组件的事件监听

  1. 父组件通过 v-on 指令来监听子组件发出的事件。
  2. 子组件内部通过 $emit(eventName[,arguments]) 来发出事件并传递事件参数。
  3. 事件可以携带要传递的值(事件参数),在父组件的模板中可以通过专门的 $event 来获取子组件传递的值。
<comp-1 v-on:triggel="count+=$event"></comp-1>
复制代码

你也可以指定一个事件响应处理的方法。

v-model 的原理

v-model 的实现是建立在组件事件通信的基础上。
v-model 是一个语法糖,它默认绑定了组件的 input 事件,接收事件携带的值,然后变更组件的 value 属性的值,从而实现数据的双向绑定。

<input v-model="searchText">

<!--等价于:-->

<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>
复制代码

slot 插槽

<slot>, [slɒt] 元素是 Vue 内置的组件之一。
<slot> 元素可以用来接收和分发组件起始标签结束标签之间的内容。

<alert-box>
  Something bad happened. 
</alert-box>
复制代码
Vue.component('alert-box', {
  template: `
    <div class="demo-alert-box">
      <strong>Error!</strong>
      <slot></slot>
    </div>
  `
})
复制代码

动态组件

<component> 元素也是 Vue 内置的组件之一。
<component> 元素用来实现动态组件技术

我们可以将 <component> 理解成是一个空的组件容器,它会基于 :is 属性传递的组件名称来动态渲染对应的组件。因此也可以将其理解成组件的占位符

<component> 组件支持像一般组件那样绑定属性、绑定事件,这些事件与属性会自动传递到要实际渲染的组件上。

<component
    title="title"
    :is="componentName"
    :post="dataItem.post"
    v-on:triggel="count += $event"
></component>

<!--等价于-->

<component-name
    title="title"
    :post="dataItem.post"
    v-on:triggel="count += $event"
></component>
复制代码

解析 DOM 模板时的注意事项

有些 HTML 标签对其内部的子元素有着严格的限制要求,例如<table> 只能是 <tr><ul> 只能是 <li><select> 只能是 <option> 等。如果我们用自定义组件去替代此类元素的类容,就会被浏览器解析为无效的内容提升到外部,从而导致最终渲染结果出错。

幸好,动态组件技术的 is attribute 给了我们一个变通方法的启发:

<table>
  <tr is="blog-post-row"></tr>
</table>
复制代码

这种问题只会出现在将 自定义组件 使用在了一个 HTML 文件中(例如 public.html 中),而且所处的父元素对其内部的子元素还有着严格的要求。所以如果我们使用的是 “单文件组件”、“模板字符串”、“脚本模板” 的任一种方式都不会出现此类问题:

  • 字符串 (例如:template: ‘…’)
  • 单文件组件 (.vue)
  • <script type="text/x-template">

因为它们都会事先通过 Vue 编译器进行编译输出,而不是事先固定存在在一个 html 文件中直接被浏览器加载并解析。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享