共同编辑文档功能实现(websocket)

目录

前言

websocket封装

wangeditor下载

共同编辑文档代码实现

HTML样式部分

JS部分

css部分


前言

功能:实现文档共同编辑功能,可以实时接收到其他人的信息 

思路:先调用接口获取相应的数据进行渲染,然后通过webSocket建立链接,实时进行数据的接收和修改。

技术栈:pinia,vue3,websocket,wangeditor

websocket封装

        参考文章:在vue项目中webSocket封装(传token)-CSDN博客

这里就不在做赘述了。

wangeditor下载

        wangeditor是一个富文本容器,在本次共享文档中,我们通过它当输入框(原因:它能够保存输入的格式)

        官网:安装 | wangEditor

本项目中我们只需要进行简单的安装就行

yarn add @wangeditor/editor
# 或者 npm install @wangeditor/editor --save

yarn add @wangeditor/editor-for-vue@next
# 或者 npm install @wangeditor/editor-for-vue@next --save

在安装完成后,一定要在相应的vue文件中引入css样式

<style src="@wangeditor/editor/dist/css/style.css"></style>

 选中文字后会出现样式的更改的功能,如果不喜欢可以直接去上面css源码里把其中的样式更改掉

共同编辑文档代码实现

HTML样式部分

<template>
  <div class="all">
      <el-table :data="tableData" :border="true" style="padding-left: 1px">
        <el-table-column prop="name" width="80">
          <template #="scoped">
            <div style="padding-left: 10px">{{ scoped.row.name }}</div>
          </template>
        </el-table-column>

        <el-table-column
          v-for="(item, index) in loading"
          :key="index"
          width="300"
        >
         <template #="scoped">
            <div v-if="scoped.row.Record[index]">
              <Editor
                v-model="scoped.row.Record[index].content"
                mode="default"
                @onBlur="handleBlur(scoped.row.Record[index])"
              />
            </div>
          </template>
        </el-table-column>
      </el-table>
  </div>
</template>

JS部分

<script setup>

import {
  InterviewRecord,
} from "@/apis/home.js";

import {
  sendWebsocket,
  closeWebsocket,
  websocketSend,
} from "@/utils/websocket.js";

import { ref, onMounted, onBeforeUnmount } from "vue";
import { Editor } from "@wangeditor/editor-for-vue";


// 展示数据
const tableData = ref([]);

// 评论人的数量(渲染几个富文本框)
const loading = ref(0);

//场id
const arrangeId = ref(0);

// 请求数据接口方法
const showData = (id) => {
  InterviewRecord(id).then((res) => {
    localStorage.setItem("arrangeId", res.data.id);
    arrangeId.value = res.data.id;
    tableData.value = res.data.Students;
    loading.value = res.data.Students[0].Record.length;
  });
};

onMounted(() => {
//获取初始数据,进入行页面渲染
  showData(arrangeId);
//链接websocket后面的所有通信全部依靠他来实现
  sendWebsocket(wsMessage, wsError);
});

//富文本框失去焦点
const handleBlur = (e) => {
  // 发起ws数据
  websocketSend(e);
};

// 监听服务器传来的变化
const wsMessage = (data) => {
  const dataJson = data;
  // 这里写拿到数据后的业务代码
  if (tableData.value.length !== 0) {
    console.log(tableData.value);
    tableData.value
      .flatMap((innerArray) => innerArray)
      .forEach((element) => {
        element.Record.forEach((a) => {
          console.log(dataJson.arrange_id, a.arrange_id);
          if (
            dataJson.arrange_id == a.arrange_id &&
            dataJson.content_id == a.content_id &&
            dataJson.student_id == a.student_id
          ) {
            //将后台返回的数据进行,更改
            a.content = dataJson.content;
          }
        });
      });
  }
};

const wsError = () => {
  // 比如取消页面的loading
  console.log("ws连接错误的回调函数");
};

