父子组件间传值(自定义地区选择组件)

子组件
子组件通过props接受父组件传来的值,通过this.$emit(‘方法名’, this.result)
这里通过父组件来控制子组件的弹出层显示:

props: {
			popShow: {
				type: Boolean,
				default: false
			}
		},

注意,这里的popShow和data中的数据不可重名,并且可以用this来引用,如在组件内部我通过locationPopShow来控制弹出层隐藏和显示,在组件的mounted周期中我们可以拿到父组件传来的值

mounted() {
			this.inItData()
			console.log('子组件传值', this.popShow)
			this.locationPopShow = this.popShow
		},

但是mounted生命周期在组件的创建到销毁只会被调用一次,如果我们这个参数是变量,显然只用mounted中拿到的值显然不行,这时可以使用watch方法来帮我们实现,如控制弹出层的显示隐藏

watch: {
			popShow(newVal, oldVal) {
				console.log(newVal, oldVal)
				this.locationPopShow = newVal
			}
		},

向父组件传参

this.$emit('areaResult', this.result)

完整代码

<template>
	<view>
		<view class="" @click="locationPopShow=true">
			子组件打开定位
		</view>
		<u-popup mode="top" v-model="locationPopShow">
			<view class="u-flex" style="justify-content:center;font-size:32rpx;font-weight:500">
				<view class="first-colum" :class="level>0?'border-r':''" style="margin:30rpx;line-height:50rpx;flex:1">
					<scroll-view scroll-y="true" style='height:400rpx'>
						<view class="" :style="{color:item.status?'#55aaff':'#333'}" @click='chooseChildren(arealist,item,1)' v-for="(item,index) in arealist"
						 :key='index'>
							{{item.label}}
						</view>
					</scroll-view>


				</view>
				<view class="second-colum" v-if='level>0' :class="level>1?'border-r':''" style="margin:30rpx;line-height:50rpx;flex:1">
					<scroll-view scroll-y="true" style='height:400rpx'>
						<view class="" :style="{color:item1.status?'#55aaff':'#333'}" @click='chooseChildren(firstChildren,item1,2)'
						 v-for="(item1,index1) in firstChildren" :key='index1'>
							{{item1.label}}
						</view>
					</scroll-view>
				</view>
				<view class="third-colum" v-if='level>1' style="margin:30rpx;line-height:50rpx;flex:1">
					<scroll-view scroll-y="true" style='height:400rpx'>
						<view class="" :style="{color:item2.status?'#55aaff':'#333'}" @click='chooseChildren(secondChildren,item2,3)'
						 v-for="(item2,index2) in secondChildren" :key='index2'>
							{{item2.label}}
						</view>
					</scroll-view>
				</view>

			</view>
			<view class="u-flex" style='justify-content:space-around;padding-bottom: 30rpx;'>
				<u-button type='primary' @click='popReset' :custom-style="{backgroundColor:'#cccccc',width:'150rpx'}">重置</u-button>
				<u-button type='primary' @click="popConfirm" :custom-style="{backgroundColor:'#55aaff',width:'150rpx'}">确定</u-button>
			</view>
		</u-popup>
	</view>
</template>

