组件
1.组件
vue组件,组件是一个可复用的功能模块,即将具有相同功能的模块抽取成一个组件,在需要的地方引用即可,体现了代码封装的思想。
2.注册组件
2·1全局注册组件
<div id="app">
<!-- 3、使用组件 -->
<my-header></my-header>
</div>
// 1、定义组件
const MyHeader = {
template: `<header>头部</header>`,
}
// 2、全局注册组件
Vue.component('my-header', MyHeader)
new Vue({
el: '#app'
})
2·2.局部注册组件
<div id="app">
<!-- 3、使用组件 -->
<my-header></my-header>
</div>
// 1、定义组件
const MyHeader = {
template: `<header>头部</header>`,
}
new Vue({
el: '#app',
// 2、局部注册组件
components: {
'my-header': MyHeader
}
})
2·2·1.多组件
<div id="app">
<!-- 3、使用组件 -->
<my-header></my-header>
<my-content></my-content>
<my-footer></my-footer>
</div>
// 1、定义组件
const MyHeader = {
template: `<header>头部</header>`,
}
const MyContent = {
template: `<div>内容</div>`,
}
const MyFooter = {
template: `<footer>底部</footer>`,
}
new Vue({
el: '#app',
// 2、局部注册组件
components: {
'my-header': MyHeader,
'my-content': MyContent,
'my-footer': MyFooter
}
})
2·2·2.嵌套组件
<div id="app">
<!-- 3、使用组件 -->
<my-header></my-header>
<my-content></my-content>
<my-footer></my-footer>
</div>
// 1、定义组件
const myBanner = { // a、定义子组件
template: '<div>轮播图</div>'
}
const myNav = {
template: '<div>导航</div>'
}
const MyHeader = {
template: `<header>头部</header>`,
}
const MyContent = { // 使用组件也是在此组件的内部
template: `<div class="content">
内容
<my-banner></my-banner>
<my-nav></my-nav>
</div>`,
components: { // 因为轮播图在content内容区域内,所以需要在此内部进行注册组件
"my-banner": myBanner,
"my-nav": myNav
}
}
const MyFooter = {
template: `<footer>底部</footer>`,
}
new Vue({
el: '#app',
// 2、局部注册组件
components: {
'my-header': MyHeader,
'my-content': MyContent,
'my-footer': MyFooter
}
})
2·2·3.抽离组件
<div id="app">
<!-- 3、使用组件 -->
<my-header></my-header>
</div>
<template id="header">
<header>
这里是头部
</header>
// 1、定义组件
const MyHeader = {
template: '#header'
}
new Vue({
el: '#app',
// 2、局部注册组件
components: {
'my-header': MyHeader
}
})
3.组件之间的传值
3.1父组件给子组件传值
- 父组件在调用子组件的地方 添加一个自定义的属性
- 属性的值就是你要传递给子组件的值
- 如果属性的值是number类型,boolean类型,或者是变量,需要使用到绑定属性
- 在子组件定义的地方 const Content = {}
- 给他添加一个选项 props const Content = { props: }
- props的值可以为数组以及对象
- 如果是数组, 元素则为父组件中自定义的属性名在子组件中就可以通过 你自定义的属性名 得到父组件传递过来的数据。
- 如果是对象,对象的形式有两种写法:
- 写法一:验证传递数据的有效性 ---- 如果数据类型不对,会报出警告,可以及时调整
- 写法二:既要验证数据的类型,又要设定属性的默认值,如果默认值是对象或者是数组,值为一个函数。
<div id="app">
<my-content test = "测试" :count="100" :flag="true" :tip="tip"/>
</div>
<template id="content">
<div>
{{ test }} -- {{ count }} --- {{ flag }} --- {{ tip }}
</div>
</template>
const Content = {
template: '#content';
props: {
test: String,
count: Number,
flag: Boolean,
tip: String
}
}
new Vue({
el: '#app',
data: {
tip: '提示'
},
components: {
'my-content': Content
}
})
3·2.子组件给父组件传值
子组件需要利用一个$emit(‘声明的事件’,‘需要发送的值’);而父组件的接收需要利用事件进行接收–也就是在子组件中进行事件的绑定,并且函数在声明中不能加(),在父组件的methos中,接收的函数需要有一个参数,这个参数也就是子组件传给父组件之间的值。
<div id="app">
<my-content @myevent="getData"/>
</div>
<template id="content">
<div>
我这里是内容区域
</div>
</template>
const Content = {
template: '#content',
mounted () {
this.$emit('myevent', 10000)
}
}
new Vue({
el: '#app',
data: {},
methods: {
getData (val) { // val为从子组件中获取到的值
console.log(val)
}
},
components: {
'my-content': Content
}
})
3·3.非父子组件之间的传值(兄弟组件传值)
非父子传值,需要有共同的父组件,作为中间仓库。
中央事件总线传值 1. const bus = new Vue()
2.在接收端通过 bus.$on(‘收信信号’, function (val) { })
3.在发送端通过 bus.$emit(‘收信信号’, val)
<div id="app">
<my-list></my-list>
<my-count></my-count>
</div>
<template id="list">
<ul>
<li>111<button @click="add">+1</button></li>
<li>222<button @click="add">+1</button></li>
<li>333<button @click="add">+1</button></li>
</ul>
</template>
<template id="count">
<div>
总量是:{{ num }}
</div>
</template>
const bus = new Vue()
const List = {
template: '#list',
methods: {
add () {
bus.$emit('count-event', 1)
}
}
}
const Count = {
template: '#count',
data () {
return {
num: 0
}
},
mounted () { // 一般情况下接收都使用 生命周期钩子函数
bus.$on('count-event', (val) => {
console.log(val)
this.num += val
})
}
}
new Vue({
el: '#app',
components: {
'my-list': List,
'my-count': Count
}
})