Vue-组件传递
# Vue2
# 父组件向子组件传值
单向下行绑定(父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解)
// 父组件
<Header :msg='msg'></Header>
// 子组件
props:['msg']
// 或者
props:{
msg:数据类型,
},
// 或者
props:{
isBack: { type: [Boolean, String], default: true },
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 子组件向父组件传值
// 子组件
this.$emit('自定义事件名称',要传的数据)
// 父组件
<Header @childInput='getVal'></Header>
methods:{
getVal(msg){
// msg就是子组件传递的数据
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 兄弟组件之间的传值(通过一个中转bus)
// 组件A
<button @click='goFooter'>传过去</button>
import bus from '@/common/bus'
data(){
return{
msg:'这是兄弟数据'
}
}
methods:{
goFooter(){
bus.$emit('toFooter',this.msg)
}
}
// 组件B
import bus from '@/common/bus'
data(){
return{
str:''
}
},
mounted(){
bus.$on('toFooter',(data)=>{
// data是this.msg数据
this.str = data
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 父组件调用子组件方法
在 vue2
中 ref
被用来获取对应的子元素,然后调用子元素内部的方法。
<template>
<!-- 子组件 -->
<TestComponent ref="TestComponent"></TestComponent>
</template>
<script>
// 导入子组件
import TestComponent from './TestComponent'
export default {
components: {
TestComponent
},
mounted () {
// 调用子组件方法
this.$refs.TestComponent.show()
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 子组件调用父组件方法
在子组件里用$emit
向父组件触发一个事件,父组件监听这个事件
// 父组件
<template>
<div>
<child @fatherMethod="fatherMethod"></child>
</div>
</template>
<script>
import child from '~/components/dam/child';
export default {
components: {
child
},
methods: {
fatherMethod() {
console.log('测试');
}
}
};
</script>
// 子组件
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
methods: {
childMethod() {
this.$emit('fatherMethod');
}
}
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Vue2实例
<tabs :list="list" :fontColor="color" @change="change" fontSize="30rpx" underLine></tabs>
<script>
import tabs from '../../components/tabs.vue';
export default {
components: {
tabs
},
data() {
return {
tabs:0,
color: '#1abb1d',
fontSize:'26rpx',
title: 'Hello',
list: [{
name: '首页',
index: 0
}, {
name: '饮品',
index: 1
}, {
name: '购物车',
index: 2
}, {
name: '我的',
index: 3
}, ]
}
},
methods: {
change(index) {
this.tabs = index
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<view class="list">
<view class="item" v-for="(item,index) in list" :key="index" @click="change(item.index)"
:style="{fontSize:fontSize}"
:class="[changeIndex===item.index?'item__active':'',
changeIndex===item.index && underLine ?'item__active_underLine':'']"
>{{item.name}}
</view>
</view>
<script>
export default {
name: "tabs",
props: {
list: Array,
fontColor: String,
fontSize: {
type: String,
default: '50rpx'
},
underLine:{
type:Boolean,
default:false
}
},
data() {
return {
changeIndex: 0
};
},
methods: {
change(index) {
this.changeIndex = index
this.$emit('change', index)
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// Make sure to add code blocks to your code group
# Vue3
# 父组件向子组件传参
选中添加样式
// 子组件
<div :class="{ selected: isSelected }">{{info}}</div>
// props可以省略前面的名字;props只读;
<script setup>
let props = pefineProps({
// 是否被选中
isSelected: {
type: Boolean
},
info:{
type: String
}
})
</script>
<style>
.selected {
border-left: 6px solid #5172e9;
background-color: white;
}
<style>
// 父组件
<sheetLabelVue :isSelected="currentRegionsIndex === index" v-for="(item,index) in regionsData" :key="item"@click="onChangeRegion(index)"/>
<script setup>
const currentRegionsIndex = ref(0)
const onChangeRegion = (index) => {
currentRegionsIndex.value = index
// TODO:获取该大区对应的数据
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 父组件调用子组件方法
在 Vue3
<script setup>
中使用 ref
,如何获取到子元素,并调用方法
// 父组件
<template>
<!-- 子组件 -->
<TestComponent ref="RefTestComponent"></TestComponent>
</template>
<script setup>
// 导入子组件
import TestComponent from './TestComponent'
import { ref } from 'vue'
import { nextTick } from 'process'
// 定义一个对象关联上子组件的 ref 值(注意:这里的属性名必须跟子组件定义的 ref 值一模一样,否者会关联失效)
const RefTestComponent = ref(null)
// 延迟使用,因为还没挂载
nextTick(() => {
RefTestComponent.value.show()
})
</script>
// 子组件
const show = ()=>{
console.log('你调用了子组件的方法')
}
defineExpose({
show
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 非父子组件之间进行交互的三种方式
父子组件通讯:通过
props
或emits
来完成。非父子组件通讯:两个无关的组件进行通讯要找到一个 “沟通者” ,这个沟通者必须可以与双方都进行通讯。
找到双方共同的父组件:通过子向父通讯,父向子通讯的方式
- 优点:以现有技术即可完成
- 缺点:大量的跨组件处理事件,会导致逻辑变得非常复杂,各个组件之间的耦合性变强
借助
vuex
:可以与所有组件都进行交互的,所以可以借助它承担 “沟通者” 的角色- 优点:以现有技术即可完成
- 缺点:数据必须由
Vuex
处理,如果该数据之前没有存放在Vuex
中,则需要进行较大的改动
事件中心
EventHub
:有一个 公开的单例,会提供emits 发送事件
和on 监听事件
两个方法。在
Vue2
中vm
实例因为直接具备这两个方法,所以可以直接作为事件中心实例。在
Vue3
中,取消了on
方法,所以如果想要实现这种机制,则需要通过 mitt (opens new window) 来进行实现。- 优点:有利于组件之间的解耦,增加可维护性
- 缺点:当事件足够多时,会导致事件中心极其复杂
上次更新: 2024/08/14, 04:14:33