<script>
	import areaData from '../../common/areaData.js'
	export default {
		props: {
			popShow: {
				type: Boolean,
				default: false
			}
		},
		data() {
			return {
				level: 0,
				result: [],
				firstChildren: [],
				secondChildren: [],
				thirdChildren: [],
				locationPopShow: false,
				arealist: areaData,
				list: []
			}
		},
		onLoad() {
			this.inItData()

		},
		mounted() {
			this.inItData()
			console.log('子组件传值', this.popShow)
			this.locationPopShow = this.popShow
		},
		watch: {
			popShow(newVal, oldVal) {
				console.log(newVal, oldVal)
				this.locationPopShow = newVal
			}
		},
		computed: {

			getArray(arr, value, label) {
				let array = []
				array = arr.filter((val, idx) => {
					return val.code == value
				})
				console.log('筛选结果', array)
				return array.children
			},
		},
		methods: {
			inItData() {
				this.arealist.map((value, index) => {
					value.status = false
					if (value.children) {

						let obj = {
							status: true,
							code: value.code,
							label: '不限',
							name: value.label
						}
						if (value.children[0].label != '不限') value.children.unshift(obj)

						if (value.children.length > 0) {

							let arr2 = value.children

							arr2.map((value2, index2) => {
								// console.log(value2)
								if (value2.children) {
									let obj2 = {
										status: true,
										code: value2.code,
										label: '不限',
										name: value2.label
									}
									if (value2.children[0].label != '不限') value2.children.unshift(obj2)
								}
							})

						}

					}
				})
				console.log(this.arealist)
			},
			popReset() {
				this.arealist.map((value, index) => {
					value.status = false
					this.firstChildren = []
					this.secondChildren = []
					this.thirdChildren = []
				})
				// this.locationPopShow=false
				console.log(this.arealist)
				this.level = 0
			},
			popConfirm() {
				// console.log('thirdChildren提交结果',this.result)

				this.result = this.arealist.filter(value => value.status == true)
				
				if (this.result.length == 0) {
					this.$emit('areaResult', this.result)
					return
				}
				if (this.result[0].children) {
					this.result = this.result[0].children.filter(value => value.status == true)

					if (this.result[0].children) {
						this.result = this.result[0].children.filter(value => value.status == true)

					}
				}
				if (this.result.length > 1) {
					let codes = ''
					this.result.map(value => {
						if (codes == '') {
							codes += value.code
						} else {
							codes += ',' + value.code
						}

					})
					this.result = [{
						label: '多选',
						code: codes
					}]
				}
				// console.log('arealist提交结果3',this.result)
				// 子组件向父组件传参
				this.$emit('areaResult', this.result)

			},
			statusInit(arr) {
				arr.map((value, index) => {
					if (value.label != '不限') {
						value.status = false
						// console.log(value)
					} else {
						value.status = true
					}
				})
				this.$forceUpdate()
			},
			arrayChildren(arr, value, label) {

				let array = []
				array = arr.filter((val, idx) => {
					return val.code == value
				})

				return array
			},
			chooseChildren(arr, item, idx) {
				console.log(idx)

				if (item.label == '不限') {
					item.status = !item.status
					this.level = idx - 1
					if (idx == 2) {
						this.statusInit(this.firstChildren)
					} else if (idx == 3) {
						this.statusInit(this.secondChildren)
					}
					this.$forceUpdate()
					return
				}

				if (idx == 1) {
					this.statusInit(this.arealist)
					this.firstChildren = this.arrayChildren(arr, item.code)[0].children


					// console.log('secondChildren',this.secondChildren)
				} else if (idx == 2) {
					this.statusInit(this.firstChildren)
					this.secondChildren = this.arrayChildren(arr, item.code)[0].children

					this.firstChildren[0].status = false


				} else if (idx == 3) {
					this.secondChildren[0].status = false

					// console.log('筛选结果',item)

				}
				item.status = !item.status
				this.$forceUpdate()
				this.level = idx

			}

		}
	}
</script>

<style scoped>
	.border-r {
		border-right: 2rpx solid #ededed;
	}
</style>

父组件
父组件通过绑定事件来监听子组件传过来的值,通过props传递参数,需要注意:监听函数的名字要和子组件保持一直,props参数也要保持一致

<template>
	<view>
		<view class="" @click="popTest">
			父组件打开
		</view>
		<location-select  :popShow='popShow' @areaResult='areaResult'></location-select>
	</view>
</template>

<script>
	import locationSelect from '@/pages/locationSelect/locationSelect.vue'
	
	export default {
		data() {
			return {
				list:[],
				popShow:false
			}
		},
		components:{
			locationSelect
		},
		methods: {
			popTest(){
				this.popShow=true
				console.log('父组件传值')
			},
			areaResult(e){
				console.log('子组件传值',e)
			}
		}
	}
</script>

<style>

</style>

兄弟组件传值
兄弟组件间的传值可以建立一个事件中心,eventBus。首先需要创建一个事件总线并将其导出, 以便其他模块可以使用或者监听它bus.js:

import Vue from 'vue'
export const bus = new Vue()

使用时先引入bus

import {bus} from '@/bus.js'

触发事件的组件

methods:{
    additionHandle(){
      bus.$emit('事件名', {
        属性:})
    }
  }

接受事件的组件在mounted中监听

mounted() {
	//事件名要保持一致
    bus.$on('事件名', arg=> {
     console.log('组件传值',arg)
    })
  }

示例中用到了uview的组件,基于uview才能正常运行。
测试数据可自定义

const areaData = [
  {
    'label': '江苏省',
    'code': '32',
    'children': [
      {
        'label': '南京市',
        'code': '3201',
        'children': [{
          'label': '南京市',
          'code': '320100'
        },
        {
          'label': '玄武区',
          'code': '320102'
        },
        {
          'label': '秦淮区',
          'code': '320104'
        },
        {
          'label': '建邺区',
          'code': '320105'
        },
        {
          'label': '鼓楼区',
          'code': '320106'
        },
        {
          'label': '浦口区',
          'code': '320111'
        },
        {
          'label': '栖霞区',
          'code': '320113'
        },
        {
          'label': '雨花台区',
          'code': '320114'
        },
        {
          'label': '江宁区',
          'code': '320115'
        },
        {
          'label': '六合区',
          'code': '320116'
        },
        {
          'label': '溧水区',
          'code': '320117'
        },
        {
          'label': '高淳区',
          'code': '320118'
        }
        ]
      },
      ]}
      ]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值