【vue组件】使用element-ui table 实现嵌套表格 点击展开时获取数据

news2024/11/26 2:34:37

应用场景是这样
主表格的数据是所有的学校
然后点击展开的时候,获取学校下相应班级的数据
并且班级要能选择后生成图表,但所有的班级最多选择5个

首先是嵌套表格

<div>
    <el-table
      :data="tableDisplayData"
      id="chartTableExpand"
      style="width: 100%"
      ref="chartTable"
      @expand-change="handleRowClick"
      :expand-row-keys="expandedRows"
      :row-key="getRowKeys"
    >
      <el-table-column type="expand">
        <template slot-scope="scope">
          <el-table
            :ref="'expandTable' + scope.row.id"
            :data="scope.row.tableExpandData"
            style="width: 100%"
            v-loading="expandLoading"
            @selection-change="
              (val) => {
                return handleExpandSelectionChange(val, scope.row.id);
              }
            "
          >
            <el-table-column
              :selectable="
                (row) => {
                  return checkSelectable(row, 'id');
                }
              "
              type="selection"
            >
            </el-table-column>
            <el-table-column
              prop="className"
              label="班级名称"
              width="180"
              fixed="left"
            >
              <template slot-scope="scope">
                <span>
                  {{ scope.row.Name }}
                </span>
              </template>
            </el-table-column>
            <el-table-column prop="studentCount" label="学生数量">
              <template slot-scope="scope">
                <span>
                  {{ scope.row.StudentCount }}
                </span>
              </template>
            </el-table-column>
            <el-table-column prop="answerCount" label="回答数量">
              <template slot-scope="scope">
                <span>
                  {{ scope.row.AnswerCount }}
                </span>
              </template>
            </el-table-column>
          </el-table>
        </template>
      </el-table-column>
      <el-table-column prop="schoolName" label="学校名">
        <template slot-scope="scope">
          <span>
            {{ scope.row.schoolName }}
          </span>
        </template>
      </el-table-column>
      <el-table-column prop="classCount" label="班级数量">
        <template slot-scope="scope">
          <span>
            {{ scope.row.classCount }}
          </span>
        </template>
      </el-table-column>
      <el-table-column prop="status" label="时间">
        <template slot-scope="scope">
          <span>
            {{ scope.row.date }}
          </span>
        </template>
      </el-table-column>
      <el-table-column prop="search">
        <template slot="header" slot-scope="scope">
          <el-input v-model="searchKey" size="medium" placeholder="Search" />
        </template>
        <template slot-scope="scope"> </template>
      </el-table-column>
    </el-table>
  </div>

在主表格type为expand的行(<el-table-column type="expand">)下面添加子表格,并且添加方法

@selection-change="(val) => {return handleExpandSelectionChange(val, scope.row.id); }"

传入主表格row的数据和row的id

在方法handleExpandSelectionChange中,将 multipleSelection的值对应相应的table存起来,也就是说一个table 对应它自己的 multipleSelection,键是tableId ;值是每个table自己的multipleSelection,这样能解决多个table共用一个multipleSelection时会出现前一个子table选中的值会被后一个子table选中的值替换掉的问题

handleExpandSelectionChange(val, tableId) {
      let _this = this;
      // 如果是表格展开时去点击的话,就不要改变selections的值
      if (!_this.isClassTableExpanded) {
        // 这里将 multipleSelection的值对应相应的table存起来
        // 也就是说一个table 对应它自己的 multipleSelection
        // 键是tableId 值是 multipleSelection
        _this.selections[tableId] = val;
      }
      _this.updateMultipleSelection();
    },

在方法updateMultipleSelection中,会将各个表格的multipleSelection汇总,形成一个总的multipleSelection,再根据这个汇总的multipleSelection进行后面的处理

updateMultipleSelection() {
      let _this = this;
      // 把selections里的row取出来汇总
      _this.multipleSelection = [].concat.apply(
        [],
        Object.keys(_this.selections).map(function (key) {
          return _this.selections[key];
        })
      );
      // 用汇总后的multipleSelection来生成图表
    },

然后再看主表格的展开时触发的方法

@expand-change="handleRowClick"

