学习记录-vue2,3-数据通信

目录

数据通信功能描述

  1. 默认数据渲染到表格中
  2. 通过搜索框搜素关键词,表格展现出对应数据
  3. 点击详情按钮,弹出详情页,同时渲染出该数据对象

数据通信实现步骤

1. 概念理解

了解数据通信的基本概念

父子通信:

  1. 父组件的数据传给子组件:
javascript 复制代码
//父组件
<Son :数据名="数据值"></Son>
//子组件
props:{
数据名:数据类型
}
//如此子组件便可以直接使用父组件传入的数据
  1. 非父子组件通信方法
javascript 复制代码
//发送方
<Son ref="自定义名称"></Son>
//接受方
mounted(){
this.$refs...		//可以取到发送方的组件,便可以取到发送方的方法
}
  1. 非父子组件通信数据
javascript 复制代码
//新增组件eventBus
import Vue from 'vue'
import Bus from 'vue'
export default Bus
javascript 复制代码
//发送方
import Bus from '相对路径'
Bus.$emit('数据名','数据值')
//接受方
import Bus from '相对路径'
Bus.$on('数据名',(data)=>{//可从这里取到发送方发送的数据})
  1. 父子组件双向绑定
javascript 复制代码
//父组件
<Son v-model="绑定的数据"></Son>
//子组件
props:{
value:String		//必须为value
}
<input @input="函数名" :value="value">
函数名(e){
this.$emit('数据名',e.target.value)
//e.target.value为表单数据
}

2.数据渲染

使用父子组件通信,子组件通过父组件获取数据,并将其渲染到表格中

javascript 复制代码
//父组件
<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. 数据搜索

将子组件搜索框绑定输入事件,并将结果返回给父组件,父组件通过筛选选出符合条件的数据,并将其传输给子组件

javascript 复制代码
//子组件
<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号,关闭详情页

javascript 复制代码
//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
    })
  },

完整实例代码

javascript 复制代码
//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>
javascript 复制代码
//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>
javascript 复制代码
//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>
相关推荐
卸任6 小时前
Vibe coding工具使用心得
前端·ai编程
brien96 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
wangqiaowq7 小时前
Ontology 学习
学习
修炼的dance7 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M7 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写7 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李7 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易7 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马7 小时前
前沿视界
前端
kyriewen7 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员