组件化开发
组件化开发注重重用,可以用作实现基础架构的技术方案。组件化开发实际上可以看作是一个不断对实体进行抽象的过程。先定义好一个基本类型,在基于定义好的类型进行实现。
1.组件注册
(1)全局组件注册语法
vue.component(组件名称, {
data: 组件数据,
template: 组件模板内容
})
(2)组件用法
<div id="app">
<button-counter></button-counter>
</div>
组件可重用,子组件之间的数据是独立的 ——props传值
(3)注意事项
- data必须是一个函数
- 组件模板内容必须是单个根元素
- 组件模板内容可以是模板字符串
- 组件命名方式
短横线方式
Vue.component ('my-component', { /*.........*/ })
驼峰方式 (只能在字符串模板中用驼峰方式,普通标签中,使用短横线方式引用)
Vue.component ('MyComponent', { /*.........*/ })
(4)局部组件注册 局部组件只能在注册它的父组件中使用
var ComponentA = { /*.........*/ }
var ComponentB = { /*.........*/ }
.
.
.
new Vue ({
el: '#app'
Component: {
'component-a': ComponentA,
'component-b': ComponentB,
.
.
.
}
})
2.组件间数据交互
(1)父组件向子组件传值
- 组件内部通过props接收传递过来的值
Vue.component ('menu-item', {
props: ['title']
template: '<div> {{ title }}'</div>
})
- 父组件通过属性将值传递给子组件
<menu-item title="来自父组件的数据"></menu-item>
<menu-item :title="title"></menu-item>
- props属性名规则
在props中使用驼峰形式,模板中需要使用短横线的形式
字符串形式中的模板中没有这个限制
- props属性值类型
- 字符串 String
数值 Number
布尔型 Boolean
数组 Array
对象 Object
(2)子组件向父组件传值
- 子组件通过自定义事件向父组件传递信息
<button v-on:click='$emit("enlarge-text")'>扩大字体</button>
- 父组件监听子组件事件
<menu-item v-on:enlarge-text='fontSize += 0.1'></menu-item>
- 子组件通过自定义事件向父组件传递信息
<button v-on:click='$emit("enlarge-text", 0.1)'>扩大字体</button>
- 父组件监听子组件的事件
<menu-item v-on:enlarge-text='fontSize += $event'></menu-item>
(3)非父子组件间传值(兄弟组件)
- 单独的事件中心管理组件间的通信
var eventHub = new Vue()
- 监听事件与销毁事件
eventHub.$on('add-todo', addTodo)
eventHub.$off('add-todo')
- 触发事件
eventHub.$emit('add-todo', id)
3.组件插槽
(1)作用
父组件向子组件传递模板内容
(2)组件插槽基本用法
- 插槽位置
Vue.Component('alert-box', {
template: '
<div class="demo-alert-box">
<strong>Error!</strong>
<slot></slot>
</div>
'
})
- 插槽内容
<alert-box>something bad happened</alert-box>
(3)具名插槽用法
- 插槽定义
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
- 插槽内容
<base-layout>
<h1 slot="header">标题内容</h1>
<p>主要内容1</p>
<p>主要内容2</p>
<p slot="footer">底部内容</p>
</base-layout>
(4)作用域插槽
插槽定义
<ul>
<li v-for="item in list" v-bind:key="item.id">
<slot v-bind:item="item">
{{ item.name }}
</slot>
</li>
</ul>
插槽内容
<fruit-list v-bind:list="list">
<template slot-scope="slotprops">
<strong v-if="slotprops.item.current">
{{ slotprops.item.text }}
</strong>
</template>
</fruit-list>