在handleRowClick方法中
通过方法getExpandClassData中获取数据

	// 点击展开
     handleRowClick(row,rows) {
      let _this = this;

      _this.getExpandClassData(row,rows);
    },

    // 获取学校或班级汇总数据
    async getExpandClassData(row,rows) {
      let _this = this;
      let schoolId = row.id
      // 展开class table对应的ref
      let expandTable = "expandTable" + schoolId;

      // table展开时,根据之前选中的选项通过toggleRowSelection点击checkbox
      _this.$nextTick(function () {
        if (_this.$refs[expandTable]) {
          let hasSelections =
            _this.selections.length > 0 ||
            _this.selections[schoolId] ||
            (_this.selections[schoolId]
              ? _this.selections[schoolId].length
              : undefined) > 0;
          if (hasSelections) {
            _this.isClassTableExpanded = true;
            let selectedIds = _this.selections[schoolId].map(
              (mSelect) => mSelect.id
            );
            row.tableExpandData.forEach((row) => {
              if (selectedIds.includes(row.id)) {
                _this.$refs[expandTable].toggleRowSelection(row, true);
              }
            });
          }
        }
        _this.isClassTableExpanded = false;
      });
      const delIndex = _this.expandedRows.findIndex((item)=>{return item === schoolId});
      if (delIndex > -1) {
        _this.expandedRows.splice(delIndex, 1);
      }
      
      const isRowNowExpand = rows.some(r => r.id === row.id) // 判断当前行展开状态
      if (isRowNowExpand) {
          _this.expandedRows = [schoolId,..._this.expandedRows];
      }

      // 如果已经展开获取或数据了,就返回不要再获取了
      if (row.isExpanded) {
        return;
      }
      _this.expandLoading = true;
      await _this.getClassList(row.id);

      // 将school下对应的class表格数据,赋值到相应的school下
      // 作为tableExpandData存起来
      _this.$nextTick(() => {
        _this.$set(row, "tableExpandData", _this.tableExpandData);
        _this.$set(row, "isExpanded", true);
        _this.expandLoading = false;
      });
    },

注意在上面代码中
通过await _this.getClassList(row.id);获取到班级数据
然后将数据赋值给对应的row

_this.$nextTick(() => {
   _this.$set(row, "tableExpandData", _this.tableExpandData);
   _this.$set(row, "isExpanded", true);
   _this.expandLoading = false;
 });

但这里会产生一个问题,用$set赋值后,页面会重新渲染,展开的table会收回去,我的想法是让展开的table保持展开的状态,
这里使用到的就是:expand-row-keys="expandedRows"

首先在主表格中添加

<el-table
      ...
      :expand-row-keys="expandedRows"
      :row-key="getRowKeys"
    >

注意一定要设置row-key
然后在下面代码里

const delIndex = _this.expandedRows.findIndex((item)=>{return item === schoolId});
if (delIndex > -1) {
  _this.expandedRows.splice(delIndex, 1);
}

const isRowNowExpand = rows.some(r => r.id === row.id) // 判断当前行展开状态
if (isRowNowExpand) {
    _this.expandedRows = [schoolId,..._this.expandedRows];
}

首先要将_this.expandedRows中对应主表展开行的数据清除掉
然后通过const isRowNowExpand = rows.some(r => r.id === row.id)判断当前行是否展开
如果展开就把当前行添加到expandedRows 中,那样页面刷新后会保持展开状态

在getExpandClassData这个方法里还要注意的是
首先对展开的子table设置对应的ref

let expandTable = "expandTable" + schoolId;

然后,因为选中子table的单选框后,把展开的子table收齐再展开时,单选框的选中样式会丢失,这时我想的办法是根据之前选中的选项,调用toggleRowSelection这个方法,再把单选框选中

// table展开时,根据之前选中的选项通过toggleRowSelection点击checkbox
   _this.$nextTick(function () {
     if (_this.$refs[expandTable]) {
       let hasSelections =
         _this.selections.length > 0 ||
         _this.selections[schoolId] ||
         (_this.selections[schoolId]
           ? _this.selections[schoolId].length
           : undefined) > 0;
       if (hasSelections) {
         _this.isClassTableExpanded = true;
         let selectedIds = _this.selections[schoolId].map(
           (mSelect) => mSelect.id
         );
         row.tableExpandData.forEach((row) => {
           if (selectedIds.includes(row.id)) {
             _this.$refs[expandTable].toggleRowSelection(row, true);
           }
         });
       }
     }
     _this.isClassTableExpanded = false;
   });

