首页
留言
导航
统计
Search
1
追番推荐!免费看动漫的网站 - 支持在线观看和磁力下载
829 阅读
2
PVE自动启动 虚拟机 | 容器 顺序设置及参数说明
491 阅读
3
一条命令,永久激活!Office 2024!
452 阅读
4
优选 Cloudflare 官方 / 中转 IP
334 阅读
5
[Windows] MicroSoft Office LTSC Professional Plus 2024 官方安装部署工具
328 阅读
默认分类
服务器
宝塔
VPS
Docker
OpenWRT
Nginx
群晖
前端编程
Vue
React
Angular
NodeJS
uni-app
后端编程
Java
Python
SpringBoot
SpringCloud
流程引擎
检索引擎
Linux
CentOS
Ubuntu
Debian
数据库
Redis
MySQL
Oracle
虚拟机
VMware
VirtualBox
PVE
Hyper-V
计算机
网络技术
网站源码
主题模板
登录
Search
标签搜索
Java
小程序
Redis
SpringBoot
docker
Typecho
Cloudflare
虚拟机
WordPress
uni-app
CentOS
docker部署
Vue
Java类库
群晖
Linux命令
防火墙配置
Mysql
脚本
计算机网络
流年微醺
累计撰写
256
篇文章
累计收到
8
条评论
首页
栏目
默认分类
服务器
宝塔
VPS
Docker
OpenWRT
Nginx
群晖
前端编程
Vue
React
Angular
NodeJS
uni-app
后端编程
Java
Python
SpringBoot
SpringCloud
流程引擎
检索引擎
Linux
CentOS
Ubuntu
Debian
数据库
Redis
MySQL
Oracle
虚拟机
VMware
VirtualBox
PVE
Hyper-V
计算机
网络技术
网站源码
主题模板
页面
留言
导航
统计
搜索到
7
篇与
的结果
2024-07-31
还学鸿蒙原生?vue3 + uniapp 可以直接开发鸿蒙啦!
前言7月20号,uniapp 官网 “悄咪咪” 的上线了 uniapp 开发鸿蒙应用 的文档,算是正式开启了 Vue3 + uniapp 开发鸿蒙应用 的时代。开发鸿蒙的前置准备想要使用 uniapp 开发鸿蒙,我们需要具备三个条件:DevEco-Studio 5.0.3.400 以上(下载地址:https://developer.huawei.com/consumer/cn/deveco-studio/)鸿蒙系统版本 API 12 以上 (DevEco-Studio有内置鸿蒙模拟器)HBuilderX-alpha-4.22 以上PS: 这里不得不吐槽一下,一个 DevEco-Studio 竟然有 10 个 G......[安装好之后,我们就可以通过 开发工具 运行 示例代码]运行时,需要用到 鸿蒙真机或者模拟器。但是这里需要 注意: Windows系统需要经过特殊配置才可以启动,mac 系统最好保证系统版本在 mac os 12 以上windows 系统配置方式(非 windows 用户可跳过): 打开控制面板 - 程序与功能 - 开启以下功能Hyper-VWindows 虚拟机监控程序平台虚拟机平台注意: 需要win10专业版或win11专业版才能开启以上功能,家庭版需先升级成专业版或企业版启动鸿蒙模拟器整个过程分为三步(中间会涉及到鸿蒙开发者申请):下载 uni-app 鸿蒙离线SDK template-1.3.4.tgz (下载地址:https://web-ext-storage.dcloud.net.cn/uni-app/harmony/zip/template-1.3.4.tgz)解压刚下载的压缩包,将解压后的模板工程在 DevEco-Studio 中打开等待 Sync 结束,再 启动鸿蒙模拟器 或 连接鸿蒙真机(如无权限,则需要申请(一般 3 个工作日),申请地址:https://developer.huawei.com/consumer/cn/activity/201714466699051861/signup)配置 HBuilderX 吊起 DevEco-Studio打开HBuilderX,点击上方菜单 - 工具 - 设置,在出现的弹窗右侧窗体新增如下配置[注意:值填你自己的 DevEco-Studio 启动路径]"harmony.devTools.path" : "/Applications/DevEco-Studio.app"创建 uni-app 工程BuilderX 新建一个空白的 uniapp 项目,选vue3在 manifest.json 文件中配置鸿蒙离线SDK路径(SDK 路径可在 DevEco-Studio -> Preferences(设置) z中获取)编辑 manifest.json 文件,新增如下配置:然后点击 运行到鸿蒙即可最后这样我们就有了一个初始的鸿蒙项目,并且可以在鸿蒙模拟器上运行。关于更多 uniapp 开发鸿蒙的 API,大家可以直接参考 uniapp 官方文档:https://zh.uniapp.dcloud.io/tutorial/harmony/dev.html#nativeapi
2024年07月31日
20 阅读
0 评论
0 点赞
2024-05-28
实战:element-ui 树型控件自定义图标(给节点添加图标)
效果图:<el-input v-model="searchVal" placeholder="请输入关键词" clearable style="margin-bottom: 12px" /> <div class="treeBox"> <el-tree :data="sourceData" node-key="id" default-expand-all :expand-on-click-node="false" :props="defaultProps" @node-click="handleNodeClick" > // 重点:给节点添加图标 <span slot-scope="{ node, data }" class="slot-t-node"> <template> <i :class="{ 'el-icon-folder': !node.expanded, // 节点收缩时的图标 'el-icon-folder-opened': node.expanded, // 节点展开时的图标 'el-icon-user-solid': data.type === 2 // data.type是后端配合提供的识别字段,最后一级 }" style="color: #409eff;" // 图标颜色 /> <span>{{ node.label }}</span> </template> </span> </el-tree> </div>data() { return { searchVal: '', // 输入的关键词 defaultProps: { children: 'childrenList', // 将tree中的每项的 childrenList 映射为 children label: 'name' // 将tree中的每项的 name 映射为 label }, sourceData: [ // 树源数据 { id: null, name: '深圳市XXX有限公司', parentId: '0', childrenList: [ { id: null, name: '研发中心', parentId: '1', childrenList: [ { id: null, name: '研发1组', parentId: '2', childrenList: [ { id: null, name: 'IOS测试机', parentId: null, childrenList: null, type: 2 } ], type: 1 }, { id: null, name: '安卓测试机', parentId: null, childrenList: null, type: 2 } ], type: 1 }, { id: null, name: '产品中心', parentId: '1', childrenList: [], type: 1 }, { id: null, name: '员工1', parentId: null, childrenList: null, type: 2 }, { id: null, name: '员工12', parentId: null, childrenList: null, type: 2 }, { id: null, name: '员工13', parentId: null, childrenList: null, type: 2 } ], type: 1 } ] } }, methods: { // 节点点击时 handleNodeClick(data) { // 。。。 } }
2024年05月28日
16 阅读
0 评论
0 点赞
2024-03-18
vue2到vue3中插槽slot变化详解---从slot,slot-scope到v-slot的变化
前言vue 插槽,目前到3.0有2种方式,第一种,在2.6之前使用的是 slot 和 slot-scpe 2.6后已被官方废弃,但在2.x版本仍被支持,第二种是vue 在2.6版本后更新的新指令 v-slot 来替代slot 和 slot-scpe那么什么是插槽呢,作用又是什么插槽,简单说,插槽就是杯子,杯子里面装的是饮料还是牛奶,由外部倒入什么来决定 ,就好比下面的代码,我需要一个子组件,他有部分内容,需要根据我当前页面需要来展示,我如何将html模板传人到子组件就需要使用插槽。所以我定义了一个子组件item,我用solt标签定义了一个默认插槽,为在父组件使用时,需要传递到item组件的模板,占个位置, 这样我在组件,使用item子组件,在其中编写,html模板就会被渲染到子组件默认插槽//父组件 <template> <tab> <item > <div>装一杯牛奶</div> <item> <tab> </template> //item子组件 <template> <div> <slot ></slot>//默认插槽 在父组件使用item子组件,item标签包裹的内容将默认被渲染到子组件的 solt中 <h1> 我是杯子 </h1> </div> </template>这样的好处,显而易见,可以让组件模块化更清晰,同时复用性更高,不至于,我要一杯茶,我就要定义一个组件,我要一杯牛奶我又定义一个组件,有了插槽,我只需要定义一个杯子,要喝什么由使用的传人决定。上述代码也叫默认插槽,就是默认把模板全部渲染到solt中,如果需要指定渲染,就需要使用具名插槽,简单说就是起一个名字,告诉他小红该坐那儿,小明该坐那儿具名插槽//父级 <template> <div> <layout> <div solt="header">头部标题</div> <div >显示的内容</div> <div slot="footer">尾部</div> </layout> </div> </template> //layout子组件 <template> <div> <layout> <h1>layout子组件</h1> <slot name="header"></slot> //这种就叫具名插槽 <slot></slot> //如果不指定名字,就会将模板中未匹配到的内容渲染到默认插槽中,这里为显示的内容 <slot name="footer"></slot> </layout> </div> </template>上面已说, 具名插槽 简单说就是起一个名字,告诉他小红该坐那儿,小明该坐那儿tip: 当你的子组件中 如layout 中并不存在,slot这个元素,那么在父页面中 这个标签中的内容都会被抛弃作用域插槽父组件提供了模板给子组件,那么子组件如何反馈给父组件呢,例如:我定义了一个杯子,我需要告诉使用的人,我这个杯子,只能装300mL,这时我们就需要用slot-scope来接收子组件上通过v-bind绑定的值。作用域插槽,就是能让插槽内容访问到子组件中才有的数据//父级 <template> <div> <cup> <div solt="size" slot-scope="data"> {{data.msg}} </div> </cup> </div> </template> //cup子组件 <template> <div> <slot name="size" :msg="msg"></slot> </div> </template> <script> export default { data(){ return{ msg:'300mL大小的杯子' } } } </script>解构prop的写法下面写法等同上面//父级 <template> <div> <cup> <div slott="size" slot-scope="{msg}"> {{msg}} </div> </cup> </div> </template>上述是vue2.6之前的版本,之后vue官方废弃了上面的语法,改为v-solt来代替,然后大家就想知道,区别在哪呢首先就是 用一个指令合并了solt 和solt-scope2个attribute,写法更加简洁,其次就是语义化更明显2.6之前的写法会出现作用域混淆的问题例:<one> <two slot-scope="one"> //接受到的作用域,是外层one组件的,而不是当前组件two <three slot-scope="two"> <template slot-scope="three"> {{ one }} {{ two }} {{ three }} </template> </three> </two> </one>如上述代码一层子组件时,你能清晰的看清作用域是哪一个组件的,但多层嵌套后,每一层接收的作用域是外层组件的而不是当前组件的,这样,就会不清晰,所以vue希望能实现,当前组件,接受当前组件的作用域于是就有了v-solt 下面是改良后的代码,是否更加的清晰了<one v-slot="one"> <twotwo v-slot="two"> //接收到的作用域为当前two组件的 <three v-slot="three"> {{ one }} {{ two }} {{ three }} </three> </bar> </one>如果没看懂 那么下面来阐述,v-solt的使用变化,v-solt 默认插槽和原来不同便是,原来的solt属性可以定义在任何元素上,现在v-solt只能是template元素上,只有一种额外情况,就是独占默认插槽,我们先看常规情况。v-slot:default这种就是具名的写法//父组件 <template> <item > <template v-slot:default> // v-slot:default可以不加,只能定义在template上 <div>装一杯牛奶</div> </template> <item> </template> //item子组件 <template> <div> <slot ></slot>//默认插槽 <h1> 我是杯子 </h1> </div> </template>未具名的solt 元素,自动默认名为default 你可以不写,当然如果你要看的更清晰,独占默认插槽提供内容只有默认插槽,上述就满足此条件,所以我们可以这样写//父组件 <template> <item v-slot:default> //v-slot:default可以不加 <div>装一杯牛奶</div> <item> </template> //item子组件 <template> <div> <slot ></slot>//默认插槽 <h1> 我是杯子 </h1> </div> </template>v-solt具名插槽//父级 <template> <div> <layout> <template v-slot:header>//v-slot指令使用插槽 <div >头部标题</div> </template> <div >显示的默认内容</div> <!-- 或者 <template v-slot:default> <div >显示的默认内容</div> </template> --> <template v-slot:footer> <div >尾部</div> </template> </layout> </div> </template> //layout子组件 <template> <div> <layout> <h1>layout子组件</h1> <slot name="header"></slot> //这种就叫具名插槽 <slot></slot> //如果不指定名字,就会将模板中未匹配到的内容渲染到默认插槽中,这里为显示的内容 <slot name="footer"></slot> </layout> </div> </template>v-solt作用域插槽这是改动最大地方//父级 <template> <div> <cup> <template v-slot:default="data"> //具名写法 <div> {{data.msg}} </div> </template> <!-- 或者 <template v-slot="data"> <div > {{data.msg}} </div> </template> --> </cup> </div> </template> //cup子组件 <template> <div> <slot :msg="msg"></slot > </div> </template> <script> export default { data(){ return{ msg:'300mL大小的杯子' } } } </script>当为独占默认插槽时,v-solt可以省略default不写注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确下面是官方的例子<!-- 无效,会导致警告 --> <current-user v-slot="slotProps"> {{ slotProps.user.firstName }} <template v-slot:other="otherSlotProps"> slotProps is NOT available here </template> </current-user>所以当出现多个插槽的时候,请使用完整的基于 template 的语法解构props的写法这里使用上面cup组件的例子<template> <div> <cup> <template v-slot:default="{msg}"> //解构 <div> {{msg}} </div> </template> </cup> </div> </template>v-slot 的解构还提供 重命名的写法<template> <div> <cup> <template v-slot:default="{msg : size}"> //别名 <div> {{size}} </div> </template> </cup> </div> </template>动态插槽名v-slot 支持2.6的动态参数写法<layout> <template v-slot:[attributeName]> ... </template> </layout>这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data property attributeName,其值为 "header",那么这个绑定将等价于 v-slot:header。插槽的缩写2.6后插槽 可以把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #headerv-slot: 后面必须有值,不可写成#="{data}"<template> <div> <cup> <template #default="msg"> <div> {{size}} </div> </template> </cup> </div> </template>
2024年03月18日
39 阅读
0 评论
0 点赞
2023-07-11
前后端分离,开源的 Spring Boot + Vue 3.2 的博客,泰裤辣!
WeBlog简介一款由 Spring Boot + Vue 3.2 开发的前后端分离博客。{mtitle title="Weblog 后台仪"/}后端采用 Spring Boot 、Mybatis Plus 、MySQL 、Spring Sericuty、JWT、Minio、Guava 等;后台管理采用 Vue 3.2 + Element Plus 纯手写的管理后台,未采用任何 Admin 框架;支持博客 Markdown 格式发布与编辑、文章分类、文章标签的管理;支持博客基本信息的设置,以及社交主页的跳转;支持仪表盘数据统计,Echarts 文章发布热图统计、PV 访问量统计;相关地址GitHub 地址:https://github.com/weiwosuoai/WeBlogGitee 地址:https://gitee.com/AllenJiang/WeBlog演示地址:http://118.31.41.16:8081/游客账号:test游客密码:test演示截图登录页仪表盘文章管理写博客前台首页博客详情功能前台功能是否完成首页✅分类列表✅标签标签✅博客详情✅站内搜索TODO知识库 WikiTODO博客评论TODO后台功能是否完成后台登录页✅仪表盘✅文章管理✅分类管理✅标签管理✅博客设置✅评论管理TODO模块介绍{mtitle title="WeBlog 项目模块一览"/}项目名说明weblog-springboot后端项目weblog-vue3前端项目后端项目模块介绍模块名说明weblog-module-admin博客后台管理模块weblog-module-common通用模块weblog-module-jwtJWT 认证、授权模块weblog-web博客前台(启动入口)技术栈后端框架说明版本号备注JDKJava 开发工具包1.8它是目前企业项目比较主流的版本Spring BootWeb 应用开发框架2.6.3主流框架Maven项目构建工具3.6.3企业主流的构建工具MySQL数据库5.7 Mybatis PlusMybatis 增强版持久层框架3.5.2 HikariCP数据库连接池4.0.3Spring Boot 内置数据库连接池,号称性能最强Spring Security安全框架2.6.3 JWTWeb 应用令牌0.11.2 Lombok消除冗余的样板式代码1.8.22 JacksonJSON 工具库2.13.1 Hibernate Validator参数校验组件6.2.0.Final Logback日志组件1.2.10 GuavaGoogle 开源的工具库18.0 p6spy动态监测框架3.9.1 Minio对象存储8.2.1用于存储博客中相关图片flexmarkMarkdown 解析0.62.2 前端框架说明版本号Vue 3Javascript 渐进式框架3.2.47Vite前端项目构建工具4.3.9Element Plus饿了么基于 Vue 3 开源的组件框架2.3.3vue-routerVue 路由管理器4.1.6vuex状态存储组件4.0.2md-editor-v3Markdown 编辑器组件3.0.1windicssCSS 工具类框架3.5.6axios基于 Promise 的网络请求库1.3.5Echarts百度开源的数据可视化图表库5.4.2
2023年07月11日
21 阅读
0 评论
0 点赞
2023-02-17
vue项目中使用elementUI的el-tabs组件跳转卡死问题
解决方案1:在页面上使用了el-tabs元素的页面(log.vue),使用el-row el-col元素来包裹el-tabs元素,也可以解决页面卡死问题<tempalte> <div class="log-box"> <el-row> <el-col :span="24"> <el-tabs> <el-tab-pane>1111</el-tab-pane> <el-tab-pane>22222</el-tab-pane> </el-tabs> </el-col> </el-row> </div> </template>解决方案2:在el-tabs标签上面,加一个兄弟节点–空的块级元素<tempalte> <div class="log-box"> <div> </div> <el-tabs> <el-tab-pane>1111</el-tab-pane> <el-tab-pane>22222</el-tab-pane> </el-tabs> </div> </template>此块级元素,要占位dom内容,但不设置宽高,即不影响页面为主;解决方案3:降级elementUI版本到2.6.3,或者升级vue版本到2.6x+解决方案4:vue(2.5.2)版本过低时 elment版本过高,会出现这个问题,解决方法:终端输入 npm audit fix 命令执行即可
2023年02月17日
52 阅读
0 评论
0 点赞
2023-02-16
Docker部署 Mysql、redis、Rabbitmq、Vue、Java 项目
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux 或 Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。本文主要讲解如何在Linux环境下使用 Docker 部署前后端分离项目,其中涉及到使用 Docker 安装本人项目相关的一些环境 ,例如mysql、rabbitmq、redis,基于CenterOS7.0。Docker 环境安装1.安装 Docker 客户端# step 1: 安装必要的一些系统工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # Step 2: 添加软件源信息 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # Step 3: 更新并安装 Docker-CE sudo yum makecache fast sudo yum -y install docker-ce # Step 4: 开启Docker服务 sudo service docker start2.配置镜像加速器sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://sq2b0kv9.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker安装 PortainerPortainer 是一个轻量级 Web 端的 Docker 管理 UI,Portainer 够轻松地管理不同的 Docker 环境(Docker 主机或集群)。Portainer 的部署和使用十分简单。Portainer 可以部署为 Linux 容器或 Windows 本机容器,也支持其他平台。Portainer 允许您管理所有 Docker 资源(容器、映像、卷、网络等)!它与独立的 Docker 引擎和 Docker 集群模式兼容。1.安装# 拉取官方镜像 docker pull portainer/portainer # 运行镜像到容器 docker run -d -p 9000:9000\ --restart=always\ -v /var/run/docker.sock:/var/run/docker.sock\ -m 20M --oom-kill-disable --memory-swap=-1\ --name portainer\ portainer/portainer2.访问页面访问地址:http://localhost:9000,第一次打开需要设置用户名、密码,docker 模式我一般选择 Local 本机模式。通过此工具我们可以更加简便的对镜像和容器进行操作和管理。登录页 面板页 安装 mysql# docker search mysql 可通过此命令查看可用版本 # 拉取mysql镜像,默认会拉取最新版本,我这里加上版本号 docker pull mysql:8.0.0 # 查看镜像是否拉取成功 docker images # 在/home/docker/mysql目录下创建mysql挂载目录 mkdir {data,logs,conf} # 运行容器 docker run -d -p 3306:3306 -v /home/docker/mysql/my.cnf:/etc/mysql/conf.d/mysqld.cnf -v /home/docker/mysql/data:/var/lib/mysql -v /home/docker/mysql/logs:/var/log/mysql -e MYSQL_ROOT_PASSWORD=12345 --name mysql_test mysql:8.0.0说明:--name:容器名-e:配置信息,此处配置 mysql 的 root 用户登陆密码-d:后台运行容器,保证在退出终端后容器继续运行-p:端口映射,此处映射 主机 3306 端口 到 容器的 3306 端口-v:挂载目录此处需要注意不要直接挂载容器中的 mysql 配置文件目录,可能会将容器内的配置文件目录清空。个人建议将容器中的 my.cnf 文件复制出来进行选择性的修改,再挂载 mysql.cnf 文件即可。docker cp :用于容器与主机之间的数据拷贝。# 语法 docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|- # 实例 docker cp 96f7f14e99ab:/etc/mysql/conf.d/mysqld.cnf /home/docker/mysql/my.cnf安装 redis因为 redis 默认配置只能够本地连接,不能进行远程访问,使用 Redis 客户端工具连接都会报错,因此需要手动挂载 redis 配置文件。# /home/docker/redis目录下新增挂载文件夹 mkdir {data,conf} # 下载最新版本的Redis镜像 docker pull redis # 新增redis配置文件 cd /home/docker/redis/conf touch redis.conf vim redis.conf添加以下内容#bind 127.0.0.1 protected-mode no appendonly yes requirepass 123456说明:bind 127.0.0.1 ,注释掉这部分,这是限制 redis 只能本地访问protected-mode:默认 yes,开启保护模式,限制为本地访问appendonly:redis 持久化(可选)requirepass:设置访问密码为 123456运行容器docker run --name myredis -p 6379:6379 -v /home/docker/redis/data:/data -v /home/docker/redis/conf/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf说明:--name:容器名称-p :表示将服务器的 6379(冒号前的 6379)端口映射到 docker 的 6379(冒号后的 6379)端口-d :表示以后台服务的形式运行 redis-v :挂载宿主机目录redis redis-server /etc/redis/redis.conf:表示运行 redis 服务器程序,并且指定运行时的配置文件经过以上步骤,便可以通过 redis 客户端工具进行连接,如果连接不上,检查安全组和服务器防火墙端口是否开放安装 rabbitmq# 拉取带图形化管理界面的镜像 docker pull rabbitmq:3.7.7-management # 根据下载的镜像创建和启动容器 docker run -d --name rabbitmq3.7.7 -p 5672:5672 -p 15672:15672 -v `pwd`/data:/var/lib/rabbitmq --hostname myRabbit -e RABBITMQ_DEFAULT_VHOST=my_vhost -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin df80af9ca0c9说明:-d:后台运行容器;--name:指定容器名;-p:指定服务运行的端口(5672:应用访问端口;15672:控制台 Web 端口号);-v:映射目录或文件;--hostname :主机名(RabbitMQ 的一个重要注意事项是它根据所谓的 “节点名称” 存储数据,默认为主机名);-e:指定环境变量;(RABBITMQ_DEFAULT_VHOST:默认虚拟机名;RABBITMQ_DEFAULT_USER:默认的用户名;RABBITMQ_DEFAULT_PASS:默认用户名的密码)Rabbitmq 访问地址:http://localhost:15672 至此,基本的运行环境都安装完毕,下面就是关键的打包步骤了。Vue 前端项目打包将 dist 下的所有文件目录拷贝到 SpringBoot 后端项目的 resources\static 目录下,static 目录需要新建。如果你的项目中用到了 shiro 或者 spring security 等安全框架,需要对静态资源放行。以上配置完成后,先在本地运行,再用 maven 进行打包。将 jar 包上传到服务器后,就要开始制作自己的镜像了,首先在与 jar 包同目录下新建 Dockerfile 文件。# 新建Dockerfile文件 touch Dockerfile # 编写Dockerfile文件 vim Dockerfile加入以下内容# Docker image for springboot file run # VERSION 0.0.1 FROM java:8 # VOLUME 指定了临时文件目录为/tmp。 # 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp VOLUME /tmp # 将jar包添加到容器中并更名为app.jar ADD demo-01.jar app.jar # 运行jar包 RUN bash -c 'touch /app.jar' ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]执行 docker build -t [镜像名称] . ,至此镜像文件就制作完成了。docker images查看镜像是否存在。最后一步,创建并启动容器,docker run --name [容器名称] -d -p 80:8080 [镜像名]。
2023年02月16日
33 阅读
0 评论
0 点赞
2023-02-15
VUE后台管理中使用富文本编辑器导入word 文档进行编辑
前言最近因业务需求在项目中嵌入了[tinymce]这个编辑器,用于满足平台给用户编辑各类新闻内容什么的业务需求,前后也花了不少时间体验和对比了市面上各类开源编辑器,直接将新闻部门的工作从半天工作量提升只要一个小时就可以搞到,一两分钟就可以搞定一个任务优点文档好,功能强,bug 少,无外部依赖。word 文档粘贴进来要带格式 兼容移动端 word 文档粘贴进来要正常显示并且还要兼容移动端 电脑网页里粘贴进来内容要正常显示并且排版还不能乱 电脑网页拷过来的内容还要兼容到移动端安装npm install tinymce @tinymce/tinymce-vue@3.2.8 -S下载语言包中文语言包下载开始操作文件将依赖包 node_modules 里找到 tinymce文件夹,复制到 public 里,【左图是 tinymce,右图是 public 复制后的目录】一下是注意点:很多的博客的写法是将 node_modules 里面的skins文件夹复制到public/tinymce目录下,经过尝试是不完善的,需要将整个目录倒入进 public 里不完全导入的错误显示,我还以为是语言包的问题,一个个语言包版本去试,这种展示一半英文一半中文的导入 tinymcejspublic/index.html 添加 tinymce.js<div id="app"></div> <script src="/tinymce/tinymce.min.js"></script>引入基本文件// 引入组件 import tinymce from 'tinymce/tinymce' import Editor from '@tinymce/tinymce-vue' // 引入富文本编辑器主题的js和css import 'tinymce/themes/silver/theme.min.js' import 'tinymce/skins/ui/oxide/skin.min.css' // 扩展插件 import 'tinymce/plugins/image' import 'tinymce/plugins/link' import 'tinymce/plugins/code' import 'tinymce/plugins/table' import 'tinymce/plugins/lists' import 'tinymce/plugins/wordcount'注册组件components: { Editor },使用组件<div class="activeConfig-container"> <Editor id="tinymce" v-model="tinymceHtml" :init="editorInit" /> </div>tinymce 初始化配置data() { return { // tinymce的绑定值 tinymceHtml: '', // tinymce的初始化配置 editorInit: { selector: '#tinymce', language_url: '/tinymce/langs/zh_CN.js', language: 'zh_CN', skin_url: '/tinymce/skins/ui/oxide', height: 400, plugins: 'link lists image code table wordcount importword', toolbar: 'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image code | removeformat | importword', //点击富文本图片上传的时候将图片转成base64再通过success插入 images_upload_handler: (blobInfo, success) => { const img = 'data:image/jpeg;base64,' + blobInfo.base64() success(img) }, importword_filter: function(result, insert, message) { // console.log(result) // console.log(insert) // console.log(message) // 自定义操作部分 insert(result) // 回插函数 }, // statusbar: false // 是否隐藏底部的状态栏 // menubar: false, // 是否隐藏最上方的菜单 branding: false // 是否禁用“Powered by TinyMCE” } } },整体代码<template> <div class="activeConfig"> <div class="activeConfig-container"> <Editor id="tinymce" v-model="tinymceHtml" :init="editorInit" /> </div> </div> </template> <script> // 引入组件 import tinymce from 'tinymce/tinymce' import Editor from '@tinymce/tinymce-vue' // 引入富文本编辑器主题的js和css import 'tinymce/themes/silver/theme.min.js' import 'tinymce/skins/ui/oxide/skin.min.css' // 扩展插件 import 'tinymce/plugins/image' import 'tinymce/plugins/link' import 'tinymce/plugins/code' import 'tinymce/plugins/table' import 'tinymce/plugins/lists' import 'tinymce/plugins/wordcount' // import { uploadImgage } from '@/api/activeConfig' export default { name: 'ActiveConfig', components: { Editor }, data() { return { // tinymce的绑定值 tinymceHtml: '', // tinymce的初始化配置 editorInit: { selector: '#tinymce', language_url: '/tinymce/langs/zh_CN.js', language: 'zh_CN', skin_url: '/tinymce/skins/ui/oxide', height: 400, plugins: 'link lists image code table wordcount importword', toolbar: 'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image code | removeformat | importword', // 此处为图片上传处理函数 // images_upload_handler: (blobInfo, success, failure) => { // this.handleImgUpload(blobInfo, success, failure) // }, images_upload_handler: (blobInfo, success) => { const img = 'data:image/jpeg;base64,' + blobInfo.base64() success(img) }, importword_filter: function(result, insert, message) { // console.log(result) // console.log(insert) // console.log(message) // 自定义操作部分 insert(result) // 回插函数 }, // statusbar: false // 是否隐藏底部的状态栏 // menubar: false, // 是否隐藏最上方的菜单 branding: false // 是否禁用“Powered by TinyMCE” } } }, mounted() { tinymce.init({}) }, methods: { // 图片上传 handleImgUpload(blobInfo, success, failure) { // this.baseUrl = process.env.VUE_APP_BASE_URL // const imgBase64 = 'data:image/jpeg;base64,' + blobInfo.base64() // const data = { img: [imgBase64] } // uploadImgage(data).then(res => { // // 传入success回调里的数据就是富文本编辑器里插入图片的src的值 // success(`${this.baseUrl}/${res.data[0]}`) // }).catch(() => { failure('error') }) } } } </script> <style lang="scss" scoped> .activeConfig { &-container { margin: 30px; } } </style>特殊需求需要找个能实现 word 文档上传到富文本编辑器,减轻编辑机构的负担,解决机构需要每次打开文档复制再编辑的繁琐工作,实现直接导入编辑tinymce 插件一个下载插件,一个是注意点,图片在富文本是 base64 的方式导入插件下载解压后将整个文件复制到 public 的插件目录再往 tinymce 配置添加即可editorInit.plugins 和 editorInit.toolbar 添加 importword 即可editorInit: { selector: '#tinymce', language_url: '/tinymce/langs/zh_CN.js', language: 'zh_CN', skin_url: '/tinymce/skins/ui/oxide', height: 400, plugins: 'link lists image code table wordcount importword', toolbar: 'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image code | removeformat | importword' }图片解决方案如果碰到图片的问题,处理图片有两种方式: 1、一种在提交内容的时候统一处理图片,稿件文件里图片只要提交一次。 2、一种是监听图片上传,每次更新图片都上传图片。图片上传函数有images_upload_handler第二种const files = [] const base64ImgSum = [] for (let i = 0; i < imgs.length; i++) { //去除不用的属性 imgs[i].removeAttribute('data-mce-src') imgs[i].removeAttribute('alt') //拿到所有的图片列表 imgs[i].src.includes('base') && base64ImgSum.push(imgs[i]) } //将base64图片转换file文件 dataURLToFile(dataURL, filename) { const arr = dataURL.split(',') const mime = arr[0].match(/:(.*?);/)[1] // mime类型 image/png const bstr = atob(arr[1]) // base64 解码 let n = bstr.length const u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } return new File([u8arr], filename, { type: mime }) // return new Blob([a8arr], {type: mime}); }, //将处理file文件当参处理即可 fd.append('file', this.dataURLToFile(base64ImgSum[i].src, `${(new Date()).getTime()}.jpg`))
2023年02月15日
47 阅读
0 评论
0 点赞