// 页面销毁时关闭ws。因为有可能ws连接接收数据尚未完成,用户就跳转了页面
// 在需要主动关闭ws的地方都可以调用该方法
onBeforeUnmount(() => {
  closeWebsocket();
});
</script>

在 // 监听服务器传来的变化时

因为第一次请求所有数据时,后台返回的数据嵌套的比较深,所有我进行了三层循环,进行定位,用来查找相匹配的数据,进行文本的更改

arrange_id: 207,         场id

student_id: 1,              学生id(行id)

content_id: 0,              列id

content: '<p>看看看看米尔</p>     内容

css部分

//最后别忘了因为富文本框的css

<style src="@wangeditor/editor/dist/css/style.css"></style>

至此所有的功能就都实现了,如果大家有什么不懂的可以在评论区里留言。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C#基础知识 - 基本语法篇

C#基础知识-基本语法篇 第2节 C#基本语法2.1 C#程序结构2.2 C# 结构解析2.3 命名空间及标识符、关键字2.3.1 别名的使用2.3.2 标识符2.3.3 C#关键字 更多C#基础知识详解请查看&#xff1a;C#基础知识 - 从入门到放弃 第2节 C#基本语法 2.1 C#程序结构 “Hello, World”程序历…

棋牌的电脑计时计费管理系统教程,棋牌灯控管理软件操作教程

一、前言 有的棋牌室在计时的时候&#xff0c;需要使用灯控管理&#xff0c;在开始计时的时候打开灯&#xff0c;在结账后关闭灯&#xff0c;也有的不需要用灯控&#xff0c;只用来计时。 下面以 佳易王棋牌计时计费管理系统软件为例说明&#xff1a; 软件试用版下载或技术支…

Java架构师系统架构高可用维度分析

目录 1 导语2 可用性介绍3 本地高可用-集群、分布式4 本地高可用-数据逻辑保护5 异地容灾-双活、两地三中心6 异地容灾-DRP规划&BCP业务连续性7 多活和妥协方案8 高可用流程9 总结想学习架构师构建流程请跳转:Java架构师系统架构设计 1 导语 Java架构师在进行系统架构设…

ELk(七)—部署Nginx

目录 部署Nginxfilebeat启动Nginx模块Module对nginx模块配置进行修改修改nginx-log.yml配置文件 部署Nginx 下面是nginx的安装脚本&#xff0c;里面的参数可以根据实际需要进行修改。 #!/bin/bash#新建一个文件夹用来存放下载的nginx源码包mkdir -p /opt/nginx cd /opt/nginx…

Android Studio 软件如何将系统自带的标题栏隐藏

目录 一、实现效果 二、开发环境 三、实现方法 ①首先创建一个新的项目 ②打开你需要隐藏标题栏的Activity ③我们看下正常的显示效果 ④然后在onCreate中进行代码编写 ⑤点击运行查询看效果 三、Android Studio 模板 一、实现效果 二、开发环境 三、实现方法 在Andro…

千帆竞渡,鸿蒙已过万重山

近期&#xff0c;华为宣布其自主研发的鸿蒙Next系统将不再兼容Android系统&#xff0c;而是完全独立运营。 也就是说&#xff0c;你的 Android APK 已经不能在 HarmonyOS NEXT 上运行&#xff0c;因为系统已经不存在 AOSP 代码&#xff0c;甚至没有 JVM。 此举意味着鸿蒙系统…

pytorch网络的增删改

本文介绍对加载的网络的层进行增删改, 以alexnet网络为例进行介绍。 1. 加载网络 import torchvision.models as models alexnet models.alexnet(weightsmodels.AlexNet_Weights.DEFAULT) print(alexnet)2. 删除网络 在做迁移学习的时候&#xff0c;我们通常是在分类网络的…

为uniDBGrid设置文字操作栏

为uniDBGrid设置文字操作栏&#xff0c;如下图的效果&#xff0c;用户点击审核&#xff0c;执行审核代码&#xff0c;点退回&#xff0c;执行退回代码&#xff1a; 对于Web应用界面&#xff0c;这是最常见的方式&#xff0c;那对于我等Delphi开发者来说&#xff0c;基于uniGUI该…

