Vue组件基础-父向子、子向父、子向子传值
- 一、Vue组件概念,创建和使用
- 1.1 组件概念
- 1.2 组件基础使用
- 1.3 组件-scoped作用
- 二、Vue组件通信
- 2.1 父向子传值(props)
- 2.2 子向父传值($emit)
- 2.3 子与子传值(EventBus)
一、Vue组件概念,创建和使用
1.1 组件概念
组件是可复用的Vue实例,封装标签,样式和JS代码
组件化:封装的思想,把页面上 可复用的部分 封装为 组件,从而方便项目的开发和维护
一个页面,可以拆分成一个个组件,一个组件就是一个整体,每个组件可以有自己独立的结构 样式 和 行为(html,css,js)
组件的好处:各自独立,互不影响
1.2 组件基础使用
每个组件都是一个独立的个体, 代码里体现为一个独立的.vue文件
1.创建组件 封装要复用的标签, 样式, JS代码
2.注册组件
全局注册组件 -main.js中
局部注册组件 -某.vue文件中
全局注册组件
//组件的基本使用--全局注册
//1.创建组件 组件名.vue
//2.引入组件
import Pannel from './components/Pannel_1.vue'
//3.全局注册组件
Vue.component('PannelG', Pannel)
局部注册组件
//组件--局部注册
//a.创建组件 组件名.vue
//b.引入组件
import Pannel from './components/Pannel.vue'
export default {
//c.局部注册组件
components: {
Pannel: Pannel //键 和 值相同可简写为 Pannel
},
}
3.使用组件
<div id="app">
<h3>案例:折叠面板</h3>
<!-- d.组件使用 -->
<Pannel></Pannel>
</div>
1.3 组件-scoped作用
准备: 当前组件内标签都被添加 data-v-hash值 的属性
获取: css选择器都被添加 [data-v-hash值] 的属性选择器
二、Vue组件通信
2.1 父向子传值(props)
父组件 -> 子组件 传值
子组件(被引入的叫做子组件)
父组件(引入其他组件的页面)
步骤
1.子组件内, 定义变量, 准备接收, 然后使用变量
<template>
<div class="my-product">
<h3>标题: {{ title }}</h3>
<p>价格: {{ price }}元</p>
<p>{{ intop }}</p>
</div>
</template>
<script>
export default {
// a.子组件 定义变量
props: ['title', 'price', 'intop']
}
</script>
2.父组件内, 要展示封装的子组件
引入组件, 注册组件, 使用组件, 传值进去
<template>
<div>
<!-- 目标:父(app.vue) 向 子组件传值 -->
<!-- 每次组件显示不同的数据信息 -->
<!-- 步骤 -->
<!-- a.子组件定义变量 接受变量 -->
<!-- b.父组件 传值进去 -->
<!-- 3.使用组件 -->
<MyProduct title="好吃的口水鸡" price="50" intop="开业大酬宾, 全场八折"></MyProduct>
</div>
</template>
<script>
//1.引入组件
import MyProduct from './components/MyProduct.vue'
export default {
// 2.注册组件
components: {
MyProduct //key和value值 重名了 可以简写
}
}
父传子配合v-for循环使用
单项数据流
从父到子的数据流向, 叫单向数据流
子组件内直接改变父组件传过来的值(props),不通知父级,会报错,数据不一致性
Vue规定props里的变量, 本身是只读的
2.2 子向父传值($emit)
子组件触发父自定义事件方法
步骤
1.父组件内, 绑定自定义事件和事件处理函数
语法: @自定义事件名="父methods里函数名"
父组件完整代码
<template>
<div>
<!-- 目标子穿父 -->
<!-- 第一步 父组件 @自定义事件名="父函数名"-->
<MyProductsub v-for="(obj, ind) in list" :key="obj.id" :title="obj.proname" :price="obj.proprice" :intop="obj.info"
:index="ind" @subprice="fn">
</MyProductsub>
</div>
</template>
<script>
//目标 循环组件 分别传入数据
//1.引入组件
import MyProductsub from './components/MyProduct_sub.vue';
export default {
//2.注册组件
components: {
MyProductsub
},
data() {
return {
list: [
{ id: 1, proname: "超级好吃的棒棒糖", proprice: 18.8, info: '开业大酬宾, 全场8折' },
{ id: 2, proname: "超级好吃的大鸡腿", proprice: 34.2, info: '好吃不腻, 快来买啊' },
{ id: 3, proname: "超级无敌的冰激凌", proprice: 14.2, info: '炎热的夏天, 来个冰激凌了' },
],
}
},
methods: {
fn(index, price) {
//逻辑代码
this.list[index].proprice > 1 && (this.list[index].proprice = (this.list[index].proprice - price).toFixed(2))
}
}
}
</script>
2.子组件触发父自定义事件方法 调用$emit方法
子组件完整代码
<template>
<div class="my-product">
<h3>标题: {{ title }}</h3>
<p>价格: {{ price }}元</p>
<p>{{ intop }}</p>
<button @click="btn_sub">宝刀-砍1元</button>
</div>
</template>
<script>
//1.引入空白vue对象(EventBus)
import eventBus from '../EventBus'
export default {
// a.子组件 定义变量
props: ['index', 'title', 'price', 'intop'],
methods: {
//砍价方法
btn_sub() {
//错误
//1.子组件改父组件传过来的数据 不通知父亲 会造成数据的不一行
//2.vue回顶props 本身 只读的(不允许重新赋值)
// this.price--
//第二步 触发父亲的自定义事件 并传值
this.$emit('subprice', this.index, 1)
}
}
}
</script>
2.3 子与子传值(EventBus)
App.vue里引入MyProduct.vue和List.vue
组件通信-EventBus
常用于跨组件通信时使用
步骤
1.src/EventBus/index.js – 创建空白Vue对象并导出
//引入Vue
import Vue from 'vue'
//导出 空白的vue对象
export default new Vue()
2.在要接收值的组件(List.vue) eventBus.$on('事件名', 函数体)
//目标:跨组件传值
//1.引入空白vue对象(EventBus)
import eventBus from '../EventBus/index.js' //默认查找index.js
//2.接收方 $on监听事件
export default {
props: ['arr'],
//3.组件创建完毕后 在created生命周期中 监听send事件
created() {
eventBus.$on('send', (index, price) => {
this.arr[index].proprice > 1 && (this.arr[index].proprice = (this.arr[index].proprice - price).toFixed(2))
})
}
}
3.在要传递值的组件(MyProduct.vue) eventBus.$emit('事件名', 值)
//1.引入空白vue对象(EventBus)
import eventBus from '../EventBus'
export default {
// a.子组件 定义变量
props: ['index', 'title', 'price', 'intop'],
methods: {
//砍价方法
btn_sub() {
eventBus.$emit('send', this.index, 1)
}
}
}