一.什么是组件化?
组件化:封装的思想,把页面上‘可重用的部分’封装为‘组件’,从而方便项目的开发和维护,
这里可复用的部分,可以html,css和,js标签,封装到一个vue文件里面
二.全局组件和局部组件
1.如何注册一个全局的组件?
(1)位置: 在main.js(入口文件)进行注册;
(2)语法: import 组件对象 from 'vue文件路径'
Vue.component(”组件名“,组件对象)
(3)使用:把注册的组件名,当做标签进行使用
2.如何注册一个局部的组件?
(1)位置:在一个单vue文件里面进行注册;
(2):语法: import 组件对象 from 'vue文件路径'
components:{
组件的名字:组件对象
}
components与data是平级的
(3)使用:把注册的组件名,当做标签进行使用(作用范围:只能是在单vue的文件内)
上面已经介绍了组件的注册和使用,接下来说一下组件之间的通信
三.组件之间的通信
(1)父亲向子传递数据
1.首先的明白谁是父,谁是子,谁被引入谁就是子
2.父组件通过 属性的方式传递数据
3.子组件采用props进行接收
如果想要动态绑定需要加:
(2)子向父传递数据
1.语法:@自定义的事件名=“父methods里面函数名”
2.子组件想要传递数据给父组件需要用
this.$emit(“事件名”,要传递是数据)方法
3.代码演示:
子组件:
<template>
<div class="">
<button @click="fn">点击</button>
</div>
</template>
<script>
export default {
props:['title','price','info'],
data(){
return{
}
},
methods: {
fn(){
this.$emit("aaa",'李四')
}
}
}
</script>
<style scoped>
</style>
解析:给按钮帮绑定一个点击事件fn,在fn利用 this.$emit('aaa'(事件名), '李四'(要传递是数据))
父组件:
<template>
<div class="">
<Product @aaa=show></Product>
{
{name}}
</div>
</template>
<script>
import Product from './a3.vue'
export default {
data(){
return{
name:"张三"
}},
methods: {
show(val){
this.name=val
}
},
components:{
Product
}
}
</script>
<style scoped>
</style>
解析: @aaa(事件名)=show 在组件里面定义的事件名必须和子组件保持一致,后面跟的是show方法,利用val接收传递过来的数据,并且赋值给name
(3)兄弟之间传值
1.思路:两个组件的关系非常的复杂,通过父子组件通讯是非常麻烦的。这时候可以使用通用的组件通讯 方案:事件总线(event-bus)
2.图解
3.在这之前,可以创建一个文件夹,创建一个.js文件在js文件夹中
import Vue from 'vue'
// 导出空白vue对象
export default new Vue()
4.然后注册并且导入两个子组件
import a3 from './a3.vue'
import a4 from './a4.vue'
export default {
name: '',
methods: {
},
components:{
a3,
a4
}
}
5.然后分别在两个组件中导入实例化的vue对象
import qq from './DASDA/index'
6. 绑定事件并且发送数据(发送方)
<button @click="fn">发送</button>
methods: {
fn(){
qq.$emit('aaa','小明')
}
有emit说明是发送放,aaa是事件名,小明是数据
7.接收方
created(){
qq.$on('aaa',(val)=>{
this.name=val;
})
名字要和发送方的名字一样,点击按钮发生的事情是把传过来的小明赋值了给小红
8.总结: 空的Vue对象, 只负责注册事件emit触发事件, 一定要确保$on先执行;
代码:
主文件:
<template>
<div class="">
<a3/>
<a4/>
</div>
</template>
<script>
import a3 from './a3.vue'
import a4 from './a4.vue'
export default {
name: '',
methods: {
},
components:{
a3,
a4
}
}
</script>
<style scoped>
</style>
兄弟1
<template>
<div class="">
<h1>{
{ xm}}</h1>
<button @click="fn">发送</button>
</div>
</template>
<script>
import qq from './DASDA/index'
export default {
data(){
return{
// xm:'小明'
}
},
methods: {
fn(){
qq.$emit('aaa','小明')
}
}
}
</script>
<style scoped>
</style>
兄弟2
<template>
<div class="">
<h1>{
{name}}</h1>
</div>
</template>
<script>
import qq from './DASDA/index'
export default {
data(){
return{
name:'小红'
}
},
methods: {
},
created(){
qq.$on('aaa',(val)=>{
this.name=val;
})
}
}
</script>
<style scoped>
</style>
四.scoped
1.问题:当使用的样式改变的时候,其它组件的css也会跟着变,为了解决采用scoped
2.
<style scoped>
在style上加入scoped属性, 就会在此组件的标签上加上一个随机生成的data-v开头的属性
而且必须是当前组件的元素, 才会有这个自定义属性, 才会被这个样式作用到
3.总结: style上加scoped, 组件内的样式只在当前vue组件生效