学习记录-vue2,3-数据通信
目录
- 数据通信功能描述
- 数据通信实现步骤
- 1. 概念理解
- 2.数据渲染
- 3. 数据搜索
- 4. 查看详情
- 完整实例代码
数据通信功能描述
- 默认数据渲染到表格中
- 通过搜索框搜素关键词,表格展现出对应数据
- 点击详情按钮,弹出详情页,同时渲染出该数据对象
数据通信实现步骤
1. 概念理解
了解数据通信的基本概念
父子通信:
- 父组件的数据传给子组件:
//父组件
<Son :数据名="数据值"></Son>
//子组件
props:{
数据名:数据类型
}
//如此子组件便可以直接使用父组件传入的数据
- 非父子组件通信方法
//发送方
<Son ref="自定义名称"></Son>
//接受方
mounted(){
this.$refs... //可以取到发送方的组件,便可以取到发送方的方法
}
- 非父子组件通信数据
//新增组件eventBus
import Vue from 'vue'
import Bus from 'vue'
export default Bus
//发送方
import Bus from '相对路径'
Bus.$emit('数据名','数据值')
//接受方
import Bus from '相对路径'
Bus.$on('数据名',(data)=>{//可从这里取到发送方发送的数据})
- 父子组件双向绑定
//父组件
<Son v-model="绑定的数据"></Son>
//子组件
props:{
value:String //必须为value
}
<input @input="函数名" :value="value">
函数名(e){
this.$emit('数据名',e.target.value)
//e.target.value为表单数据
}
2.数据渲染
使用父子组件通信,子组件通过父组件获取数据,并将其渲染到表格中
//父组件
<MyTable :records="records"></MyTable>
//子组件
props: {
records: Array
}
//-----我是模块分割线
<tbody>
<tr v-for="item in records" :key="item.doctor">
<td>{{ item.date }}</td>
<td>{{ item.doctor }}</td>
<td>{{ item.prescription }}</td>
<td>{{ item.diagnosis }}</td>
<td @click="alert(item.doctor)">详情</td>
</tr>
</tbody>
实现效果
3. 数据搜索
将子组件搜索框绑定输入事件,并将结果返回给父组件,父组件通过筛选选出符合条件的数据,并将其传输给子组件
//子组件
<input placeholder="输入关键字搜索" @input="search" />
//-----
search(e) {
if (this.timer) clearTimeout(this.timer) //使用事件防抖
this.timer = setTimeout(() => {
this.$emit('handleH', e.target.value)
}, 500)
},
//父组件
<MyTable :records="records" @handleH="handle"></MyTable> //监听子组件事件
methods: {
handle(value) { //定义函数,判断输入框的值,如果为空,则将输入备份的值,如果不为空,则判断输入数据和原始数据项是否相同,将相同项筛选出来
this.records=value?this.records1.filter(item=>item.doctor==value||item.diagnosis==value||item.prescription==value):this.records1 //创建原始数据备份
}
},
实现效果
4. 查看详情
使用非父子组件通信,将对应点击的数据渲染到详情页中,点击详情页的x号,关闭详情页
//eventBus.js
import Vue from 'vue'
const EventBus = new Vue()
export default EventBus
//发送方
alert(doctor) { //绑定点击事件
Bus.$emit('msg', doctor) //发送数据
Bus.$emit('show', this.flag) //用flag判断表格的显示
}
//接受方
mounted() {
Bus.$on('msg', (msg) => {
this.data1 = this.records.filter(item => item.doctor === msg) //数据筛选
})
Bus.$on('show', (flag) => {
this.status=flag
})
},
完整实例代码
//App.vue
<template>
<div id="app">
<MyTable :records="records" @handleH="handle"></MyTable>
<MyIndex :records="records"></MyIndex>
</div>
</template>
<script>
import MyTable from './components/MyTable.vue'
import MyIndex from './components/MyIndex.vue'
export default {
data() {
return {
records: [
{
date: '2022-01-01',
doctor: '张三',
diagnosis: '感冒',
prescription: '感冒药',
},
{
date: '2022-02-01',
doctor: '李四',
diagnosis: '头疼',
prescription: '止疼药',
},
{
date: '2022-03-01',
doctor: '王五',
diagnosis: '腰痛',
prescription: '止痛贴',
}
],
records1: [
{
date: '2022-01-01',
doctor: '张三',
diagnosis: '感冒',
prescription: '感冒药',
},
{
date: '2022-02-01',
doctor: '李四',
diagnosis: '头疼',
prescription: '止疼药',
},
{
date: '2022-03-01',
doctor: '王五',
diagnosis: '腰痛',
prescription: '止痛贴',
}
]
}
},
methods: {
handle(value) {
this.records = value ? this.records1.filter(item => item.doctor == value || item.diagnosis == value || item.prescription == value) : this.records1
}
},
components: {
MyTable,
MyIndex
}
}
</script>
<style></style>
//MyTable
<template>
<div>
<input placeholder="输入关键字搜索" @input="search" />
<table class="my-table">
<thead>
<tr>
<th>就诊日期</th>
<th>医生姓名</th>
<th>诊断结果</th>
<th>处方信息</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in records" :key="item.doctor">
<td>{{ item.date }}</td>
<td>{{ item.doctor }}</td>
<td>{{ item.prescription }}</td>
<td>{{ item.diagnosis }}</td>
<td @click="alert(item.doctor)">详情</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import Bus from '../utils/EventBus'
export default {
data() {
return {
timer: null,
flag: true
}
},
props: {
value: String,
records: Array
},
methods: {
search(e) {
if (this.timer) clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.$emit('handleH', e.target.value)
}, 500)
},
alert(doctor) {
Bus.$emit('msg', doctor)
Bus.$emit('show', this.flag)
}
}
}
</script>
<style scoped>
.my-table {
border-collapse: collapse;
width: 100%;
}
.my-table td,
.my-table th {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
.my-table th {
background-color: #f2f2f2;
}
</style>
//MyIndex
<template>
<div class="modal-mask" v-show="status">
<div class="modal-container">
<div class="modal-header">
<h3>就诊记录详情</h3>
<span class="close-btn" @click="close">X</span>
</div>
<div class="modal-body" v-for="item in data1" :key="item.doctor">
<p><strong>就诊日期:</strong>{{item.date}}</p>
<p><strong>医生姓名:</strong>{{item.doctor}}</p>
<p><strong>诊断结果:</strong>{{item.diagnosis}}</p>
<p><strong>处方信息:</strong>{{item.prescription}}</p>
</div>
</div>
</div>
</template>
<script>
import Bus from '../utils/EventBus'
export default {
data() {
return {
data1: [],
status:false
}
},
methods: {
close() {
this.status=false
}
},
mounted() {
Bus.$on('msg', (msg) => {
this.data1 = this.records.filter(item => item.doctor === msg)
})
Bus.$on('show', (flag) => {
this.status=flag
})
},
props: {
records:Array
}
}
</script>
<style scoped>
.hidden{
display: none !important;
}
.modal-mask {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
.modal-container {
background-color: #fff;
border-radius: 5px;
padding: 20px;
max-width: 500px;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.close-btn {
cursor: pointer;
}
</style>