如何你没有下面几个问题,那这篇文章真的是一无是处。
- 组件的创建与引用
- 父组件与子组件的交互
- 组件与组件间的交互
0.1 谈谈组件
我一开始是对组件有着深深的误解,我个人直接把web中的组件强行等于安卓中的button啊,listview啊,其实是错的。组件的划分,并没有那么严格,一个按钮可以是一个组件,页面的导航栏可以是一个组件。最好是一个页面中,只包含尽可能少的大组件,在大组件中,尽可以包含功能相近的小组件。
导航栏可以是一个大组件,内容可以是一个大组件,导航栏里又可以包含logo,具体栏目的导航。
上面都是我个人的理解。
1 组件的创建与引用
这里只谈单文件系统,一个.vue就是一个组件。
在单文件系统中,一个*.vue文件包含script、style、template标签。那么,如何在a.vue中,用b.vue中的组件呢?
import view from 'xxx/xxx/xxx.vue'
import Vue from 'vue';
Vue.component('你喜欢的标签名',view)
这样在a的template中,就可以这么使用b了
<template>
<你喜欢的标签名></你喜欢的标签名>
<template>
然后呢,由此,就会扯出一坨别的问题
- 那怎么才能向子组件里传数据啊?
- 那收到父组件的数据,子组件里要怎么用呢?
- 那完成了一些操作,子组件要怎么报告给父组件呢?
答:我也不知道 见第二章。
2. 组件与组件间的交互
- 那怎么才能向子组件里传数据啊? prop
- 那收到父组件的数据,子组件里要怎么用呢? 插槽
- 那完成了一些操作,子组件要怎么报告给父组件呢? 如果只是简单的,用自定义事情,复杂的,可以使用第三章提到的vuex。
其实官方文档都有这些的使用,地址点我。
但是我这个更是读完后的一个重点啊!我觉得我理一下更方便自己的理解与使用~
2.1 prop
实在是觉得官网的中文教程写的好,花10分钟就可以看完了,真的不想单纯的复制过来水,没意思。就再补充下单文件下的定义吧:
<template>
<span>{{ message }}</span>
</template>
<script>
export default {
// 声明 props
props: ['message'],
// 就像 data 一样,prop 也可以在模板中使用
}
<style >
</style>
2.2 插槽
补充一下:怎么理解插槽。
如果子组件要接收父组件的内容显示,要放在哪里显示呢?
子组件要怎么使用呢?
于是就引出了<slot>这个标签,见b.vue,它用作接收父组件中的数据
如a.vue(发数据,和slot无关)
<template>
<div>
<h1>我是父组件的标题</h1>
<my-component>
<p>这是一些初始内容</p>
<p>这是更多的初始内容</p>
</my-component>
</div>
</template>
b.vue(收数据)
<div>
<h2>我是子组件的标题</h2>
<slot>
只有在没有要分发的内容时才会显示。
</slot>
</div>
最后就显示成了:
<div>
<h1>我是父组件的标题</h1>
<div>
<h2>我是子组件的标题</h2>
<p>这是一些初始内容</p>
<p>这是更多的初始内容</p>
</div>
</div>
slot还可以指定名字来接收数据。具名插槽
更详细内容看官网
2.3 事件
使用自定义事件做一些子组件与父组件的交互
- on(eventName) 监听事件
- emit(eventName) 触发事件
我把官网例子搞过来切割一下,并做点详细的解释吧~
父组件的template:
<div id="counter-event-example">
<p>{{ total }}</p>
<!--increment是事件的名字,而引号后面的incrementTotal是函数名-->
<!-- button-counter就是一个子组件-->
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
可以看出,父组件订阅了increment这个事件,那么自然,字组件就一定触发了increment这个事件。
下面还是父组件的js:
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
子组件的template:
<button v-on:click="incrementCounter">{{ counter }}</button>
子组件的js:
data: function () {
return {
counter: 0
}
},
methods: {
incrementCounter: function () {
this.counter += 1
this.$emit('increment')
}
}
从代码中可以看出,子组件的click可以触发incrementcounter函数,在这个函数里,又发射了increment事件。
更多细节请参考官网
3 组件与组件之间的通迅
如果:
- a.vue中的子组件想与b.vue中的子组件的通迅
- a.vue想与b.vue中的子组件的通迅
- a.vue中的子组件想与b.vue通迅
- a.vue的子组件的子组件想与b.vue的子组件通迅
- ......
想想就烦啊,这个时候,就要全局的vuex,就是状态管理~
这个坑值得另开一篇文章讲,等一个二。