Uniapp项目Web打包部署
为什么不部署小程序
因为小程序部署审核比较严格,还需要备案,而且我现在还没有完全开发完成(研究生开学之后,基本没有时间开发了),到时候再摸索一下吧。之所以还没有开发完成我就部署,是因为我那弱小的服务器已经时日不多了/(ㄒoㄒ)/~~,再不部署就白买了
Web打包前对项目进行调整
客户端的开发是基于uniapp,uniapp的一个优点是支持跨平台,一次开发可以多端适配,即开发一次可以打包成小程序、网站、安卓等程序,但并没有想象的这么简单,不同平台之间支持的组件、功能还是有所差距的,如下图所示。因为之前的开发是根据微信小程序来开发的,如键盘呼出事件的处理、websocket的连接方式、页面的导航条都需要调整
网站、小程序切换
对项目调整让其可以适配网站的前提是不能丧失原有对小程序的适配,因此不能直接修改项目的代码来适配网站,而是增加代码来完成对网站的适配,再增加一个切换开关来控制,这样在打包之前就可以控制是打包为小程序还是网站程序
增加constant.js来控制常量
js
// 类型 0:小程序 1:网站
const softType = 1;
// socket的ip:端口
const socketUrl = '23.23.147.200:8085';
// const socketUrl = '10.23.17.164:8085';
export default {
softType,
socketUrl
}
将js绑定到main.js的全局变量中
js
import Constant from "@/constant/constant.js"
Vue.prototype.Constant = Constant
后面直接使用this.Constant.softType
来获取常量的值即可
WebSocket差异
【连接差异】
js
/**
* 创建websocket连接
*/
initWebsocket() {
// console.log("this.socket:" + JSON.stringify(this.$socket))
// this.$socket == null,刚刚进入首页,还没有建立过websocket连接
// this.$socket.readyState==0 表示正在连接当中
// this.$socket.readyState==1 表示处于连接状态
// this.$socket.readyState==2 表示连接正在关闭
// this.$socket.readyState==3 表示连接已经关闭
let socket = null;
if (this.Constant.softType == 0) {
socket = this.$socket;
} else if (this.Constant.softType == 1) {
socket = this.$store.state.ws;
}
if (socket == null || (socket.readyState != 1 && socket.readyState != 0)) {
// --if--小程序类型
let socketUrl = this.Constant.socketUrl;
// console.log("socketUrl:" + socketUrl)
if (this.Constant.softType == 0) {
this.$socket = uni.connectSocket({
url: "ws://" + socketUrl + "/websocket/" + uni.getStorageSync("curUser")
.userName,
success(res) {
console.log('WebSocket连接成功', res);
},
})
// 监听WebSocket连接打开事件
this.$socket.onOpen((res) => {
console.log("websocket连接成功")
Vue.prototype.$socket = this.$socket;
// 连接成功,开启心跳
this.headbeat();
});
// 连接异常
this.$socket.onError((res) => {
console.log("websocket连接出现异常");
// 重连
this.reconnect();
})
// 连接断开
this.$socket.onClose((res) => {
console.log("websocket连接关闭");
// 重连
this.reconnect();
})
} else if (this.Constant.softType == 1) {
// --if--网站类型
socket = new WebSocket("ws://" + socketUrl + "/websocket/" + uni.getStorageSync(
"curUser")
.userName);
// 网站类型
//监听WebSocket连接打开事件
let _that = this;
socket.onopen = function() {
console.log("websocket连接成功")
// Vue.prototype.Constant.WebSocket = socket;
console.log("常量socket:" + JSON.stringify(socket));
store.commit("SET_WS", socket);
// console.log("Vue.prototype.$socket:" + Vue.prototype.WebSocket)
// 连接成功,开启心跳
_that.headbeat();
};
socket.onmessage = function(msg) {
console.log("接收到socket服务器的数据====" + JSON.stringify(msg))
};
// 连接异常
socket.onerror = function() {
console.log("websocket连接出现异常");
// 重连
_that.reconnect();
};
// 连接断开
socket.onclose = function() {
console.log("websocket连接关闭");
// 重连
_that.reconnect();
};
}
}
},
【发送消息差异】
js
/**
* 发送消息
*/
send() {
if (this.messageInput != '') {
let message = {
from: this.me.userName,
to: this.you.username,
text: this.messageInput
}
// console.log("this.socket.send:" + this.$socket)
// 将组装好的json发送给服务端,由服务端进行转发
if (this.Constant.softType == 0) {
this.$socket.send({
data: JSON.stringify(message)
});
} else if (this.Constant.softType == 1) {
// 网站类型
let socket = this.$store.state.ws;
socket.send(JSON.stringify(message));
}
this.total++;
let newMessage = {
// code: this.messageList.length,
type: 1,
content: this.messageInput
};
this.messageList.push(newMessage);
this.messageInput = '';
this.toBottom();
}
},
【接收消息差异】
js
/**
* 接收消息
*/
receiveMessage() {
if (this.Constant.softType == 0) {
this.$socket.onMessage((response) => {
// console.log("接收消息:" + response.data);
let message = JSON.parse(response.data);
let newMessage = {
// code: this.messageList.length,
type: 0,
content: message.text
};
this.messageList.push(newMessage);
this.total++;
// 让scroll-view自动滚动到最新的数据那里
this.toBottom();
})
} else if (this.Constant.softType == 1) {
// 网站类型
let socket = this.$store.state.ws;
let _that = this;
socket.onmessage = function(response) {
console.log("接收消息:" + response.data);
let message = JSON.parse(response.data);
let newMessage = {
// code: this.messageList.length,
type: 0,
content: message.text
};
_that.messageList.push(newMessage);
this.total++;
// 让scroll-view自动滚动到最新的数据那里
_that.toBottom();
};
}
},
监听键盘呼出
js
onReady() {
// 监听键盘高度变化,以便设置输入框的高度(适用于小程序,不适用于网站)
uni.onKeyboardHeightChange(res => {
if (this.Constant.softType == 0) {
let keyBoardHeight = res.height;
this.chatSuitable(keyBoardHeight);
}
})
},
methods: {
/**
* 键盘呼出(适用于网站)
*/
keyboardUp(value, height) {
if (this.Constant.softType == 1) {
this.chatSuitable(height);
}
},
/**
* 键盘呼出时,聊天框自适应缩短
*/
chatSuitable(keyBoardHeight) {
this.scrollViewHeight = `calc(100vh - 20px - 44px - ${keyBoardHeight}px)`;
this.scrollToView = '';
setTimeout(() => {
this.scrollToView = 'message' + this.messageList[this
.messageList.length - 1].id;
}, 150)
},
}
导航条
使用安卓手机打开网页时,上面已经有导航标题了,因此可以隐藏掉小程序的标题,不然重复的标题显得多余。
uniapp自带的标题无法直接使用代码来隐藏,uniapp只提供了设置导航栏的颜色和内容的方法(可能是我没有找到)
因此我只能想到直接修改配置文件pages.json
的方式,通过设置navigationStyle
为custom
来实现,当需要切换成小程序来打包时,可以通过将custom
替换为default
来实现
打包
uniapp项目的打包h5程序较为简单,首先修改配置文件的运行的基础路径修改为./
,作用是将程序运行的基础路径设为当前路径,而不是默认的根目录,使得程序在不同的环境中更加灵活,可以更方便地进行部署和迁移
修改完成之后,使用菜单栏下面的发行操作即可完成打包
部署
打包成功之后,将这两个文件拖入到服务器的文件夹中即可部署,我部署的方式使用宝塔面板,具体步骤可以学习SpringBoot+Vue 前后端分离 微服务项目 打包部署全流程(原始部署/宝塔部署)的前端部署
下面的宝塔部署
。
后端项目打包部署
后端项目基于若依管理系统进行开发
打包前准备
创建两个配置文件来分别存储开发环境和生产环境的配置,application.yml
可以用来存储开发环境和生产环境的公共配置,例如mysql、redis、rabbitmq这些中间件,开发时可能是使用的本地电脑进行开发,部署时使用的是云服务器,因为开发环境和生产环境中中间件的ip和端口有所不同,因此使用两个文件来进行区分,方便切换
在application.yml中可以指定使用dev
还是prod
文件,当然,在打包之前并不需要对其进行修改,因为在运行jar包的时候还可以二次指定jar包运行的端口、使用的内存、使用的配置文件......,如java -Xmx256M -Xms256M -jar sss-enterprise-0.0.1-SNAPSHOT.jar --server.port=6002 --spring.profiles.active=prod
打包
打包直接使用maven工具里面的clean
和install
命令即可,因为若依管理系统已经在pom.xml
中内置了打包配置
部署
本文使用的是若依的单机版本,并非微服务版本,因此只需要在服务器中启动admin的jar包即可,具体的操作步骤可以学习SpringBoot+Vue 前后端分离 微服务项目 打包部署全流程(原始部署/宝塔部署)