瑞_23种设计模式_观察者模式

文章目录

    • 1 观察者模式(Observer Pattern)
      • 1.1 介绍
      • 1.2 概述
      • 1.3 观察者模式的结构
      • 1.4 观察者模式的优缺点
      • 1.5 观察者模式的使用场景
    • 2 案例一
      • 2.1 需求
      • 2.2 代码实现
    • 3 案例二
      • 3.1 需求
      • 3.2 代码实现
    • 4 JDK中提供的观察者模式实现 ★
      • 4.1 Observable类
      • 4.2 Observer 接口
      • 4.3 案例

🙊 前言:本文章为瑞_系列专栏之《23种设计模式》的观察者模式篇。本文中的部分图和概念等资料,来源于博主学习设计模式的相关网站《菜鸟教程 | 设计模式》和《黑马程序员Java设计模式详解》,特此注明。本文中涉及到的软件设计模式的概念、背景、优点、分类、以及UML图的基本知识和设计模式的6大法则等知识,建议阅读 《瑞_23种设计模式_概述》

本系列 - 设计模式 - 链接:《瑞_23种设计模式_概述》

⬇️本系列 - 创建型模式 - 链接🔗

  单例模式:《瑞_23种设计模式_单例模式》
  工厂模式:《瑞_23种设计模式_工厂模式》
  原型模式:《瑞_23种设计模式_原型模式》
抽象工厂模式:《瑞_23种设计模式_抽象工厂模式》
 建造者模式:《瑞_23种设计模式_建造者模式》

⬇️本系列 - 结构型模式 - 链接🔗

  代理模式:《瑞_23种设计模式_代理模式》
 适配器模式:《瑞_23种设计模式_适配器模式》
 装饰者模式:《瑞_23种设计模式_装饰者模式》
  桥接模式:《瑞_23种设计模式_桥接模式》
  外观模式:《瑞_23种设计模式_外观模式》
  组合模式:《瑞_23种设计模式_组合模式》
  享元模式:《瑞_23种设计模式_享元模式》

⬇️本系列 - 行为型模式 - 链接🔗

模板方法模式:《瑞_23种设计模式_模板方法模式》
  策略模式:《瑞_23种设计模式_策略模式》
  命令模式:《瑞_23种设计模式_命令模式》
 职责链模式:《瑞_23种设计模式_职责链模式》
  状态模式:《瑞_23种设计模式_状态模式》
 观察者模式:《后续更新》
 中介者模式:《后续更新》
 迭代器模式:《后续更新》
 访问者模式:《后续更新》
 备忘录模式:《后续更新》
 解释器模式:《后续更新》

在这里插入图片描述

1 观察者模式(Observer Pattern)

瑞:观察者模式是一种常用的设计模式,常作用于分布式系统事件通知、业务对象交互、数据同步与缓存更新、实时数据监控等。

  观察者模式是一种行为型模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新

  当对象间存在一对多关系时,则使用观察者模式。比如,当一个对象被修改时,则会自动通知依赖它的对象。

  瑞:行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。
  瑞:行为型模式分为类行为模式对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性

观察者模式属于:对象行为模式

