Vue组件
组件开发的优点:利于维护、代码结构清晰、无冗余代码
组件化 : 封装的思想,把页面上可重用的部分封装为组件,从而方便项目的开发和维护;
组件注册使用:
全局注册
import Vue from 'vue'
import 组件对象 from 'vue文件路径'
// import Pannel from './components/Pannel'
// Vue.component("PannelG", Pannel)
Vue.component("组件名", 组件对象)
全局注册组件名后, 就可以当做标签在任意Vue文件中template里用
单双标签都可以或者小写加-形式, 运行后, 会把这个自定义标签当做组件解析, 使用组件里封装的标签替换到这个位置
// 这三个标签是完全相等的
<PannelG></PannelG>
<PannelG/>
<pannel-g></pannel-g>
局部注册
import 组件对象 from 'vue文件路径'
export default {
components: {
"组件名": 组件对象
}
}
scoped作用
<style scoped>
在style上加入scoped属性, 就会在此组件的标签上加上一个随机生成的data-v开头的属性
vue组件通信
因为每个组件的变量和值都是独立的,组件之间想要互相使用变量就需要组件通信
父向子使用自定义属性,子向父使用自定义事件
父向子通信
父组件传值:
<template>
<div>
<!--
目标: 父(App.vue) -> 子(MyProduct.vue) 分别传值进入
需求: 每次组件显示不同的数据信息
步骤(口诀):
1. 子组件 - props - 变量 (准备接收)
2. 父组件 - 传值进去
-->
<Product title="好吃的口水鸡" price="50" intro="开业大酬宾, 全场8折"></Product>
<Product title="好可爱的可爱多" price="20" intro="老板不在家, 全场1折"></Product>
<Product title="好贵的北京烤鸭" price="290" :intro="str"></Product>
</div>
</template>
<script>
// 1. 创建组件 (.vue文件)
// 2. 引入组件
import Product from './components/MyProduct'
export default {
data(){
return {
str: "好贵啊, 快来啊, 好吃"
}
},
// 3. 注册组件
components: {
// Product: Product // key和value变量名同名 - 简写
Product
}
}
</script>
子组件接收:
export default {
props: ['title', 'price', 'intro']
}
单向数据流
从父到子的数据流向,叫单向数据流
在vue中需要遵循单向数据流原则
- 父组件的数据发生了改变,子组件会自动跟着变
- 子组件不能直接修改父组件传递过来的props props是只读的(子组件不能修改的只是父组件传过来的栈中的值)
子向父通信
语法:
- 父: @自定义事件名=“父methods函数”
- 子: this.$emit(“自定义事件名”, 传值) - 执行父methods里函数代码
跨组件通信-EventBus
两个组件的关系非常的复杂,通过父子组件通讯是非常麻烦的。这时候可以使用通用的组件通讯方案:事件总线(event-bus)
EventBus/index.js- 定义事件总线bus对象
import Vue from 'vue'
// 导出空白vue对象
export default new Vue()
传值
<button @click="subFn"></button>
methods: {
subFn(){
this.$emit('subprice', this.index, 1) // 子向父
eventBus.$emit("send", this.index, 1) // 跨组件
}
}
接收
export default {
props: ["arr"],
// 3. 组件创建完毕, 监听send事件
created() {
eventBus.$on("send", (index, price) => {
this.arr[index].proprice > 1 && (this.arr[index].proprice = (this.arr[index].proprice - price).toFixed(2));
});
},