在上面代码中hasSelections 是判断是否有选中的选项,然后把展开子表格选中的id取出来,根据选中的id调用toggleRowSelection去点击

然后如果已经展开获取过数据了,就返回不要再调用接口获取了

  if (row.isExpanded) {
    return;
  }

最后要限制选中的数量,就通过下面的方法
在展开的子表格中单选框对应的行中 添加:selectable

<el-table-column
    :selectable="(row) => {return checkSelectable(row, 'id'); }"
    type="selection"
  >

然后checkSelectable方法的实现如下:

// 是否禁用多选
checkSelectable: function (row, key) {
  let _this = this;
  let flag = true;
  // 多选最多选 banNumber 个
  if (_this.multipleSelection.length >= _this.banNumber) {
    if (!Array.isArray(row)) {
      flag = _this.multipleSelection.some(
        (selection) => row[key] === selection[key]
      );
    }
  }
  return flag;
},

然后通过banNumber 控制限制的数量

最后还有一个搜索方法

 watch: {
    searchKey: function (val) {
      this.tableDisplayData = this.filterTableData.filter(function (data) {
        return data.schoolName.toLowerCase().includes(val.toLowerCase());
      });
    },
  },

完整代码如下:


<template>
  <div>
    <el-table
      :data="tableDisplayData"
      id="chartTableExpand"
      style="width: 100%"
      ref="chartTable"
      @expand-change="handleRowClick"
      :expand-row-keys="expandedRows"
      :row-key="getRowKeys"
    >
      <el-table-column type="expand">
        <template slot-scope="scope">
          <el-table
            :ref="'expandTable' + scope.row.id"
            :data="scope.row.tableExpandData"
            style="width: 100%"
            v-loading="expandLoading"
            @selection-change="
              (val) => {
                return handleExpandSelectionChange(val, scope.row.id);
              }
            "
          >
            <el-table-column
              :selectable="
                (row) => {
                  return checkSelectable(row, 'id');
                }
              "
              type="selection"
            >
            </el-table-column>
            <el-table-column
              prop="className"
              label="班级名称"
              width="180"
              fixed="left"
            >
              <template slot-scope="scope">
                <span>
                  {{ scope.row.Name }}
                </span>
              </template>
            </el-table-column>
            <el-table-column prop="studentCount" label="学生数量">
              <template slot-scope="scope">
                <span>
                  {{ scope.row.StudentCount }}
                </span>
              </template>
            </el-table-column>
            <el-table-column prop="answerCount" label="回答数量">
              <template slot-scope="scope">
                <span>
                  {{ scope.row.AnswerCount }}
                </span>
              </template>
            </el-table-column>
          </el-table>
        </template>
      </el-table-column>
      <el-table-column prop="schoolName" label="学校名">
        <template slot-scope="scope">
          <span>
            {{ scope.row.schoolName }}
          </span>
        </template>
      </el-table-column>
      <el-table-column prop="classCount" label="班级数量">
        <template slot-scope="scope">
          <span>
            {{ scope.row.classCount }}
          </span>
        </template>
      </el-table-column>
      <el-table-column prop="status" label="时间">
        <template slot-scope="scope">
          <span>
            {{ scope.row.date }}
          </span>
        </template>
      </el-table-column>
      <el-table-column prop="search">
        <template slot="header" slot-scope="scope">
          <el-input v-model="searchKey" size="medium" placeholder="Search" />
        </template>
        <template slot-scope="scope"> </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import { getClassData, getSchoolData } from "@/api/api";