1.1 介绍

  • 意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

  • 主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

  • 何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

  • 如何解决:使用面向对象技术,可以将这种依赖关系弱化。

  • 关键代码:在抽象类里有一个 ArrayList 存放观察者们。

  • 应用实例
      1️⃣ 拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。
      2️⃣ 西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。

  • 优点
      1️⃣ 观察者和被观察者是抽象耦合的。
      2️⃣建立一套触发机制。

  • 缺点
      1️⃣ 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
      2️⃣ 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
      3️⃣ 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

  • 使用场景
      1️⃣ 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
      2️⃣ 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
      3️⃣ 一个对象必须通知其他对象,而并不知道这些对象是谁。
      4️⃣ 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

  • 注意事项
      1️⃣ JAVA 中已经有了对观察者模式的支持类(但自JDK 9开始,java.util.Observable 和 java.util.Observer 由于使用频率不高且存在设计问题,已被标记为废弃
      2️⃣ 避免循环引用
      3️⃣ 如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式

1.2 概述

定义:又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

  观察者模式(发布订阅模式)有时也被称为模型-视图模式、源-收听者模式或从属者模式。它主要定义了对象间的一种一对多的依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都能得到通知并被自动更新。

  观察者模式通常用于实现分布式事件处理系统、新闻代理、状态监测等。这种模式可以使得一个对象的改变能够自动传递给所有依赖于它的观察者,从而实现对象之间的松耦合。例如,它可以用于构建消息发布/订阅系统,其中消息发布者作为被观察者,而订阅者则作为观察者。当发布者发布新消息时,所有订阅者都会收到通知并执行相应操作。此外,在图形用户界面(GUI)开发中,观察者模式常被用于处理用户界面组件之间的交互。当一个组件的状态发生变化时,其他依赖该组件的组件将自动更新以反映新的状态。在金融领域,观察者模式也可用于实现股票市场监控系统,使投资者能实时收到股票价格变动的通知。

1.3 观察者模式的结构

  • 观察者模式主要包含以下角色:
      1️⃣ Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
      2️⃣ ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
      3️⃣ Observer:抽象观察者,是观察者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
      4️⃣ ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

1.4 观察者模式的优缺点

优点

  • 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
  • 被观察者发送通知,所有注册的观察者都会收到信息【可以实现广播机制】

缺点

  • 如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时。
  • 如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,会导致系统崩溃

1.5 观察者模式的使用场景

  • 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面时。



2 案例一

【案例】微信公众号

2.1 需求

  在使用微信公众号时,大家都会有这样的体验,当你关注的公众号中有新内容更新的话,它就会推送给关注公众号的微信用户端。我们使用观察者模式来模拟这样的场景,微信用户就是观察者,微信公众号是被观察者,有多个的微信用户关注了程序猿这个公众号。

  类图如下:

在这里插入图片描述

2.2 代码实现


  定义抽象观察者类,里面定义一个更新的方法

抽象观察者类(接口)
/*** 抽象观察者类** @author LiaoYuXing-Ray**/
public interface Observer {void update(String message);
}

  定义具体观察者类,微信用户是观察者,里面实现了更新的方法

微信用户(类)
/*** 具体的观察者角色类** @author LiaoYuXing-Ray**/
public class WeiXinUser implements Observer {private final String name;public WeiXinUser(String name) {this.name = name;}public void update(String message) {System.out.println(name + "-" + message);}
}

  定义抽象主题类,提供了attach、detach、notify三个方法

抽象主题角色类(接口)
/*** 抽象主题角色类** @author LiaoYuXing-Ray**/
public interface Subject {// 添加订阅者(添加观察者对象)void attach(Observer observer);// 删除订阅者void detach(Observer observer);// 通知订阅者更新消息void notify(String message);
}

  微信公众号是具体主题(具体被观察者),里面存储了订阅该公众号的微信用户,并实现了抽象主题中的方法

具体主题角色类(类)
import java.util.ArrayList;
import java.util.List;/*** 具体主题角色类** @author LiaoYuXing-Ray**/
public class SubscriptionSubject implements Subject {// 定义一个集合,用来存储多个观察者对象private final List<Observer> weiXinUserList = new ArrayList<Observer>();public void attach(Observer observer) {weiXinUserList.add(observer);}public void detach(Observer observer) {weiXinUserList.remove(observer);}public void notify(String message) {// 遍历集合for (Observer observer : weiXinUserList) {// 调用观察者对象中的update方法observer.update(message);}}
}

  客户端程序测试类

测试类
/*** 测试类** @author LiaoYuXing-Ray**/
public class Client {public static void main(String[] args) {// 1.创建公众号对象SubscriptionSubject subject = new SubscriptionSubject();// 2.订阅公众号subject.attach(new WeiXinUser("Ray"));subject.attach(new WeiXinUser("瑞瑞"));subject.attach(new WeiXinUser("CSDN-Ray486"));// 3.公众号更新,发出消息给订阅者(观察者对象)subject.notify("《瑞_23种设计模式》专栏更新了!");}
}

  代码运行结果如下:

	Ray-《瑞_23种设计模式》专栏更新了!瑞瑞-《瑞_23种设计模式》专栏更新了!CSDN-Ray486-《瑞_23种设计模式》专栏更新了!

3 案例二

本案例为菜鸟教程中的案例

3.1 需求

  观察者模式使用三个类 Subject、Observer 和 Client。Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。

  ObserverPatternDemo,我们的演示类使用 Subject 和实体类对象来演示观察者模式。

在这里插入图片描述

3.2 代码实现

步骤 1

  创建 Subject 类。

Subject.java
import java.util.ArrayList;
import java.util.List;public class Subject {private List<Observer> observers = new ArrayList<Observer>();private int state;public int getState() {return state;}public void setState(int state) {this.state = state;notifyAllObservers();}public void attach(Observer observer){observers.add(observer);      }public void notifyAllObservers(){for (Observer observer : observers) {observer.update();}}  
}

步骤 2

  创建 Observer 类。

Observer.java
public abstract class Observer {protected Subject subject;public abstract void update();
}

步骤 3

  创建实体观察者类。

BinaryObserver.java
public class BinaryObserver extends Observer{public BinaryObserver(Subject subject){this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); }
}
OctalObserver.java
public class OctalObserver extends Observer{public OctalObserver(Subject subject){this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Octal String: " + Integer.toOctalString( subject.getState() ) ); }
}
HexaObserver.java
public class HexaObserver extends Observer{public HexaObserver(Subject subject){this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() ); }
}

步骤 4

  使用 Subject 和实体观察者对象。

ObserverPatternDemo.java
public class ObserverPatternDemo {public static void main(String[] args) {Subject subject = new Subject();new HexaObserver(subject);new OctalObserver(subject);new BinaryObserver(subject);System.out.println("First state change: 15");   subject.setState(15);System.out.println("Second state change: 10");  subject.setState(10);}
}

步骤 5

  执行程序,输出结果:

	First state change: 15Hex String: FOctal String: 17Binary String: 1111Second state change: 10Hex String: AOctal String: 12Binary String: 1010



4 JDK中提供的观察者模式实现 ★

  在 Java 中,通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例。

瑞:需要注意的是:自JDK 9开始,java.util.Observable 和 java.util.Observer 由于使用频率不高且存在设计问题,已被标记为废弃。

4.1 Observable类

  Observable 类是抽象目标类(被观察者),它有一个 Vector 集合成员变量,用于保存所有要通知的观察者对象,下面来介绍它最重要的 3 个方法。

  • void addObserver(Observer o) 方法:用于将新的观察者对象添加到集合中。
  • void notifyObservers(Object arg) 方法:调用集合中的所有观察者对象的 update方法,通知它们数据发生改变。通常越晚加入集合的观察者越先得到通知。
  • void setChange() 方法:用来设置一个 boolean 类型的内部标志,注明目标对象发生了变化。当它为true时,notifyObservers() 才会通知观察者。

4.2 Observer 接口

  Observer 接口是抽象观察者,它监视目标对象的变化,当目标对象发生变化时,观察者得到通知,并调用 update 方法,进行相应的工作。

4.3 案例

【例】警察抓小偷

  警察抓小偷也可以使用观察者模式来实现,警察是观察者,小偷是被观察者。

  代码如下:

  1️⃣ 小偷是一个被观察者,所以需要继承Observable类

小偷 - 被观察者(类)
import java.util.Observable;/*** 小偷 - 被观察者** @author LiaoYuXing-Ray**/
public class Thief extends Observable {private String name;public Thief(String name) {this.name = name;}public void setName(String name) {this.name = name;}public String getName() {return name;}public void steal() {System.out.println("小偷:我偷东西了,有没有人来抓我!!!");super.setChanged(); //changed  = truesuper.notifyObservers();}
}

  2️⃣ 警察是一个观察者,所以需要让其实现Observer接口

警察 - 观察者(类)

import java.util.Observable;
import java.util.Observer;/*** 警察 - 观察者** @author LiaoYuXing-Ray**/
public class Policemen implements Observer {private String name;public Policemen(String name) {this.name = name;}public void setName(String name) {this.name = name;}public String getName() {return name;}@Overridepublic void update(Observable o, Object arg) {System.out.println("警察:" + ((Thief) o).getName() + ",我已经盯你很久了,你可以保持沉默,但你所说的将成为呈堂证供!!!");}
}
测试类
/*** 测试类** @author LiaoYuXing-Ray**/
public class Client {public static void main(String[] args) {// 创建小偷对象Thief t = new Thief("隔壁老王");// 创建警察对象Policemen p = new Policemen("小李");// 让警察盯着小偷t.addObserver(p);// 小偷偷东西t.steal();}
}

  执行程序,输出结果:

	小偷:我偷东西了,有没有人来抓我!!!警察:隔壁老王,我已经盯你很久了,你可以保持沉默,但你所说的将成为呈堂证供!!!



本文是博主的粗浅理解,可能存在一些错误或不完善之处,如有遗漏或错误欢迎各位补充,谢谢

  如果觉得这篇文章对您有所帮助的话,请动动小手点波关注💗,你的点赞👍收藏⭐️转发🔗评论📝都是对博主最好的支持~


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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Day63-LVS四层负载均衡及结合Nginx7层负载均衡实践

Day63-LVS四层负载均衡及结合Nginx7层负载均衡实践 1. LVS&#xff08;Linux Virtual Server&#xff09;介绍2. IPVS&#xff08;LVS&#xff09;发展史3. IPVS软件工作层次图4. LVS技术点小结5. LVS的4模式原理讲解5.1 NAT(Network AddressTranslation)&#xff0c;中文网络地…

《Retrieval-Augmented Generation for Large Language Models: A Survey》 AI 解读

论文链接&#xff1a;Retrieval-Augmented Generation for Large Language Models: A Survey 论文标题&#xff1a;《Retrieval-Augmented Generation for Large Language Models: A Survey》 一译中文版地址&#xff1a; https://yiyibooks.cn/arxiv/2312.10997v5/index.htm…

PI案例分享--2000A核心电源网络的设计、仿真与验证

目录 摘要 0 引言 1 为什么需要 2000A 的数字电子产品? 2 2000A 的供电电源设计 2.1 "MPM3698 2*MPM3699"的 MPS扩展电源架构 2.2 使用恒定导通时间(COT)模式输出核心电压的原因 2.3 模块化 VRM 的优势 2.4 用步进负载验证2000A的设计难点 2.4.1 电源网络 …

qtcreator的信号槽链接

在ui文件中简单创建一个信号槽连接并保存可以在ui_mainwindow.h下 class Ui_MainWindow 类 void setupUi(QMainWindow *MainWindow)函数 找到对应代码 QObject::connect(pushButton, SIGNAL(clicked()), MainWindow, SLOT(close())); 下拉&#xff0c;由于 class MainWind…

《权力》为什么只为某些人所拥有 - 三余书屋 3ysw.net

权力&#xff1a;为什么只为某些人所拥有 大家好&#xff0c;今天我们解读的书名是《权力》&#xff0c;副标题是“为什么只为某些人所拥有”。该书深入探讨了职场中的权力议题&#xff0c;强调获得权力是关键的职场技能之一。在激烈的职场竞争中&#xff0c;缺乏这一技能将使…

C#(winform) 调用MATLAB函数

测试环境 VisualStudio2022 / .NET Framework 4.7.2 Matlab2021b 参考&#xff1a;C# Matlab 相互调用 Matlab 1、编写Matlab函数 可以没有任何参数单纯定义matlab处理的函数&#xff0c;输出的数据都存在TXT中用以后期读取数据 function [result,m,n] TEST(list) % 计算…

Python 后端 Flask 使用 Flask-SocketIO、前端 Vue3 实现长连接 Websocket 通信详细教程(更新中)

Flask 安装 Flask-Socketio Flask-SocketIO 第三方库使 Flask 应用程序可以实现客户端和服务器之间的低延迟双向通信。客户端应用程序可以使用 Javascript、Python、C、Java 和 Swift 中的任何 SocketIO 客户端库或任何其他兼容客户端来建立与服务器的永久连接。 Flask-Socke…

逐步学习Go-Select多路复用

概述 这里又有多路复用&#xff0c;但是Go中的这个多路复用不同于网络中的多路复用。在Go里&#xff0c;select用于同时等待多个通信操作&#xff08;即多个channel的发送或接收操作&#xff09;。Go中的channel可以参考我的文章&#xff1a;逐步学习Go-并发通道chan(channel)…

使用 Yoda 和 ClickHouse 进行实时欺诈检测

背景 Instacart 是北美领先的在线杂货公司,拥有数百万活跃的客户和购物者。在其平台上打击欺诈和滥用行为不仅对于维护一个值得信赖和安全的环境至关重要,也对保持Instacart的财务健康至关重要。在这篇文章中,将介绍了一个欺诈平台——Yoda,解释了为什么我们选择ClickHous…

【踩坑】荣耀系统Android8.0 system目录Read-only file system

本来以为直接把Charles证书改成系统证书格式&#xff0c;然后通过mt管理器root之后移动到系统证书目录就行了&#xff0c;结果访问baidu仍然显示网络错误&#xff0c;折腾一晚上。后来直接安装为用户证书&#xff0c;与系统证书冲突。 手机型号&#xff1a;荣耀v10 EMUI&…

升级程序到Java21的记录一(在先升级jdk到21)

背景&#xff1a;为了使用Java21的最新特性虚拟线程以及提高程序的整体性能&#xff0c;决定将一个程序A升级到Java21. 备注&#xff1a;程序A有很多文件操作因此使用虚拟线程对提升性能有帮助&#xff0c;如果读者的程序是其他类型&#xff0c;请参考虚拟线程的一些资料决定是…

STM32学习笔记(10_3)- 软件I2C读写MPU6050

无人问津也好&#xff0c;技不如人也罢&#xff0c;都应静下心来&#xff0c;去做该做的事。 最近在学STM32&#xff0c;所以也开贴记录一下主要内容&#xff0c;省的过目即忘。视频教程为江科大&#xff08;改名江协科技&#xff09;&#xff0c;网站jiangxiekeji.com 本期开…

flutter官方案例context_menus

1&#xff1a;根据项目中的案例进行部署 2&#xff1a;运行查看有什么用&#xff0c;可不可以直接复制粘贴 案例地址 https://github.com/flutter/samples/tree/main/context_menus案例展示方法 直接把这个文件夹中的文件复制到lib文件夹中 3&#xff0c;19&#xff0c;4的fl…

Lazarus远控组件NukeSped分析

静态信息&#xff1a; 样本md5&#xff1a;9b656f5d7e679b94e7b91fc3c4f313e4 由此可见为假的Adobe Flash Player 的攻击样本 样本分析 通过五个函数&#xff0c;内部调用sub_40159D函数动态获取API函数 利用IDA python解密字符串。。 完整python代码 Python> idc.get_…

最优算法100例之18-列升序行升序的数组中查找元素

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样一…

LeetCode刷题【链表,图论,回溯】

目录 链表138. 随机链表的复制148. 排序链表146. LRU 缓存 图论200. 岛屿数量994. 腐烂的橘子207. 课程表 回溯 链表 138. 随机链表的复制 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节…

计算机网络——32差错检测和纠正

差错检测和纠正 错误检测 EDC 差错检测和纠错位&#xff08;冗余位&#xff09; D 数据由差错检测保护&#xff0c;可以包含头部字段 错误检测不是100%可靠的 协议会泄露一些错误&#xff0c;但是很少更长的EDC字段可以得到更好的检测和纠正效果 奇偶校验 单bit奇偶校验 …

App推广新篇章:Xinstall助力精准分析与优化

在当前的移动应用市场中&#xff0c;App推广已成为每个开发者不可或缺的一环。然而&#xff0c;推广并非简单的投放广告与等待用户下载&#xff0c;而是需要一套科学、系统的分析与优化流程。这正是Xinstall作为国内专业的App全渠道统计服务商&#xff0c;能够为您带来的核心价…

Decoupled Multimodal Distilling for Emotion Recognition 论文阅读

Decoupled Multimodal Distilling for Emotion Recognition 论文阅读 Abstract1. Introduction2. Related Works2.1. Multimodal emotion recognition2.2. Knowledge distillation3. The Proposed Method3.1. Multimodal feature decoupling3.2. GD with Decoupled Multimodal …

【vue2+antvx6】报错Cannot read properties of undefined (reading ‘toUpperCase‘)

我的代码是这样的 <el-collapseref"collapse"v-model"active"accordionclass"collapseStart"change"collapsechange"><el-collapse-item:name"String(index 1)"v-for"(i, index) in List":key"in…