Vue 父子组件的通信及传值
前言父子组件间的通信,组件可以说是一个具有独立功能的整体,但是当我们要将这些组件拼接在一起时,这些组件相互之间要建立联系,这个联系我们就称之为通信一、简单案例html<body><div id="app"><Scholar></Scholar></div><!-- 初学者模板 --><template id="schol
·
前言
父子组件间的通信,组件可以说是一个具有独立功能的整体,但是当我们要将这些组件拼接在一起时,这些组件相互之间要建立联系,这个联系我们就称之为通信
一、简单案例
html
<body>
<div id="app">
<Scholar></Scholar>
</div>
<!-- 初学者模板 -->
<template id="scholar">
<div>
<h3> 初学者 </h3>
<h3> 技术回应到: {{show}} </h3>
<hr>
<!-- 父组件传参 :参数='值' ,@responses是子组件定义的 response自己定义的方法-->
<technology :language='language' @responses='response'/>
</div>
</template>
<!-- 学习语言 -->
<template id='technology'>
<div>
<h3> 初学者要学的技术语言 {{language}}</h3>
<button @click="responses">回应</button>
</div>
</template>
</body>
script
<script>
// 父组件
Vue.component('scholar',{
template: '#scholar',
data () {
return {
// 参数
language: ['Java','前端','PHP'],
// 接收响应渲染
show: ''
}
},
methods: {
// 接收语言响应
response (data) {
this.show=data
}
}
})
// 子组件
Vue.component('technology',{
template: '#technology',
// 子组件接收参数
props: {
// 接收父组件参数名
language: []
},
methods: {
// 回应的单击事件
responses () {
// 将数据传回父组件
this.$emit('responses','你就这样,先别急于求成,先学前端吧')
}
}
})
new Vue({
}).$mount('#app')
</script>
这是用 props 实现的
测试效果
二、项目实践案例(只提供部分代码)
需求
在开发中常用到搜索功能,搜索功能页面几乎都是一样的,需要将搜索单独的剥离,从而提高代码的复用性和扩展性。
父组件
<template>
<!-- @search='search'指接收子组件事件, selectOptions下拉框参数,selectValue下拉框默认参数 -->
<selectAndDateSearch @search='search' :selectOptions='selectOptions' :selectValue='selectValue'></selectAndDateSearch>
</template>
import selectAndDateSearch from '@/components/SelectAndDateSearch'
export default {
// 子组件
components: {
selectAndDateSearch
},
data () {
return {
// 将参数传给子组件
selectOptions: ['传感器id', '医院id', '医院id2'],
selectValue: '传感器id',
searchValue: ''
}
},
methods: {
search (data) {
//子组件传参响应
}
}
}
子组件
<template>
<div class = "device-list-main">
<div class ="header">
<div class="header_title">
<cube-select v-model="selectChildValue" :options="selectOptions" ></cube-select>
</div>
<div class="header_input">
<cube-input v-model="searchValue" placeholder="请输入搜索值" :maxlength=30 ></cube-input>
<div class="header_input_btn" @click="clickGetDeviceInfo()">
<img src="../../static/img/search.png">
</div>
</div>
</div>
<div class="header">
<cube-input v-on:focus="showMinPicker('startTime')" v-model="startTime" placeholder="开始时间" :maxlength=30 style="width: 50%;"></cube-input>
<span>到</span>
<cube-input v-on:focus="showMinPicker('endTime')" v-model="endTime" placeholder="结束时间" :maxlength=30 style="width: 50%;"></cube-input>
</div>
</div>
</template>
<script>
import datwTimeUtil from '@/utils/dateTimeUtil'
import emptyUtil from '@/utils/emptyUtil'
export default {
data () {
return {
// 避免和父组件传的值冲突,爆:父组件传的值传进子组件就被修改 违反了vue的数据流
selectChildValue: this.selectValue,
// 填写的值
searchValue: '',
// 开始时间
startTime: '',
// 结束时间
endTime: '',
// 时间标识
timeIdentifying: '',
pageable: {
//
sensorImei: '',
//
hospitalName: '',
//
saleChanelName: '',
// 开始时间
startTime: '',
// 结束时间
endTime: '',
// 下拉框标识
selectValue: ''
}
}
},
// 接收父组件传的参数
props: {
// 父组件传参(选择的value数组)
selectOptions: [],
// 父组件传参(默认选择)
selectValue: String
},
methods: {
// 点击搜索事件
clickGetDeviceInfo () {
if (emptyUtil.stringIsNotBlank(this.selectChildValue)) {
this.pageable.selectValue = this.selectChildValue
this.pageable.sensorImei = (this.selectChildValue === '传感器id' ? this.searchValue : '')
this.pageable.hospitalName = (this.selectChildValue === '医院id' ? this.searchValue : '')
this.pageable.saleChanelName = (this.selectChildValue === '医院id2' ? this.searchValue : '')
}
console.log('this.pageable:', this.pageable)
// 向父组件传参
this.$emit('search', this.pageable)
},
// 监听出发选择时间
showMinPicker (time) {
if (!this.minPicker) {
this.minPicker = this.$createDatePicker({
title: '选择时间',
visible: true,
min: new Date(2000, 0, 1),
max: new Date(2099, 12, 1),
value: new Date(),
format: {
year: 'YYYY',
month: 'MM',
date: 'DD'
},
columnCount: 3,
onSelect: this.selectHandler,
onCancel: this.cancelHandler
})
}
// 选择时间标识
this.timeIdentifying = time
this.minPicker.show()
},
selectHandler (selectedTime, selectedText, formatedTime) {
let date = datwTimeUtil.getFormatDate(selectedTime)
if (this.timeIdentifying === 'startTime') {
this.startTime = date
this.pageable.startTime = date
} else if (this.timeIdentifying === 'endTime') {
this.endTime = date
this.pageable.endTime = date
}
},
// 取消事件
cancelHandler () {
if (this.timeIdentifying === 'startTime') {
this.startTime = ''
this.pageable.startTime = ''
} else if (this.timeIdentifying === 'endTime') {
this.endTime = ''
this.pageable.endTime = ''
}
}
}
}
</script>
4.效果展示
问题
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: "selectValue"
大概报错意思:父组件传的值传进子组件就被修改 违反了vue的数据流
解决
将父组件传过来的值赋给另一个值v-model绑定,这样就不会影响到父组件传过来的值(类似在java中类似值传递,拷贝时,两个变量互不干扰。
例子:
<!-- selectChildValue下拉框数组,selectOptions显示的值 -->
<cube-select v-model="selectChildValue" :options="selectOptions" ></cube-select>
data () {
return {
// 重点: 避免和父组件传的值冲突,爆:父组件传的值传进子组件就被修改 违反了vue的数据流
selectChildValue: this.selectValue,
},
props: {
// 父组件传参(选择的value数组)
selectOptions: [],
// 父组件传参(默认选择)
selectValue: String
},
}
更多推荐
已为社区贡献13条内容
所有评论(0)