export default {
  name: "embededTable",
  props: {
    tooltip: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      multipleSelection: [],
      selections: [],
      banNumber: 5,
      isTableSelected: false,
      tableExpandData: [],
      filterTableData: [],
      searchKey: "",
      tableDisplayData: [],
      isClassTableExpanded: false,
      expandedRows: [],
      expandLoading: false,
    };
  },
  async created() {
    let _this = this;
    await _this.getData();
  },
  mounted() {
    let _this = this;
  },
  watch: {
    searchKey: function (val) {
      this.tableDisplayData = this.filterTableData.filter(function (data) {
        return data.schoolName.toLowerCase().includes(val.toLowerCase());
      });
    },
  },

  components: {},
  methods: {
    getRowKeys: function (row) {
      return row.id;
    },
    async getClassList(id) {
      let _this = this;
      await getClassData(id)
        .then((res) => {
          _this.tableExpandData = res;
        })
        .catch((err) => {
          console.log(err, "err");
        });
    },
    async getSchoolList() {
      let _this = this;
      await getSchoolData()
        .then((res) => {
          _this.tableData = res;
          _this.filterTableData = _this.tableData;
          _this.tableDisplayData = _this.tableData;
        })
        .catch((err) => {
          console.log(err, "err");
        });
    },
    async getData() {
      let _this = this;
      await _this.getSchoolList();
    },

    // 点击展开
     handleRowClick(row,rows) {
      let _this = this;

      _this.getExpandClassData(row,rows);
    },

    // 获取学校或班级汇总数据
    async getExpandClassData(row,rows) {
      let _this = this;
      let schoolId = row.id
      // 展开class table对应的ref
      let expandTable = "expandTable" + schoolId;

      // table展开时,根据之前选中的选项通过toggleRowSelection点击checkbox
      _this.$nextTick(function () {
        if (_this.$refs[expandTable]) {
          let hasSelections =
            _this.selections.length > 0 ||
            _this.selections[schoolId] ||
            (_this.selections[schoolId]
              ? _this.selections[schoolId].length
              : undefined) > 0;
          if (hasSelections) {
            _this.isClassTableExpanded = true;
            let selectedIds = _this.selections[schoolId].map(
              (mSelect) => mSelect.id
            );
            row.tableExpandData.forEach((row) => {
              if (selectedIds.includes(row.id)) {
                _this.$refs[expandTable].toggleRowSelection(row, true);
              }
            });
          }
        }
        _this.isClassTableExpanded = false;
      });
      const delIndex = _this.expandedRows.findIndex((item)=>{return item === schoolId});
      if (delIndex > -1) {
        _this.expandedRows.splice(delIndex, 1);
      }
      
      const isRowNowExpand = rows.some(r => r.id === row.id) // 判断当前行展开状态
      if (isRowNowExpand) {
          _this.expandedRows = [schoolId,..._this.expandedRows];
      }
      console.log(_this.expandedRows)

      // 如果已经展开获取或数据了,就返回不要再获取了
      if (row.isExpanded) {
        return;
      }
      _this.expandLoading = true;
      await _this.getClassList(row.id);

      // 将school下对应的class表格数据,赋值到相应的school下
      // 作为tableExpandData存起来

      // row.tableExpandData = _this.tableExpandData;
      // row.isExpanded = true;
      _this.$nextTick(() => {
        _this.$set(row, "tableExpandData", _this.tableExpandData);
        _this.$set(row, "isExpanded", true);
        // _this.expandedRows = [schoolId,..._this.expandedRows];
        _this.expandLoading = false;
      });
    },

    // 单选
    handleExpandSelectionChange(val, tableId) {
      let _this = this;
      // 如果是表格展开时去点击的话,就不要改变selections的值
      if (!_this.isClassTableExpanded) {
        // 这里将 multipleSelection的值对应相应的table存起来
        // 也就是说一个table 对应它自己的 multipleSelection
        // 键是tableId 值是 multipleSelection
        _this.selections[tableId] = val;
      }
      _this.updateMultipleSelection();
    },

    updateMultipleSelection() {
      let _this = this;
      // 把selections里的row取出来汇总
      _this.multipleSelection = [].concat.apply(
        [],
        Object.keys(_this.selections).map(function (key) {
          return _this.selections[key];
        })
      );
    },

    // 是否禁用多选
    checkSelectable: function (row, key) {
      let _this = this;
      let flag = true;
      // 多选最多选 banNumber 个
      if (_this.multipleSelection.length >= _this.banNumber) {
        if (!Array.isArray(row)) {
          flag = _this.multipleSelection.some(
            (selection) => row[key] === selection[key]
          );
        }
      }
      return flag;
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
/* 去掉全选按钮 */
.el-table__fixed-header-wrapper .el-table__header th .el-checkbox .el-checkbox__input .el-checkbox__inner{
  display: none;
}
</style>

效果图如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1009324.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

bwapp下载安装

下载地址&#xff1a; https://sourceforge.net/projects/bwapp/ 安装&#xff1a; 解压缩 将压缩包解压到www目录 进入bwapp/admin/,打开setting.php文件&#xff0c;修改数据库用户名密码 安装数据库 打开浏览器&#xff0c;输入 http://localhost/bwapp/bwapp/install.p…

微服务简介

微服务简介 微服务架构是一种软件架构模式&#xff0c;它将一个大型应用程序拆分为一组小型、独立的服务&#xff0c;每个服务都有自己的业务逻辑和数据存储。这些服务可以独立开发、部署和扩展&#xff0c;通常使用HTTP或其他轻量级通信协议进行通信。 以下是微服务架构的一…

【完美世界】柳神为石昊,付出生命代价,石昊称“柳妈”不过分吧

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析完美世界。 在完美世界中&#xff0c;荒天帝石昊一生要追赶的人便是柳神。而柳神也在石昊崛起的过程中庇护了他一生&#xff0c;直至终极大决战陨落。人们都说石昊应该叫柳神为柳妈&#xff0c;事实也的确如此。 纵观柳神…

iwebsec靶场 文件包含漏洞通关笔记7-php://input伪协议

目录 前言 1.php://input伪协议原理 2.php://input伪协议使用条件 3.file_get_contents()函数 第07关 php://input伪协议 1.打开靶场 2.源码分析 3.伪协议渗透 &#xff08;1&#xff09;构造post信息 &#xff08;2&#xff09;渗透 前言 1.php://input伪协议原理 …

fcntl函数

#include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ... ); 参数&#xff1a; fd&#xff1a;表示需要操作的文件描述符 cmd:表示对文件描述符进行如何操作 1.F_DUPFD&#xff1a;复制文件描述符&#xff0c;复制的是第一个参数fd,得到一个新的文…

小谈设计模式(2)—简单工厂模式

小谈设计模式&#xff08;2&#xff09;—简单工厂模式 专栏介绍专栏地址专栏介绍 简单工厂模式简单工厂模式组成抽象产品&#xff08;Abstract Product&#xff09;具体产品&#xff08;Concrete Product&#xff09;简单工厂&#xff08;Simple Factory&#xff09;三者关系 …

历史重演,2024浙大MPA提面A资格预期不到25%,成败最后一个月

随着浙大mpa项目2024年提前批面试申请的截止&#xff0c;最新的申请人数也基本确定下来&#xff0c;从目前的信息来看&#xff0c;今年的提面申请数量与去年基本持平&#xff0c;很可能意味着今年的最终报考以及后续复试相关的一系列问题都可以去年为参考&#xff0c;这样一来&…

vue-drag-resize 可拖动缩放元素组件

1、安装 npm i -s vue-drag-resize 2、使用 <template><div class"screen-content"><vue-drag-resize w"200" :h"200" resizing"resize" dragging"resize" contentClass"resize-box"><p&…

JavaScript逻辑题:一个篮球的高度为100米 每次落地弹起高度为前一次高度的0.6 问多少次之后高度小于1米?

// 设置篮球的高度let height 100;// 设置次数默认值为0let i 0;// 进行循环while(true){//计算每次弹起的高度height height*0.6;// 并记录次数i;// 如果高度小于1米时&#xff0c;结束循环&#xff0c;并输出次数iif(height < 1){console.log(篮球弹起i次之后高度小于1…

测试的水太深,年轻人把握不住.....

​前言 去阿里面试测试工程师&#xff0c;这里面水太深&#xff0c;什么未来规划&#xff0c;职业发展的东西都是虚拟的&#xff0c;作者还太年轻&#xff0c;没有那个经历&#xff0c;把握不住。项目只有几个&#xff0c;开心快乐就行&#xff0c;不PK&#xff0c;文明PK。 …

简单四边形不等式优化dp(上)

*下文中“优于”一般指的是“不劣于”&#xff0c;请自行分辨。 四边形不等式 四边形不等式定义为&#xff1a; 位于整数集合上的二元函数 f ( x , y ) f(x,y) f(x,y)&#xff0c;对于 a ≤ b ≤ c ≤ d a\leq b\leq c\leq d a≤b≤c≤d&#xff0c;若满足&#xff1a; f ( a…

MyBatis中当实体类中的属性名和表中的字段名不一样,怎么办

方法1&#xff1a; 在mybatis核心配置文件中指定&#xff0c;springboot加载mybatis核心配置文件 springboot项目的一个特点就是0配置&#xff0c;本来就省掉了mybatis的核心配置文件&#xff0c;现在又加回去算什么事&#xff0c;总之这种方式可行但没人这样用 具体操作&…

c语言进阶部分详解(指针初阶)

大家好&#xff01;&#xff0c;前段时间一直在准备数学建模竞赛&#xff0c;现在也是忙完了。抓紧继续给大家带来c语言的内容。今天给大家带来指针初阶部分的讲解 当我们谈论C语言中的指针时&#xff0c;实际上是在讨论一种非常重要的概念&#xff0c;因为指针是C语言的核心之…

《昆明海晏村:修缮后的新生,历史与现代的完美交融》

在昆明市的东南角&#xff0c;有一处名为海晏村的地方&#xff0c;这里曾是滇池北岸的重要码头&#xff0c;也是滇池文化的发源地之一。近年来&#xff0c;海晏村经过精心修缮&#xff0c;焕发出新的生机&#xff0c;成为了一个集历史、文化、艺术于一体的旅游胜地。那么&#…

Harp:面向跨空间域的分布式事务优化算法

Harp&#xff1a;面向跨空间域的分布式事务优化算法 庄琪钰1,2&#xff0c;李彤1,2&#xff0c;卢卫1,2, 杜小勇1,2 1 中国人民大学信息学院&#xff0c;北京 100872 2 数据工程与知识工程教育部重点实验室&#xff0c;北京 100872 摘要&#xff1a;近数据计算范式驱动了银行、…

whee: 美图秀秀出品AI绘画图片创作工具平台

【 产品介绍】 whee.com还提供了风格模型训练和创作词库的功能&#xff0c;让用户可以定制自己的专属风格和词汇。whee.com是一个适合各种水平和兴趣的用户的创意平台&#xff0c;无论是想要学习绘画&#xff0c;还是想要展示自己的才华&#xff0c;都可以在whee.com找到乐趣和…

openpnp - 给.openpnp2目录减肥

文章目录 openpnp - 给.openpnp2目录减肥概述笔记不会引起.openpnp2目录size持续增加的目录/文件列表会引起.openpnp2目录size持续增加的目录/文件列表可以做一个程序来给openpnp减肥END openpnp - 给.openpnp2目录减肥 概述 听同学说, 如果.openpnp2将磁盘分区都占满后, 就会…

【word日常操作】word里面表格已经设置了重复标题行,但是显示无效怎么办

在制作表格的过程当中&#xff0c;相信很多人都知道&#xff0c;表格不只有一页的时候就会在下一面&#xff0c;也会显示出来&#xff0c;然而这时我们需要让word表头重复出现&#xff0c;那么该怎么办呢? 1 出现问题 word表格如何设置多页时能重复表头&#xff0c;百度后出…

ElasticSearch系列-索引原理与数据读写流程详解

索引原理 倒排索引 倒排索引&#xff08;Inverted Index&#xff09;也叫反向索引&#xff0c;有反向索引必有正向索引。通俗地来讲&#xff0c;正向索引是通过key找value&#xff0c;反向索引则是通过value找key。ES底层在检索时底层使用的就是倒排索引。 索引模型 现有索…

01- 从零开始完整实现-循环神经网络RNN

一 简介 使用 pytorch 搭建循环神经网络RNN&#xff0c;循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一类用于 处理序列数据的神经网络架构。与传统神经网络不同&#xff0c;RNN 具有内部循环结构&#xff0c;可以在处理序列数据时保持状态…