Vue 组件
Vue组件 其实是一个html、css、js等的一个聚合体。
组件定义:
Vue.extend() 得到的是一个构造函数VueComponent( options )
options即我们之前在new Vue( options )
Vue.component('VueHello', Hello )
const Hello = Vue.extend({ // 组件选项
template: `
<div>
<p> Vue Hello</p>
</div>
`,
})
组件注册
- 全局注册
- 局部注册
<div id="app">
<Demo></Demo>
<Hello></Hello>
</div>
//js代码
Vue.component('Hello',{
template: '<div> 全局组件注册简写 </div>',
data () { //data为啥是一个函数?
return {
}
}
})
new Vue({
el: '#app',
data: {},
components: {
'Demo': {
template: '<div> 局部注册简写 </div>'
}
},
})
data为啥是一个函数?
因为组件是一个独立的整体,我们希望它的数据也是独立的,所以使用函数会有独立作用域,返回值必须是一个对象,因为要经过数据劫持处理。
父子组件通信
- 在父组件模板中,将父组件数据赋值给子组件的自定义属性
- 在子组件模板中,通过 props 属性来接收绑定在自己身上的自定义属性
<div id="app">
<Father/>
</div>
<template id="father">
<div>
<h3> 父组件 </h3>
<!-- 在父组件模板中,使用单项数据绑定,将父组件数据赋值给子组件的自定义属性 -->
<Son :money = "money"/>
</div>
</template>
<template id="son">
<div>
<h5> 子组件 </h5>
<p> 我老爸给了我: {{ money }} </p>
</div>
</template>
js代码
Vue.component('Father',{
template: '#father',
data () {
return {
money: 2000
}
}
})
Vue.component('Son',{
template: '#son',
/* 子组件通过props属性来接收绑定在自己身上的自定义属性 */
props: ['money'] // 这个属性在子组件模板中相当于全局变量,可以直接使用
})
new Vue({
el: '#app',
data: {},
})
子父组件通信
- 在父组件模板中,使用自定义事件绑定(v-on监听)父组件的方法
- 在子组件模板中,通过 $emit 调用(触发)自定义事件
<div id="app">
<Father/>v-on
</div>
<template id="father">
<div>
<h3> father - 组件 </h3>
<p> 我的小金库有: {{ gk }} </p>
<hr>
<!-- 在父组件模板中,使用自定义事件绑定父组件的方法 - get是自定义事件,名称随意 -->
<Son @get = "changeGk"/>
</div>
</template>
<template id="son">
<div>
<h5> son - 组件 </h5>
<button @click = "give"> 给老爸红包 </button>
</div>
</template>
js代码
Vue.component('Father',{
template: '#father',
data () {
return {
gk: 0
}
},
methods: {
changeGk ( val ) {
this.gk = val
}
}
})
Vue.component('Son',{
template: '#son',
data () {
return {
hongbao: 888
}
},
methods: {
give () {
// 在这里调用自定义事件 get
// this.$emit('get',参数1,参数2,参数3 )
this.$emit('get', this.hongbao )
}
}
})
new Vue({
el: '#app',
data: {},
})
非父子组件通信
第一种:ref链实现
- 在父组件模板中,通过ref 获得son组件的信息,并执行son组件的事件
- 在girl组件模板中,通过 $emit 触发父组件的事件(实际上是son的事件)
<div id="app">
<Father/>
</div>
<template id="father">
<div>
<h3> 父组件 </h3>
<hr>
<Son ref = "son"></Son>
<hr>
<Girl @kick = "kick"/>
</div>
</template>
<template id="son">
<div>
<h4> Son组件 </h4>
<p v-if='f'>我被姐姐打了</p>
</div>
</template>
<template id="girl">
<div>
<h4> Girl组件 </h4>
<button @click = "hit"> 打 </button>
</div>
</template>
Vue.component('Father',{
template: '#father',
methods: {
kick () {
// 通过ref 获得son 组件,并执行son组件的changeF
// console.log( this )
this.$refs.son.changeF()
}
}
})
Vue.component('Son',{
template: '#son',
data () {
return {
f: false
}
},
methods: {
changeF () {
this.f = !this.f
}
}
})
Vue.component('Girl',{
template: '#girl',
methods: {
hit () {
this.$emit('kick') //触发父组件的kick事件
}
}
})
new Vue({
el: '#app',
data: {},
methods: {
},
})
第二种:bus事件总线实现
- 在son组件模板中,通过bus.$on监听一个自定义事件
- 在girl组件模板中,通过 bus.$emit 触发son组件的自定义事件
<div id="app">
<Father/>
</div>
<template id="father">
<div>
<h3> 父组件 </h3>
<hr>
<Son></Son>
<hr>
<Girl/></Girl>
</div>
</template>
<template id="son">
<div>
<h4> Son组件 </h4>
<p v-if='f'>我被姐姐打了</p>
</div>
</template>
<template id="girl">
<div>
<h4> Girl组件 </h4>
<button @click = "hit"> 打 </button>
</div>
</template>
js代码
const bus = new Vue() // 事件总线
//console.log(bus)
Vue.component('Father',{
template: '#father',
})
Vue.component('Son',{
template: '#son',
data () {
return {
f: false
}
},
mounted () { // 表示组件已经挂载结束,也就是表示这个组件已经渲染到了页面
// console.log('mounted')
bus.$on('cry',() => { //监听事件
this.f = !this.f
})
}
})
Vue.component('Girl',{
template: '#girl',
methods: {
hit () {
bus.$emit('cry') //触发son组件的事件
}
}
})
new Vue({
el: '#app',
data: {},
methods: {
},
})