项目实现的是 课堂 相关的内容,用uniapp开发的web端,不过需要接入app里(uniapp打包的),通过webview接入。也就是:子应用接入主应用,可以使用plus调用主应用的一些底层方法。记录一下。
使用hbuilderx开发工具,开发uniapp必备的。
创建一个vue的模板,可以进行选择。这里使用的是vue2.
目录结构(完整的):
(这个目录可以说是一个集成的感觉,有vue和小程序的既视感。 )
node_modules是安装vue相关开发的依赖,而uni_modu是uni-app的插件模块化规范,是对一些模块的封装,用于嵌入到uniapp中。在可以在hbuilderx的插件市场下载。hbuilderx文档,这里查看更具体的表述。
项目里使用的是uview-ui。进行安装,也可以下载到本地项目。
在main.js中引入 view-ui,use()进行使用。
import uView from "@/uni_modules/uview-ui";
Vue.use(uView);
然后就可以在代码里使用uView的ui组件了。
在pages.json中加入easycom, 这是为了按需加载,不用手动引入了。
"easycom": {
"^u-(.*)": "@/uni_modules/uview-ui/components/u-$1/u-$1.vue"
},
App.vue是主组件,是资源的首加载项,入口文件,可以在里面定义项目的生命周期和globalData,处理基础的css文件和设置。
index.html是模板文件,打包后的index.html模板,这里可以使用cdn,做一些全局的配置。
unpackage是打包后生成的目录。
pages是页面目录了,需要注意的是,页面想要访问,需要在pages.json中进行配置,有很多配置项,配置过后路径才能访问。
也可以配置开发模式,全局样式, 底部导航等,文档查看
根据ui设计开发页面内容。
在http封装一个全局请求,在main.js中引入$http,就可以请求接口了~
request.js
import {BASE_URL} from '@/config/constant.js'
export const myRequest = (options) => {
return new Promise((resolve,reject)=>{
uni.request({
url:BASE_URL+options.url,
method:options.method||'GET',
data:options.data||{},
header:options.header||{'token':uni.getStorageSync('study_token')},
success: (res) => {
if(res.data.code == 401){
return uni.showToast({
title:res.data.msg?res.data.msg:'请先登录!',
icon:'none'
})
}else if(res.data.code!=0){
return uni.showToast({
title:res.data.msg,
icon:'none'
})
}
resolve(res)
},
fail: (err) => {
uni.showToast({
title:'请求失败!',
icon:'none'
})
reject(err)
}
})
})
}
接下来是主应用和子应用之间的通信!!
需要引入uni.webview.js。可以在index.html中进行UniAppJSBridgeReady的监听,在其中使用uniWeb。
index.html
const BASE_URL = 'http://study.xiangnongjy.com/hzjt-xnkt' ; // 主机+端口
document.addEventListener('UniAppJSBridgeReady',function(){
window.uniWeb = uniWeb;
let envir ;
uniWeb.getEnv(function(res){
console.log('当前环境index'+JSON.stringify(res))
for(let a in res){
envir = a
}
})
window.isApp = ()=>{
if(envir == 'h5'||typeof(plus) == 'undefined'){
return false
}else if(envir == 'plus'||typeof(plus) == 'object'){
return true
}
}
uni.setStorageSync('isApp',isApp())
console.log(uni.getStorageSync('isApp'),'isapp');
// 登录
if(uni.getStorageSync('isApp')){
// console.log(plus.storage.getItem('cms_token'),'cms---------------------------在index.html');
if(plus.storage.getItem('cms_token')){
let tt = plus.storage.getItem('cms_token')
uni.request({
url:BASE_URL+'/api/auth/login',
method:'post',
data:{
token:tt
}
}).then(({data:res})=>{
if(res.code==0){
uni.setStorageSync('study_token', res.data.token);
}else{
uni.$u.toast(res.msg)
}
}).catch((res)=>{
}
)
}
}
})
使用uniWeb.getEnv()来获取当前的环境,可以区分出h5和plus情况,plus说明是app内部生效。后续可以使用plus的一些方法和数据传递。
uni.setStorageSync('isApp',isApp()) 是缓存住状态,pages里的其他页面无法使用uniWeb变量,所以通过缓存进行环境变量的判断。
plus.storage.getItem('cms_token') 是plus获取到主应用的缓存,获得到cms_token的值,通过这个访问接口,换取子应用自己的token,后续使用。
在mine中,根据uni.getStorageSync('isApp')和token来判断是否登录。
window.uniWeb.postMessage({
data:{logout:true}
})
通过给主应用postMessage来发生消息,比如登出。
如果需要跳转到主应用进行登录,也需要uniWeb来跳转主应用的路径,并且通过缓存,在主应用的缓存下保存登录后的回显页面。
if(uni.getStorageSync('isApp')){
window.uniWeb.navigateTo({
url:'/pages/login/index'
})
plus.storage.setItem('redirect','http://test.study-h5.xiangnongjy.com:7898/#/pages/mine/mine')
}
区分,主应用缓存plus.storage,和子应用缓存uni.getStorageSync() 的使用。
视频的观看,以及视频的监听,videoListener。
<video id="myVideo" :src="videoSrc" controls></video>
//立即播放
setTimeout(()=>{uni.createVideoContext('myVideo').play();this.now_Nofen = true},1000)
// 视频监听
videoListener(e){
var _this = this
let ctime = Number(e.detail.currentTime)
// console.log('进度',ctime,this.now_duration/2,this.now_Nofen);
if(ctime > (_this.now_duration/2)){
if(_this.now_Nofen){
_this.shareOkfen_look()
}
// uni.createVideoContext('myVideo').pause()
}
}
海报的生成分享和下载。需要使用 html2canvas 根据结构生成canvas。使用plus的方法在app里可以下载海报(a标签不可行),h5里可以使用a标签的方式下载。
// 生成海报
createPoster() {
const _this = this
uni.showLoading({
title: '正在生成海报'
})
let dom = document.querySelector('#poster')
console.log(dom);
html2canvas(dom,{
width:dom.clientWidth,
height:dom.clientHeight,
scrollX:0,
scrollY:0,
scale:2,
useCORS:true,
}).then((canvas)=>{
uni.hideLoading()
let imgData = canvas.toDataURL('image/png',1)
if(uni.getStorageSync('isApp')){
let bitmap = new plus.nativeObj.Bitmap('image')
bitmap.loadBase64Data(imgData,()=>{
let url = '_doc/'+new Date().getTime()+'.png'
bitmap.save(url,{
overwrite:false,// 是否覆盖
// quality:'quality', //图片清晰度
},function(i){
plus.gallery.save(i.target,(evt)=>{
const tmap = plus.nativeObj.Bitmap.getBitmapById('image')
tmap.clear()
uni.showToast({
title:'图片保存成功',
icon:'none'
})
_this.$emit('downOk')
},(err)=>{
console.log('保存图失败11'+JSON.stringify(err));
uni.showToast({
title:'图片保存失败',
icon:'none'
})
})
},function(e){
console.log('保存图失败'+JSON.stringify(e));
uni.showToast({
title:'图片保存失败',
icon:'none'
})
bitmap.clear()
})
},(e)=>{
console.log('base64失败'+JSON.stringify(e));
bitmap.clear()
})
}else{
this.downloadFile(this.data.videoTitle,imgData)
}
})
},
html2canvas()中scale:2,图片会更加的清晰一些。
plus的保存图片方法,是调用plus的nativeObj方法,gallery保存方法。
h5的图片下载方式,将base64转换为blob,然后createObjectURL创建访问链接。
// 下载
downloadFile(fileName, content) {
let aLink = document.createElement('a')
let blob = this.base64ToBlob(content) // new Blob([content]);
let evt = document.createEvent('HTMLEvents')
evt.initEvent('click',true, true) // initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡
aLink.download = fileName
aLink.href = window.URL.createObjectURL(blob)
// aLink.dispatchEvent(evt);
aLink.click()
// 成功后
uni.$u.toast('下载成功')
this.$emit('downOk')
},
//base64转blob
base64ToBlob(code) {
let parts = code.split(';base64,')
let contentType = parts[0].split(':')[1]
let raw = window.atob(parts[1]) // 解码base64得到二进制字符串
let rawLength = raw.length
let uInt8Array = new Uint8Array(rawLength) // 创建8位无符号整数值的类型化数组
for(let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i) // 数组接收二进制字符串
}
return new Blob([uInt8Array], {type: contentType})
}
h5打包,在hbuilder选项中,发行,h5发行,填写对应的发行域名。然后会在unpackage中生成打包后的文件。
需要注意的是,发行的话,需要在dcloud开发者中心进行登录,然后申请一个项目,进行打包操作。不然会打包失败哦。(打包命令执行的控制台会有对应的提醒。)
临时笔记
讨论word编辑和预览的功能实现方式:
预览可以用微软的office在线预览地址进行预览。
kkfile也可以实现预览。
重点编辑部分:wps开放平台,功能强大,底层不支持ie。
冰蓝第三方插件,可以职称ie,实现简单的预览和编辑。
onlyoffice需要两台服务器部署,和docker配置,不合适
weboffice需要进行客户端的控件下载,不合适。
目前可以使用富文本进行内容的展示和编辑,后端进行解析。