vue组件的基本使用:
- 定义组件
Vue.component(组件名, 组件配置项)
组件是可复用的vue实例, 所以vue实例怎么配置, 组件就怎么配置
注意点: 除了 el, el是根实例独有的属性, 用于指定视图, 但是可以指定 template
//全局组件
Vue.component('my-div', {
// 模板就是将来组件使用时, 展示出来的内容
template: `
<div>
<div>
你好哇
<a href='#'>嘎嘎</a>
</div>
<button>你好哇</button>
</div>
`
})
//局部组件
components: {
hello: {
template: `
<div>这是局部的hello组件</div>
`
}
}
- 使用组件
直接将定义的组件名, 可以当成 自定义的html标签 使用
//HTML
<div id="app">
<my-div></my-div>
</div>
注意点:
- 定义组件, 不要和 默认存在html标签 重名
- 定义组件, 模板内容, 必须有且只有一个根元素
组件的配置
- vue组件是可复用的 vue实例, 所以vue实例怎么配置, 组件就怎么配置
- 除了 el, el是 vue根实例的 独有属性, 指定视图, 一般组件配置的是 template
- data 在vue根实例中, 配置的直接是一个对象, 但是在组件中配置的是一个函数, 返回一个对象 (保证组件数据的独立性)
Vue.component('demo', {
// methods, data, template, 八个钩子函数, filter, computed
template: `
<div>
//这是demo组件
<button @click="fn">按钮</button>
<p>{{ count }}</p>
</div>
`,
data() {
// 每个组件实例在被初始化时, 都会执行 data 函数, 将返回的对象, 作为数据使用
// 每次执行 data 函数, 都会新创建一个 obj 对象, 可以保证每个组件实例的数据是独立的
// const obj = {
// count: 100
// }
// return obj
return {
count: 100
}
},
methods: {
fn () {
this.count++
}
}
})
组件通讯
组件中的数据定义在data中,data是一个函数,这个函数会返回一个对象
父传子
父传子利用props
**父组件代码**
<template>
<header-box :title-txt="showTitleTxt"></header-box>
</template>
<script>
import Header from './header'
export default {
name: 'index',
components: {
'header-box': Header
},
data () {
return {
showTitleTxt: '首页'
}
}
}
</script>
**子组件代码**
<template>
<header>
{{thisTitleTxt}}
</header>
</template>
<script>
export default {
name: 'header-box',
props: {
titleTxt: String
},
data () {
return {
thisTitleTxt: this.titleTxt
}
}
}
</script>
子传父
- 利用 o n 和 on和 on和emit 即子组件利用一个事件来触发$emit来传递出去一个事件及参数,然后在父组件里绑定这个事件,然后处理这个事件,获取传递的参数
- 子组件改变父组件传递的props(你会发现通过props可传递复杂类型数据,可以通过子组件改变数据内容,不推荐使用,因为vue是规定props是单向绑定)
*通过$on,$emit*
**父组件代码**
<template>
<div id="counter-event-example">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
</template>
<script>
import ButtonCounter from './buttonCounter'
export default {
name: 'index',
components: {
'button-conuter': ButtonCounter
},
data () {
return {
total: 0
}
},
methods: {
incrementTotal () {
this.total++
}
}
}
</script>
**子组件代码**
<template>
<button @click="incrementCounter">{{counter}}</button>
</template>
<script>
export default {
name: 'button-counter',
data () {
return {
counter: 0
}
},
metheds: {
incrementCounter () {
this.$emit('increment')
this.counter++
}
}
}
</script>
非父子
创建一个空的vue实例,然后挂载到当前的vue实例的原型上,然后一个组件进行 e m i t 传 递 事 件 以 及 需 要 传 递 的 数 据 。 在 另 一 个 组 件 那 里 就 可 以 进 行 使 用 emit传递事件以及需要传递的数据。在另一个组件那里就可以进行使用 emit传递事件以及需要传递的数据。在另一个组件那里就可以进行使用on来接受这个事件并处理这个传递参数
//在main.js中引入
let bus =new Vue()
Vue.prototype.bus = bus
使用过程中的有两个坑
- 在点击跳转的第一次之后值没有传递过去
- 从第二次开始传递过去,但是之后传递的都是累积重复传值重复次数是(n-1)次
坑一原因及解决方法
- 第一个原因是因为当我们还停留在第一个组件的时候,第二个组件还没有被created,所以emit事件是无法在另一个组件被on到的。
- 在组件跳转过程中两个组件是这样进行生命周期转换的 ,点击跳转-B组件created-B组件beforeMount-A组件beforeDestory-A组件destory
//解决方法:在A组件beforeDestroy里进行emit,这个时候B组件就已经created了
beforeDestroy () {
bus.$emit('get', {
item: this.item,
date: this.date
})
},
坑二原因及解决方法
因为emit里的事件会不断的累加,所以会按次数进行加载上去,要在on完之后要销毁才行
解决方法:
// 传值完成之后,在beforeDestroy里面使用off消除事件
beforeDestroy () {
bus.$off('get', this.myhandle)
},