目录
前言
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>
至此所有的功能就都实现了,如果大家有什么不懂的可以在评论区里留言。