2021SC@SDUSC

目录

一.引言

二.代码分析

1.答辩检查组件

2.文件系统组件

3.公告组件

4.教师发布题目组件

三.总结


一.引言

SDU信息门户中前端主要使用了Vue3.0的技术,这篇博客主要是根据项目的代码来解析学习Vue3.0中的知识,分析项目代码还可以掌握了antd组件库和nutUI组件库的使用,掌握了最新版本的vue router及vuex的使用,并且Vue3的一些新特性使得项目性能更加可观。

二.代码分析

1.答辩检查组件

答辩发布后通过await check来检查是否发布成功,await delete则是为了检查是否删除成功,代码开始的setup函数.执行时机,beforeCreate 表示组件刚刚被创建出来,组件的data和methods还没有初始化好,created 表示组件刚刚被创建出来,组件的data和methods已经初始化好,而且由于在执行setup函数的时候,还没有执行created生命周期方法,所以在setup函数中,是无法使用data和methods。由于我们不能在setup函数中使用data和methods,所以vue3.0为了避免我们错误的使用,它直接将setup函数中的this修改为undefined。setup函数只能是同步的不能是异步的。

<script>
import { onMounted, reactive, toRefs } from "vue";
import {getCheck,getCheckByCid,createCheck,deleteCheck,
} from "service/check";
import { useRoute } from "vue-router";
import { message } from "ant-design-vue";export default {setup() {const route = useRoute();const state = reactive({checks: [{title: "",debateId: "",content: "",timeStarted: "",timeFinished: "",location: "",roundNumber: "",},],// 答辩发布modalcheckVisible: false,// 答辩发布的详情sendCheckInfo: {title: "",content: "",timeStarted: "",timeFinished: "",location: "",},});const checkInit = async () => {const { debates } = await getCheckByCid(route.params.cid);for (let check of debates) {check.timeStarted = dateToNormal(check.timeStarted).substr(0, 16);check.timeFinished = dateToNormal(check.timeFinished).substr(0, 16);}state.checks = debates;};onMounted(async () => {await checkInit();});//日期转换格式const dateToNormal = (time) => {var re1 = new RegExp("[TZ]", "g"); //匹配html标签的正则表达式,"g"是搜索匹配多个符合的内容return time.replace(re1, " ");};const sendCheck = () => {state.checkVisible = true;};const timeOk = (val, dateString) => {state.sendCheckInfo.timeStarted = dateString[0] + ":00";state.sendCheckInfo.timeFinished = dateString[1] + ":00";};const sendCheckDone = async () => {const params = {cid: route.params.cid,title: state.sendCheckInfo.title,content: state.sendCheckInfo.content,timeStarted: state.sendCheckInfo.timeStarted,timeFinished: state.sendCheckInfo.timeFinished,location: state.sendCheckInfo.location,};try {await createCheck(params);message.success("发布成功");await checkInit();} catch (e) {message.error("发布成功");}state.checkVisible = false;};const downloadCheckFile = async (downloadName = "downLoad") => {const { data, headers } = await getCheck(route.params.cid);console.log(data, "headers", headers);const blob = new Blob([data], { type: headers["content-type"] });let dom = document.createElement("a");let url = window.URL.createObjectURL(blob);dom.href = url;dom.download = headers["content-disposition"]? headers["content-disposition"].split("=")[1]: downloadName;dom.style.display = "none";document.body.appendChild(dom);dom.click();dom.parentNode.removeChild(dom);window.URL.revokeObjectURL(url);};const _deleteCheck = async (checkId) => {try {await deleteCheck(route.params.cid, checkId);message.success("删除成功");await checkInit();} catch (e) {message.error("删除失败");}};return {...toRefs(state),downloadCheckFile,sendCheckDone,sendCheck,timeOk,_deleteCheck,};},
};
</script><style lang="scss" scoped></style>

2.文件系统组件

文件系统应该异步完成完成进入文件夹,加载文件,删除文件,下载文件,重命名文件的操作,都需要将文件FileId输入进去确定固定的文件。递归监听默认情况下都是递归监听调用方法 shallowRef/shallowReactive。如果是shallowRef类型数据,可以通过triggerRef来触发。shallowRef/shallowReactive本质是shallowReactive所以如果是通过shallow Ref创建的数据,它监听的是.value的变化,因为底层本质上value是第一层。可以通过toRow方法拿到它的原始数据,对原始数据修改就不会被追踪,这样就不会更新UI界面,这样性能就好了。
注意:如果想通过toRaw拿到ref类型的原始数据(创建时传入的那个数据)那么就必须明确的告诉toRaw方法,要获取的是.value的值,因为经过Vue的处理之后,.value中保存的才是当初创建时传入的那个原始数据。

export default {components: {FileOutlined,FolderOutlined,LeftOutlined,DownloadOutlined,UploadOutlined,},setup() {const route = useRoute();const courseId = route.params.cid;const state = reactive({// 文件列表fatherId: "",currentFileId: "",files: [{fileId: 1,fileName: "实验1",fileType: "DIR",filePermisson: "",fileOwnerId: "1",fileFatherId: "",fileLevel: "1",},],renameVisible: false,rename: "",renameFileId: "",renameFileType: "",createDirVisible: false,createDirInfo: {fileName: "",filePermission: 0,fileFatherId: "",},});onMounted(() => {state.fatherId = courseId;state.currentFileId = courseId;_getFiles(courseId);});const _getFiles = async (dirId) => {const { files } = await getFiles(dirId);state.files = files;};//进入某一文件夹const goDir = async (id, fatherId, fileType) => {if (fileType === "DIR") {await _getFiles(id);state.fatherId = fatherId;state.currentFileId = id;} else {console.log(fileType);}};const backParentDir = async () => {//需要将文件重新请求await _getFiles(state.fatherId);state.currentFileId = state.fatherId;const { ffId } = await getFatherFileId(state.currentFileId);state.fatherId = ffId;};const _createDir = () => {state.createDirVisible = true;};const createDirDone = async () => {const params = {fileName: state.createDirInfo.fileName,filePermission: parseInt(state.createDirInfo.filePermission),fileFatherId: state.currentFileId,};console.log(params);await createDir(params);await _getFiles(state.currentFileId);state.createDirVisible = false;};const renameClick = (fileId, fileType) => {state.renameVisible = true;state.renameFileId = fileId;state.renameFileType = fileType;};const renameDone = async () => {console.log(state.rename, state.renameFileId, state.renameFileType);if (state.renameFileType === "DIR") {await renameDir(state.renameFileId, state.rename);await _getFiles(state.currentFileId);} else {await renameFile(state.renameFileId, state.rename);await _getFiles(state.currentFileId);}state.renameVisible = false;};const _deleteFile = async (fileId, fileType) => {if (fileType === "DIR") {await deleteDir(fileId);await _getFiles(state.currentFileId);} else {await deleteFile(fileId);await _getFiles(state.currentFileId);}};const _uploadFile = async (data) => {try {let params = new FormData(); //创建form对象params.append("file", data.file); //通过append向form对象添加数据params.append("fileFatherId", state.currentFileId);params.append("cid", courseId);await upLoadDiskFile(params);message.success("上传成功");await _getFiles(state.currentFileId);} catch (e) {console.log(e);}};const download = async (fileId, downloadName = "downLoad") => {const { data, headers } = await downLoadDiskFile(route.params.cid,fileId);const blob = new Blob([data], { type: headers["content-type"] });let dom = document.createElement("a");let url = window.URL.createObjectURL(blob);dom.href = url;dom.download = headers["content-disposition"]? headers["content-disposition"].split("=")[1]: downloadName;dom.style.display = "none";document.body.appendChild(dom);dom.click();dom.parentNode.removeChild(dom);window.URL.revokeObjectURL(url);};return {...toRefs(state),courseId,goDir,backParentDir,renameClick,renameDone,_createDir,createDirDone,_deleteFile,download,_uploadFile,};},
};
</script>

3.公告组件

公告主要是 nid公告编码,tid: 教师编码, date: 时间, title: 标题,content: 内容,通过sendnotice方式将公告发表出来,这里用到了reactive,reactive是vue3中提供的实现响应式数据的方法。vue2中响应式数据是通过defineProperty来实现的,而在vue3中响应式数据是通过ES6的proxy来实现的。注意:reactive参数必须是对象(json/array);如果给reactive传递了其他对象默认情况下修改对象,界面不会自动更新如果想更新,可以通过重新赋值的方式。

export default {props: ["courseName"],setup(props) {const route = useRoute();const router = useRouter();const state = reactive({// 公告列表notice: [{nid: "",tid: "",date: "",title: "",content: "",},],// 控制modal显示notice详情noticeVisible: false,// 存储某条notice的详细信息noticeInfo: {tid: "",date: "",cid: [""],title: "",content: "",},});onMounted(async () => {const { noticelist } = await getNotice(route.params.cid);console.log(noticelist);for (let n of noticelist) {n.simpleContent = htmlToText(n.content);}state.notice = noticelist;});const showNotice = async (id) => {try {const notice = await getNoticeInfo(id);state.noticeInfo = notice;state.noticeVisible = true;} catch (e) {console.log(e);}};const htmlToText = (html) => {var re1 = new RegExp("<.+?>", "g"); //匹配html标签的正则表达式,"g"是搜索匹配多个符合的内容return html.replace(re1, "");};const sendNotice = () => {router.push({path: "/sendNotice",query: { cid: route.params.cid, cname: props.courseName },});};return {...toRefs(state),showNotice,sendNotice,};},
};
</script>

4.教师发布题目组件

教师通过project结构中的  cid,instructTeacher: 指导老师,  projectId: 项目编号,projectName:项目名称,发布项目,通过sendProject方法来发布题目。async的用法,它作为一个关键字放到函数前面,用于表示函数是一个异步函数,因为async就是异步的意思, 异步函数也就意味着该函数的执行不会阻塞后面代码的执行。 如果async 函数中有返回一个值 ,当调用该函数时,内部会调用Promise .solve() 方法把它转化成一个promise 对象作为返回,如果timeout 函数内部抛出错误, 那么就会调用Promise.reject() 返回一个promise 对象。

export default {components: {ProjectInfo,},setup() {const route = useRoute();const state = reactive({// 题目列表projectWithGroups: [{project: {cid: "",instructTeacher: "",projectId: "",projectName: "",},groups: [{gid: "string",gname: "string",members: [{sid: "string",sname: "string",position: "string",},],projectStatus: "string",},],},],// 题目发布modalprojectVisible: false,// 题目发布的详情sendprojectInfo: {cid: "",projectName: "",projectContent: "",instructTeacher: "",},});const sendprojectDone = async () => {const params = {cid: route.params.cid,projectName: state.sendprojectInfo.projectName,projectContent: state.sendprojectInfo.projectContent,instructTeacher: state.sendprojectInfo.instructTeacher,};await createProject(route.params.cid, params);await _init();state.projectVisible = false;};return {...toRefs(state),_init,showDetail,sendproject,sendprojectDone,};},
};
</script>

三.总结

通过本次代码分析,我初识vue3.0,学习了await,reactive,递归监听,async等重要的vue3.0知识点。第一次接触的框架是vue3.0,给人耳目一新的感觉。实现前后端的分离,对于项目的,模块划分也特别清晰。最近改项目的时候就发现一些问题。在进行抽取公共组件的时候,每一个小的组件是封装的功能越小越好。在涉及到逻辑的时候,尽量让使用者来封装。这个问题是特别突出的问题。使用一个公共组件,不断往上封装,不断加东西,有时候觉得这样很麻烦。没有节省时间。就觉得一个小组件,越小越能让人灵活运用。

SDU信息门户(10)前端vue3.0代码分析相关推荐

  1. SDU信息门户(7)图灵认证授权子系统:oauth协议详解(3)

    2021SC@SDUSC 目录 一.引言 二.代码分析 1.利用刷新令牌获取访问令牌的具体细节 2.根据授权码获取访问令牌和刷新令牌 3.认证授权基本信息配置 4.通过授权码找到授权 5.获取访问授权 ...

  2. SDU信息门户(12)系统配置的yaml文件解析

    2021SC@SDUSC 目录 一.引言 二.docker安装及yaml文件分析 1.安装 2.yaml文件分析 version build cap_add,cap_drop cgroup_paren ...

  3. SDU信息门户(5)——教务系统学生功能

    2021SC@SDUSC 目录 引言 代码分析 总结 引言 在SDU信息门户的教务系统中学生功能占据着重要的地位,在教务系统各个子功能中大部分都涉及到学生信息的添加修改,学生所选课程信息的获取以及上传 ...

  4. 前端vue3.0小兔鲜 项目

    博主收集到了一个完整的项目 前端vue3.0框架的小兔鲜项目,学习前端的小伙伴可以找我来领. 完整的教学视频+代码+笔记 项目地址:http://erabbit.itheima.net/ 需要的联系q ...

  5. Lua1.0 代码分析 库

    为什么80%的码农都做不了架构师?>>>    Lua1.0 代码分析 库 库的代码相对比较简单.这里以数学库为例进行说明. 比如看下这个取绝对值的数学函数 static void ...

  6. 前端Vue3.0搭建后台管理系统

    视频   第1节 - 了解项目开发流程         第1学时 了解产品从0到1的开发流程,产品经理.UI设计师.研发部.测试工程师.mp4            第2节 - 构建vue项目.代码仓 ...

  7. vue 前端显示图片加token_前端Vue3.0:从0到1手把手撸码搭建管理后台系统

    第1节 – 了解项目开发流程 手把手撸码前端 – 第1学时 了解产品从0到1的开发流程,产品经理.UI设计师.研发部.测试工程师 第2节 – 构建vue项目.代码仓库管理 手把手撸码前端 – 第2学时 ...

  8. SDU信息门户(8)组队和文件系统分析

    2021SC@SDUSC 目录 一.概述 1.需求背景: 2.需求描述 : 二.代码分析 1.参数指定 2.导包并确定常量 3.获得数据库并进行相关操作 4.关键信息获取 5.建立线程池 三.总结 一 ...

  9. Lua1.0 代码分析 table.c

    转载出处:http://my.oschina.net/xhan/blog/307961 table.c 代码分析 全局符号,常量,字符串,关联数组,文件列表的定义. 全局符号: 初始有 5 个基本的符 ...

最新文章

  1. python之路目录
  2. linux python wps doc 转 txt_耗时一周尝试踩坑,整理了一些Python实用知识点
  3. 崩坏3日记:戴尔超限专武天天出,我们的快乐变为刷题式重复养成
  4. hdu_2048 错排问题
  5. 计算机分php,计算机按照处理数据的形态分类,可以分为什么?
  6. typescript索引类型_typescript入门:高级类型
  7. mysql5.7.17初始化_mysql5.7.17初始化求助 - 墨天轮问答
  8. .net excel导入mysql_.NET Core使用NPOI将Excel中的数据批量导入到MySQL - 追逐时光者 - 博客园...
  9. vscode使用相关配置
  10. Java 堆内存是线程共享的!面试官:你确定吗?
  11. 如何进入腾讯、网易、阿里这样的互联网公司,看到第二条我就秒懂了~
  12. 供参考的 php 学习路线
  13. kubernetes PVC介绍
  14. 开源数据库连接池的使用
  15. 【便签纸】记录一下对比excel列表的小工具代码
  16. 流体渐变_最新的10种Fluid Colors流体渐变壁纸制作方法
  17. ffmpeg获取视频封面图片
  18. AjaxPro2 方法未定义,对象不支持此方法或属性,解决办法
  19. 大数据采集(hdu)第二章笔记
  20. win10:如何查看可用内存插槽

热门文章

  1. (c++)已知空间三维两个点坐标,得到直线方程以及两点之间所有的点,使用VTK进行绘制显示
  2. 选择教育直播平台时,要注重这三点
  3. 手把手教你玩转HarmonyOS版地图应用开发
  4. source insight 安装Quicker.em插件
  5. 真无线蓝牙耳机性价比排行,高性价比真无线蓝牙耳机
  6. 团队作业4——第一次项目冲刺(Alpha版本)-第二篇
  7. [NVIDIA实习]7月1日 无盘系统搭建 初尝3D vision
  8. 国家数据局的5大趋势预判
  9. Dbvisualizer中文乱码
  10. java实验2 对象、类、继承、包