Vue 学习笔记 - 基础(下) 组件基础
基本示例
定义一个名为 button-counter
的新组件
Vue.component('button-counter', {
data: function () {
return {count: 0}
},
template: '<button v-on:click="count++">大爷你点了我 {{ count }} 次.</button>'
})
使用 button-counter
组件
<div id="app">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script>
new Vue({ el: '#app' })
</script>
- 组件与普通标签语法一致
- 组件的参数与
new Vue
接收相同的选项。各别el
这种根实例特有的选项除外。
组件的复用
- 组件目的就是复用(每个组件都是一个
单独的实例
) - 组件的
data
参数是一个函数(猜是为了函数作用域吧,这样各实例才能维护自己独立的一份数据)
组件的组织
注册方式 | 说明 |
---|---|
全局注册 | 用Vue.component 静态方法,注册执行后再实例化的所有实例 都有此组件. |
局部注册 | new Vue({ components : {...}}) 实例化时components 参数注册,只在本实例内生效。 |
通过 Prop 向子组件传递数据
定义组件中,接受了title
参数
Vue.component('book', {
props: ['title'],
template: '<p>我喜欢看《{{ title }}》</p>'
})
title
作为一个自定义属性使用
<book title="《三国》"></book>
<book title="《水浒》"></book>
<book title="《西游》"></book>
结果:
<p>我喜欢看《三国》</p>
<p>我喜欢看《水浒》</p>
<p>我喜欢看《西游》</p>
如果我们有一书单,遍历一下:
new Vue({
el: '#app',
data: {
bookList: [{ id: 1, title: '三国演绎'},{ id: 2, title: '水浒传'},{ id: 3, title: '西游记'}]
}
})
<book v-for="book in bookList" :key="book.id" :title="book.title"></book>
单个根元素
组件必须要有一个根元素,所有的内容都包在根根元素下面。
<div>
<p>我的书单</p>
<p>书名:{{title }}</p>
</div>
监听子组件事件
vm.$emit
( eventName
, […args]
)
Vue内键方法,触发当前实例上的事件。附加参数都会传给监听器回调。详细说明见文档
在组件上使用 v-model
引子:以下两段等价
<input v-model="searchText">
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
在组件上用v-model
,Vue内部相当于这样处理:
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
所以我们自定义组件内的input
要:
- 将自己的
value
属性绑到自定义组件的value
这个prop
上 - 在自己的
input
事件被触发时,抛个自定义的input
事件,把新的值传出去
Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
建议先学完基础篇再看自定义事件
通过插槽分发内容
组件标签中的内容,会替换<slot></slot>
<div id="app">
<book>666</book>
<book>999</book>
</div>
<script>
Vue.component('book', {
template: "<div>这段红色部分<span style='color:#f00'><slot></slot></span>是使用组件时填写的标签内容</div>"
})
new Vue({el: '#app'})
</script>
建议先学完基础篇再看插槽详情
动态组件
<component>
元素通过is
属性来实现动态显示指定组件
通过已注册的组件名字
<div id="app">
<button v-for="n in ['a','b','c']" v-on:click="currentTab = 't-'+n">标签{{n}}</button>
<component v-bind:is="currentTab"></component>
</div>
<script>
new Vue({
el: "#app",
data: {
currentTab: "t-a"
},
components:{
"t-a":{ template : "<div>这是a标签页。aaaaaaaaaaaaaaaa</div>"},
"t-b":{ template : "<div>这是b标签页。bbbbbbbbbbbbbbbb</div>"},
"t-c":{ template : "<div>这是c标签页。cccccccccccccccc</div>"}
}
});
</script>
通过组件选项对象
<div id="app">
<button v-for="tab in tabs" v-on:click="currentTab = tab">{{tab.name}}</button>
<component v-bind:is="currentTab.component"></component>
</div>
<script>
var tabs =[
{name: "标签a", component:{template : "<div>这是a标签页。aaaaaaaaaaaaaaaa</div>"}},
{name: "标签b", component:{template : "<div>这是b标签页。bbbbbbbbbbbbbbbb</div>"}},
{name: "标签c", component:{template : "<div>这是c标签页。cccccccccccccccc</div>"}}
];
new Vue({
el: "#app",
data: {currentTab: tabs[0], tabs: tabs}
});
</script>
到目前为止,关于动态组件你需要了解的大概就这些了,如果你阅读完本页内容并掌握了它的内容,我们会推荐你再回来把动态和异步组件读完。
解析 DOM 模板时的注意事项
<ul>
、<ol>
、<table>
和<select>
内部限制只能放特定元素。自定组件可以通过 is
指定自定义组件book
<table>
<tr is="book"></tr>
</table>
需要注意的是如果我们从以下来源
使用模板的话,是不存在限制
:
- 字符串 (例如:
template: '...'
) - 单文件组件 (
.vue
) <script type="text/x-template">
参考资料
Vue 官方教程基数篇 - 本笔记的学习对象
Vue 官方CLI 官方文档
Vue 官方API 参考
Vue 官方API文档 - 生命周期钩子
笑虾:vue-devtools 编译安装
笑虾:Vue CLI 学习笔记
笑虾:Vue 学习笔记 - 基础(上)
笑虾:Vue 学习笔记 - 基础(中)
笑虾:Vue 学习笔记 - 基础(下)组件基础
笑虾:Vue 学习笔记 - 深入了解组件