赞
踩
提示:SpringBoot2与Vue3的小练习图文摘录(三)
例如:
在后台的很多实际应用中都存在这很多的内容编辑的处理,所以我们需要使用到的是【富文本编辑器】
参考官网即可:https://www.wangeditor.com/v5/for-frame.html#vue3
yarn add @wangeditor/editor
# 或者 npm install @wangeditor/editor --save
yarn add @wangeditor/editor-for-react
# 或者 npm install @wangeditor/editor-for-react --save
https://stackblitz.com/edit/vue3-wangeditor-demo?file=src%2Fcomponents%2FBasicEditor.vue
CREATE TABLE `t_news` (
`id` INT ( 11 ) NOT NULL AUTO_INCREMENT COMMENT '公告主键编号',
`title` VARCHAR ( 255 ) DEFAULT NULL COMMENT '标题',
`content` TEXT COMMENT '内容',
`author` VARCHAR ( 255 ) DEFAULT NULL COMMENT '作者',
`create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
`update_time` DATETIME DEFAULT NULL COMMENT '修改时间',
`create_user` INT ( 11 ) DEFAULT NULL COMMENT '创建用户编号',
`update_user` INT ( 11 ) DEFAULT NULL COMMENT '修改公告用户编号',
`deleted` INT ( 11 ) DEFAULT '0' COMMENT '逻辑删除【默认值为0】',
PRIMARY KEY ( `id` )
) ENGINE = INNODB AUTO_INCREMENT = 8 DEFAULT CHARSET = utf8;
注意实体对象的中如果有时间可以通过JSONFormat注解实现【前端的时间解析就可以去除】
<!-- 添加公告的对话框 --> <el-dialog v-model="dialogVisible" title="公告信息" width="80%"> <el-form :model="form" label-width="120px" > <el-form-item label="公告标题:"> <el-input v-model="form.title" style="width: 80%;" /> </el-form-item> <!-- <el-form-item label="作 者:"> <el-input v-model="form.author" style="width: 80%;" /> </el-form-item> --> <!-- 公告的内容 --> <el-form-item label="内 容:"> <div style="border: 1px solid #ccc"> <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" /> <Editor style="height: 400px; overflow-y: hidden;" v-model="form.content" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" @onChange="handleChange" @onDestroyed="handleDestroyed" @onFocus="handleFocus" @onBlur="handleBlur" @customAlert="customAlert" @customPaste="customPaste" /> </div> </el-form-item> </el-form> <template #footer> <span class="dialog-footer"> <el-button @click="dialogVisible = false">取消</el-button> <el-button type="primary" @click="save">确认</el-button> </span> </template> </el-dialog>
参照文档使用vue3的特性来写
<script> import { getData, postData } from "../utils/remote"; import '@wangeditor/editor/dist/css/style.css' // 引入 css import {h} from "vue" import { onBeforeUnmount, ref, shallowRef, onMounted,reactive,toRefs } from 'vue' import { Editor, Toolbar } from '@wangeditor/editor-for-vue' import { ElNotification } from "element-plus"; export default { name:"News", components: { Editor, Toolbar }, setup() { const state=reactive({ form: {}, total: 0, dialogVisible: false, search: "", currentPage: 1, pageSize: 5, tableData: [] }); // 编辑器实例,必须用 shallowRef,重要! const editorRef = shallowRef(); // 内容 HTML const valueHtml = ref('<p>hello</p>'); // 模拟 ajax 异步获取内容 onMounted(() => { setTimeout(() => { valueHtml.value = '<p>模拟 Ajax 异步设置内容</p>'; }, 1500); }); const toolbarConfig = {}; const editorConfig = { placeholder: '请输入内容...' }; // 组件销毁时,也及时销毁编辑器,重要! onBeforeUnmount(() => { const editor = editorRef.value; if (editor == null) return; editor.destroy(); }); // 编辑器回调函数 const handleCreated = (editor) => { console.log('created', editor); editorRef.value = editor; // 记录 editor 实例,重要! }; const handleChange = (editor) => { console.log('change:', editor.getHtml()); }; const handleDestroyed = (editor) => { console.log('destroyed', editor); }; const handleFocus = (editor) => { console.log('focus', editor); }; const handleBlur = (editor) => { console.log('blur', editor); }; const customAlert = (info, type) => { alert(`【自定义提示】${type} - ${info}`); }; const customPaste = (editor, event, callback) => { console.log('ClipboardEvent 粘贴事件对象', event); // 自定义插入内容 // editor.insertText('xxx'); // 返回值(注意,vue 事件的返回值,不能用 return) // callback(false); // 返回 false ,阻止默认粘贴行为 callback(true) // 返回 true ,继续默认的粘贴行为 }; const insertText = () => { const editor = editorRef.value; if (editor == null) return; editor.insertText('hello world'); }; const printHtml = () => { const editor = editorRef.value; if (editor == null) return; console.log(editor.getHtml()); }; const disable = () => { const editor = editorRef.value; if (editor == null) return; editor.disable() }; load(); //查询所有的公告信息 function load(){ getData("news/loadAllByPage", { pageNum: state.currentPage, pageSize: state.pageSize, search: state.search, }).then((res) => { console.log(res); state.tableData = res.data.records; state.total = res.data.total; }); } //打开新增公告的对话框 function add(){ state.dialogVisible = true; state.form = {}; handleCreated(); } //点击保存触发的事件 function save(){ const editor=editorRef.value; if(editor==null)return; state.form.content=editor.getHtml(); console.log("获取的内容:"+editor.getHtml()); //新增和修改是共用的 if(state.form.id){ //更新 //获取当前登录的用户名 let users=JSON.parse(sessionStorage.getItem("user")||"{}"); state.form.author=users.nickname; //发起请求 postData("news/edit",state.form).then(res=>{ console.log(res.data); if (res.data) { ElNotification({ title: "温馨提示", message: h("i",{style:'color:teal'},"成功修改公告信息!"), type: 'success' }); } else { ElNotification({ title: "温馨提示", message: h("i",{style:'color:teal'},"修改公告信息失败!"), type: 'error' }); } state.dialogVisible = false; load();//重新加载信息 }); }else{ //新增 //获取当前登录的用户名 let users=JSON.parse(sessionStorage.getItem("user")||"{}"); state.form.author=users.nickname; //发起请求 postData("news/save",state.form).then(res=>{ console.log(res.data); if (res.data) { ElNotification({ title: "温馨提示", message: h("i",{style:'color:teal'},"成功发布公告信息!"), type: 'success' }); } else { ElNotification({ title: "温馨提示", message: h("i",{style:'color:teal'},"发布公告信息失败!"), type: 'error' }); } state.dialogVisible = false; load();//重新加载信息 }); } } function handleEdit(row){ if(!editorRef){ const editors=editorRef.value; editors.insertText(row.content); } state.form=JSON.parse(JSON.stringify(row)); state.dialogVisible=true; } function handleDelete(id){ postData("news/"+id).then(res=>{ if (res.data) { ElNotification({ title: "温馨提示", message: h("i",{style:'color:teal'},"成功删除公告信息!"), type: 'success' }); load();//重新加载 } else { ElNotification({ title: "温馨提示", message: h("i",{style:'color:teal'},"删除公告信息失败!"), type: 'error' }); } }); } function handleSizeChange(pageSize) { //改变当前页的页大小触发 state.pageSize = pageSize; load(); } function handleCurrentChange(pageNum) { //改变当前页的时候触发 state.currentPage = pageNum; load(); } return { ...toRefs(state), editorRef, valueHtml, mode:"default", // 或 'simple' toolbarConfig, editorConfig, handleCreated, handleChange, handleDestroyed, handleFocus, handleBlur, customAlert, customPaste, load, add, insertText, printHtml, disable, save, handleSizeChange, handleCurrentChange, handleEdit, handleDelete }; } }
//点击保存触发的事件 function save(){ const editor=editorRef.value; if(editor==null)return; state.form.content=editor.getHtml(); console.log("获取的内容:"+editor.getHtml()); //新增和修改是共用的 if(state.form.id){ //更新 //获取当前登录的用户名 let users=JSON.parse(sessionStorage.getItem("user")||"{}"); state.form.author=users.nickname; //发起请求 postData("news/edit",state.form).then(res=>{ console.log(res.data); if (res.data) { ElNotification({ title: "温馨提示", message: h("i",{style:'color:teal'},"成功修改公告信息!"), type: 'success' }); } else { ElNotification({ title: "温馨提示", message: h("i",{style:'color:teal'},"修改公告信息失败!"), type: 'error' }); } state.dialogVisible = false; load();//重新加载信息 }); }else{ //新增 //获取当前登录的用户名 let users=JSON.parse(sessionStorage.getItem("user")||"{}"); state.form.author=users.nickname; //发起请求 postData("news/save",state.form).then(res=>{ console.log(res.data); if (res.data) { ElNotification({ title: "温馨提示", message: h("i",{style:'color:teal'},"成功发布公告信息!"), type: 'success' }); } else { ElNotification({ title: "温馨提示", message: h("i",{style:'color:teal'},"发布公告信息失败!"), type: 'error' }); } state.dialogVisible = false; load();//重新加载信息 }); } } function handleEdit(row){ if(!editorRef){ const editors=editorRef.value; editors.insertText(row.content); } state.form=JSON.parse(JSON.stringify(row)); state.dialogVisible=true; }
package com.xuguoguo.controller; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.xuguoguo.commons.Result; import com.xuguoguo.entity.Book; import com.xuguoguo.entity.News; import com.xuguoguo.service.NewsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; /** @Package: com.xuguoguo.controller @ClassName: BookController @Author: XuGuoGuo @CreateTime: 2023/12/12-16:40 @Description: */ @RestController @RequestMapping("/news") public class NewsController { //注入service @Autowired private NewsService newsService; @RequestMapping("/loadAll") public Result loadAll(){ List<News> list = newsService.list(); return Result.of(list); } @RequestMapping("/loadAllByPage") public Result loadAllByPage(@RequestParam("pageNum")Integer pageNum, @RequestParam("pageSize")Integer pageSize, String search){ //通过分页的插件【拦截器】 Page<News> pages = new Page<>(pageNum, pageSize); //构造条件构造器 QueryWrapper<News> bookQueryWrapper = new QueryWrapper<>(); if (search!=null&& !"".equals(search)) { bookQueryWrapper.like("title",search); } Page<News> page = newsService.page(pages, bookQueryWrapper); return Result.of(page); } @RequestMapping("/save") public Result save(@RequestBody News news){ //调用service实现新增用户 boolean save = newsService.save(news); return Result.of(save); } @RequestMapping("/edit") public Result edit(@RequestBody News news){ boolean b = newsService.updateById(news); return Result.of(b); } @RequestMapping("/{id}") public Result deleted(@PathVariable("id")Integer id){ boolean b = newsService.removeById(id); return Result.of(b); } @RequestMapping("/delBatch") public Result delBatch(@RequestBody List<Integer> ids){ //调用service中的批量删除实现 boolean b = newsService.removeBatchByIds(ids); return Result.of(b); } }
vue前端与后端分离的小练习就到此结束了,大家可以自行练习,加强学习哦!~~~ 有问题可留言或者评论私我~
小章节完毕,敬请期待后续更新(可留言需要学习哪方面的内容哈)!如果需要源码的朋友们可关注微信公众号"锅锅编程生活"或者扫描二维码关注回复关键字/后台留言获取即可!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。