贝蒂详解<string.h>哦~(用法与实现)

目录 引言&#xff1a; &#xff08;一&#xff09;字符函数和字符串函数 1.简介 2.strlen()函数 2.1用法 2.2实例 2.3 实现strlen() &#xff08;1&#xff09;计数法 &#xff08;2&#xff09;递归法 &#xff08;3&#xff09; 指针-指针 2.4sizeof和strlen()的区别 3.s…

车规MCU应用场景及国产替代进展

目录 1.车规MCU应用场景 1.1 车身域 1.2 动力底盘域 1.3 座舱域和智驾域 1.4 网联域 2.国产替代进展 3.小结 前面一篇文章征途漫漫:汽车MCU的国产替代往事-CSDN博客对车规MCU国产替代的背景与一些往事进行了简单叙述&#xff0c;今天来聊聊车规MCU具体会在汽车哪些地方用…

金智融门户(统一身份认证)同步数据至钉钉通讯录

前言:因全面使用金智融门户和数据资产平台,二十几个信息系统已实现统一身份认证和数据同步,目前单位使用的钉钉尚未同步组织机构和用户信息,职工入职、离职、调岗时都需要手工在钉钉后台操作,一是操作繁琐,二是钉钉通讯录更新不及时或经常遗漏,带来管理问题。通过金智融…

基于JavaEE智能实时疫情监管服务平台设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

ES-模糊查询

模糊查询 1 wildcard 准备数据 POST demolike/_bulk {"index": {"_id": "1"} } {"text": "草莓熊是个大坏蛋" } {"index": {"_id": "2"} } {"text": "wolf 也是一个坏蛋&q…

网络安全项目实战(六)--报文检测

11. NTP应用协议报文解析 目标 了解NTP协议了解NTP包基本捕获方式了解NTP协议探测&#xff08;解析&#xff09;方法&#xff08;简单方法&#xff09; 11.1. 使用ntpdate同步网络时间 安装 $ sudo apt-get install ntpdate对时服务 查看时间 $ date #date可以查看当前系…

自然数分解 C语言xdoj64

输入说明 一个正整数 n&#xff0c;0<n<30 输出说明 输出n个连续奇数&#xff0c;数据之间用空格隔开&#xff0c;并换行 输入样例 4 输出样例 13 15 17 19 int main() {int n;scanf("%d",&n);if(n % 2 0){//n为偶数int in;//打印数字个数&#xff0c;做循…

《PySpark大数据分析实战》-12.Spark on YARN配置Spark运行在YARN上

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

【MySQL】(DDL) 表操作-查询

查询&#xff1a; show tables ; //查询所有表名称 desc 表名称 ; //查询表结构 show create table 表名称; //查看创建表语句 create table 表名 ( 字段名1 字段类型1,字段名2 字段类型2) ; //创建表结构 示列&#xff1a; 1. show tables; use 数据库名; show tables …

C++ Qt开发:Tab与Tree组件实现分页菜单

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍tabWidget选择夹组件与TreeWidget树形选择组件…

NE555汽车防盗报警电路图

实用汽车防盗报警电路如图所示。它主要由防盗部分和报警两大部分电路组成。防盗电路&#xff1a;当汽车主人离开汽车时&#xff0c;将防盗开关S置于“B”位置&#xff0c;使汽车进入防盗状态。当有窃贼进入驾驶室企图发动汽车将其盗走时&#xff0c;只要拧动点火开关&#xff0…

【Hive】【Hadoop】工作中常操作的笔记-随时添加

文章目录 1、Hive 复制一个表:2、字段级操作3、hdfs 文件统计 1、Hive 复制一个表: 直接Copy文件 create table new_table like table_name;hdfs dfs -get /apps/hive/warehouse/ods.db/table_nameload data local inpath /路径 into table new_table;修复表&#xff1a; m…