feat:初始化 -融骅

This commit is contained in:
2023-10-17 09:15:30 +08:00
parent c9ff84e6a2
commit 405e152b38
1190 changed files with 138344 additions and 455 deletions

View File

@@ -0,0 +1,19 @@
/**
* 异常捕获
*/
const ErrorCapture = {
/**
* 处理IMG异常
* @param {Event} event
*/
IMG ({ target }) {
target.src = target.className.includes('avatar') ? '/logo.svg' : '/default.svg'
}
}
/**
* 捕获全局error事件
*/
document.addEventListener('error', (e) => ErrorCapture[e.target.tagName]?.(e), true)

View File

@@ -0,0 +1,57 @@
import { reportDataApi } from '@/api/statistic/index'
export const REPORT_TYPES = {
ONLINE_COURSE: '在线课程',
LIVE_TEACHING: '教学直播',
MOCK_EXAMINATION: '模拟考试',
ERROR_CONSOLIDATION: '错题巩固',
CLASS_NOTE: '课堂笔记',
ONLINE_FAQ: '在线答疑',
RESOURCE_VIEW: '资源查看',
SYSTEM_USE: '系统使用'
}
/**
* 数据上报 mixin
*
* @param {[keyof REPORT_TYPES]} type 上报类型
*
* @param {Object} options 方法
* @param {boolean} options.isListenerUnload 是否弹出关闭页面提示框
* @param {()=>boolean} options.isCancelReport 是否取消上报
* @param {()=>{ id?:number, field01?:string, field02?:string, field03?:string, remarks?:string }} options.handleReportData 处理上报数据
* field01 备用字段
* field02 备用字段
* field03 备用字段
* remarks 备注说明
*
* @returns
*/
export function dataReportMixin (type, { isListenerUnload, ...methods } = {}) {
if (!type) throw Error('上报类型错误')
return {
mounted () {
if (this.isCancelReport?.()) return console.warn('上报已中断,上报数据:', type)
this.reportData()
if (isListenerUnload) window.addEventListener('beforeunload', this.reportData)
},
beforeDestroy () {
if (isListenerUnload) window.removeEventListener('beforeunload', this.reportData)
this.reportData()
},
methods: {
...methods,
async reportData (e) {
e && (e.returnValue = '将要退出,是否继续?')
reportDataApi({ ...this.handleReportData?.(), id: this.__report_data_id__, type })
.then(({ data }) => (this.__report_data_id__ = data))
}
}
}
}

63
front/src/utils/fetch.js Normal file
View File

@@ -0,0 +1,63 @@
import { lst } from './index'
const _instance = window.axios.create({
baseURL: import.meta.env.VITE_APP_BASE_URL,
timeout: 100000
})
_instance.interceptors.request.use(
(config) => {
const _token = lst.get('token')
_token && (config.headers.Authorization = _token)
if (config.formData) {
config.headers['Content-Type'] = 'multipart/form-data;'
config.data = new FormData()
for (const k in config.formData) config.data.append(k, config.formData[k])
}
return config
},
(e) => {
throw e
}
)
_instance.interceptors.response.use(
({ data, status, config }) => {
if ([201, 200].includes(status) && (data.code === 0 || config.noCatch)) return data
throw new Error(data.msg)
},
(e) => {
throw e
}
)
/**
* @param {Object} option 选项
* @param {string} option.url 请求地址
* @param {string} option.headers 请求头
* @param {{}} option.params URL 参数
* @param {{}} option.data body 参数
* @param {{}} option.formData FormData 对象参数
* @param {'get'|'post'|'patch'|'delete'} option.method
*/
export default async (option) => {
try {
return await _instance(option)
} catch (err) {
let _msg
if (err.response) {
if (err.response.data.code === 401) {
lst.clear()
location.href = '/'
}
_msg = err.response.data.msg
}
if (!option.noNotify) {
window.ELEMENT.Message.error(_msg || err.message || '系统繁忙,请稍后再试!')
}
throw new Error(_msg || err)
}
}

View File

@@ -0,0 +1,18 @@
const vue = new Vue()
window.addEventListener('message', async (e) => {
if (e.data.type === 'confim') {
// console.log($confirm)
await confirm(e)
}
})
async function confirm (e) {
vue.$confirm(e.data.title, '操作提示', { type: 'warning' })
.then(() => {
console.log(e)
e.source.postMessage({ status: true, id: e.data.id }, '*')
})
.catch(() => {
e.source.postMessage({ status: false, id: e.data.id }, '*')
})
}

112
front/src/utils/index.js Normal file
View File

@@ -0,0 +1,112 @@
import storage from './storage'
export function mapToTree (map) {
const list = []
for (const k in map) {
if (map[k].pid === 0) {
list.push(map[k])
} else {
map[map[k].pid].children ??= []
map[map[k].pid].children.push(map[k])
}
}
return list
}
/**
* 上传文件时 accept 的枚举类
*/
export const ACCEPT_MAP = {
image: { icon: 'i-tupiao', color: '#ff6a4d', name: '图片文件', accept: 'image/*' },
audio: { icon: 'i-yinyue', color: '#9660f5', name: '音频文件', accept: 'audio/*' },
video: { icon: 'i-shipin', color: '#55d1e0', name: '视频文件', accept: 'video/*' },
ppt: { icon: 'i-ppt', color: '#ff9357', name: '演示文稿', accept: 'application/vnd.ms-powerpoint' },
pptx: { icon: 'i-pptx', color: '#ff9357', name: '演示文稿', accept: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' },
xls: { icon: 'i-xls', color: '#28c17a', name: '表格文件', accept: 'application/vnd.ms-excel' },
xlsx: { icon: 'i-xlsx', color: '#28c17a', name: '表格文件', accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' },
pdf: { icon: 'i-pdf', color: '#ff738e', name: '文本文件', accept: 'application/pdf' },
doc: { icon: 'i-doc', color: '#39afff', name: '文本文件', accept: 'application/msword' },
docx: { icon: 'i-docx', color: '#39afff', name: '文本文件', accept: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' },
folder: { icon: 'i-wenjianjia', color: '#ffd94a', name: '文件夹', accept: '' }
}
export function getAcceptType (accept) {
if (!accept) return
for (const type in ACCEPT_MAP) {
if (accept.startsWith(ACCEPT_MAP[type].accept.replace(/\*$/, ''))) return type
}
}
/**
* 颜色生成器
*
* @param {string} value
* @returns
*/
export function colorGenerator (value) {
if (!value) return
return Number(value.split('').reduce((n, s) => n + s.charCodeAt(), '')).toString(16).replace(/.*(.{6})$/, '#$1')
}
/**
* 上传文件工具类
*
* @param {Object} options
* @param {[keyof ACCEPT_MAP]} options.accepts 指定可选的文件类型
* @param {boolean} options.multiple 是否允许用户选择多个文件
* @returns {Promise}
*/
export function getDistFile ({ accepts = [], multiple = false } = {}) {
if (!getDistFile.el) { // 如果没有 Input Dom对象则创建
getDistFile.el = document.createElement('input')
getDistFile.el.type = 'file'
}
return new Promise((resolve) => {
getDistFile.el.setAttribute(
'accept',
(accepts?.length ? accepts : Object.keys(ACCEPT_MAP))
.map(k => ACCEPT_MAP[k].accept).join(' , ')
)
getDistFile.el.setAttribute('multiple', multiple)
getDistFile.el.onchange = () => {
resolve([...getDistFile.el.files])
getDistFile.el.value = null
}
getDistFile.el.click()
})
}
/**
* 下载
*
* @param {string} src 文件地址
* @param {string} name 文件下载名
* @returns
*/
export async function download (src, name) {
if (!src) return
const href = await fetch(src).then(res => {
if (res.status === 200) return res.arrayBuffer()
throw Error('文件下载出错')
})
if (!download.el) {
download.el = document.createElement('a')
}
download.el.download = name || ''
download.el.href = URL.createObjectURL(new Blob([href]))
download.el.click()
}
/**
* 本地存储 localStorage
*/
export const lst = storage(localStorage)
/**
* 本地存储 sessionStorage
*/
export const sst = storage(sessionStorage)

435
front/src/utils/prototype.js vendored Normal file
View File

@@ -0,0 +1,435 @@
import jsPDF from 'jspdf'
import html2canvas from 'html2canvas'
import { font } from './simhei-normal'
/* eslint-disable no-extend-native */
String.prototype.fetchValue = function (object) {
return this.split('.').reduce((o, k) => (o === undefined || o === null ? undefined : o[k]), object || {})
}
String.prototype.resolveObject = function (value) {
const [first, ...os] = this.split('.').reverse()
return os.reduce((o, k) => ({ [k]: o }), { [first]: value })
}
String.prototype.fileLinkTransfer = function () {
if (this) return import.meta.env.VITE_APP_BASE_URL + '/file-bucket/' + this
}
File.prototype.fileLinkTransfer = function () {
if (this) return URL.createObjectURL(this)
}
Number.prototype.formatFileSize = function (fractionDigits = 2, type = 'string') {
if (isNaN(this)) return this
const units = ['B', 'KB', 'MB', 'GB', 'TB']
let size = this
let index = 0
while (size > 1024 && index < units.length - 1) {
size = size / 1024
index++
}
if (type === 'object') return { value: size.toFixed(fractionDigits), unit: units[index] }
return size.toFixed(fractionDigits) + units[index]
}
Date.prototype.format = function (fmt) {
const o = {
'M+': this.getMonth() + 1, // 月份
'd+': this.getDate(), // 日
'h+': this.getHours(), // 小时
'm+': this.getMinutes(), // 分
's+': this.getSeconds(), // 秒
'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
S: this.getMilliseconds() // 毫秒
}
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length))
for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)) }
}
return fmt
}
Date.prototype.toTypeStr = function (timestamp, fmt) {
if (typeof timestamp === 'string') {
fmt = timestamp
timestamp = undefined
}
const time = (timestamp || new Date().getTime()) - this.getTime()
return time < 60 * 1000
? '刚刚'
: time < 60 * 60 * 1000
? Math.floor(time / (60 * 1000)) + '分钟前'
: time < 24 * 60 * 60 * 1000
? Math.floor(time / (60 * 60 * 1000)) + '小时前'
: time < 48 * 60 * 60 * 1000
? '昨天'
: this.format(fmt || 'yyyy-MM-dd hh:mm')
}
Array.generate = function (length = 0, fn) {
const _list = []
if (fn) {
let i = 0
while (i < length) _list.push(fn(i++))
}
return _list
}
Array.prototype.toTree = function ({ key = 'id', parentKey = 'pid', childKey = 'children' } = {}) {
const list = this // JSON.parse(JSON.stringify(this))
const map = {}
let index = this.length
while (index--) {
map[list[index][key]] = list[index]
}
const tree = []
const len = list.length
while (++index < len) {
const item = list[index]
const pid = item[parentKey]
if (map[pid]) {
map[pid][childKey] ??= []
map[pid][childKey].push(item)
} else {
tree.push(item)
}
}
return { map, tree }
}
// window.Vue.prototype.$html2Pdf = async function (id, isPrint) {
// const ele = document.getElementById(id)
// console.log(ele)
// html2canvas(ele, { useCORS: true }).then(canvas => {
// // 未生成pdf的html页面高度
// // 未生成pdf的html页面高度
// let leftHeight = canvas.height
// const a4Width = 595.28
// const a4Height = 841.89 // A4大小210mm x 297mm四边各保留10mm的边距显示区域190x277
// // 一页pdf显示html页面生成的canvas高度;
// const a4HeightRef = Math.floor((canvas.width / a4Width) * a4Height)
// // pdf页面偏移
// let position = 0
// const pageData = canvas.toDataURL('image/jpeg', 1.0)
// const pdf = new jsPDF('p', 'pt', 'a4') // A4纸纵向
// let index = 1
// const canvas1 = document.createElement('canvas')
// let height
// pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen')
// const pdfName = 'title'
// function createImpl (canvas) {
// console.log(leftHeight, a4HeightRef)
// if (leftHeight > 0) {
// index++
// let checkCount = 0
// if (leftHeight > a4HeightRef) {
// let i = position + a4HeightRef
// for (i = position + a4HeightRef; i >= position; i--) {
// let isWrite = true
// for (let j = 0; j < canvas.width; j++) {
// const c = canvas.getContext('2d').getImageData(j, i, 1, 1).data
// if (c[0] !== 0xff || c[1] !== 0xff || c[2] !== 0xff) {
// isWrite = false
// break
// }
// }
// if (isWrite) {
// checkCount++
// if (checkCount >= 10) {
// break
// }
// } else {
// checkCount = 0
// }
// }
// height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef)
// if (height <= 0) {
// height = a4HeightRef
// }
// } else {
// height = leftHeight
// }
// canvas1.width = canvas.width
// canvas1.height = height
// console.log(index, 'height:', height, 'pos', position)
// const ctx = canvas1.getContext('2d')
// ctx.drawImage(
// canvas,
// 0,
// position,
// canvas.width,
// height,
// 0,
// 0,
// canvas.width,
// height
// )
// const pageHeight = Math.round((a4Width / canvas.width) * height)
// // pdf.setPageSize(null, pageHeight)
// if (position !== 0) {
// pdf.addPage()
// }
// pdf.addImage(
// canvas1.toDataURL('image/jpeg', 1.0),
// 'JPEG',
// 20,
// 20,
// a4Width,
// (a4Width / canvas1.width) * height
// )
// leftHeight -= height
// position += height
// if (leftHeight > 0) {
// setTimeout(createImpl, 500, canvas)
// } else {
// console.log(pdf)
// pdf.autoPrint()
// window.open(pdf.output('bloburl'), '_blank')
// }
// }
// }
// // 当内容未超过pdf一页显示的范围无需分页
// if (leftHeight < a4HeightRef) {
// pdf.addImage(
// pageData,
// 'JPEG',
// 20,
// 20,
// a4Width,
// (a4Width / canvas.width) * leftHeight
// )
// console.log(pdf)
// pdf.autoPrint()
// window.open(pdf.output('bloburl'), '_blank')
// } else {
// try {
// pdf.deletePage(0)
// setTimeout(createImpl, 500, canvas)
// } catch (err) {
// // console.log(err);
// }
// }
// })
// }
// window.Vue.prototype.$html2Pdf = async function (id, isPrint) {
// const ele = document.getElementById(id)
// const pageWidth = 595.28 - 40 // A4纸的宽高 减去左右边距
// const pageHeight = 841.89 - 40
// // a4纸的尺寸[595.28,841.89]html页面生成的canvas在pdf中图片的宽高
// html2canvas(ele, {
// // allowTaint: true,
// // taintTest: false,
// useCORS: true,
// backgroundColor: '#FFF',
// width: ele.offsetWidth - 15, // 因为多出的需要剪裁掉,
// height: ele.offsetHeight
// // async: true,
// // scale: '1', // 放大倍数
// // dpi: '192', // 精度
// // scrollY: ele.top, // 关键代码
// // height: ele.height + 50 // 加高度,避免截取不全
// }).then(canvas => {
// const contentWidth = canvas.width
// const contentHeight = canvas.height
// const pageData = canvas.toDataURL('image/jpeg/png', 1)
// const PDF = new jsPDF('p', 'mm', 'a4') // , true
// let pageCount = 1
// // canvas图片的高
// const imgHeight = pageWidth / contentWidth * contentHeight // canvas的宽与PDF的宽比列一样的时候canvas的高缩放后的值
// let leftHeight = imgHeight
// let position = 0
// // 如果图片的高小于A4纸的高不分页
// if (leftHeight < pageHeight) {
// PDF.addImage(pageData, 'JPEG', 20, 0, pageWidth, imgHeight)
// } else {
// // 分页
// // let index = 0
// while (leftHeight > 0) {
// pageCount++
// PDF.addImage(pageData, 'JPEG', 20, position, pageWidth, imgHeight)
// leftHeight = leftHeight - pageHeight
// position -= pageHeight
// if (leftHeight > 0) {
// PDF.addPage()
// }
// }
// }
// PDF.addFileToVFS('blobs', font)
// PDF.addFont('blobs', 'font_blobs', 'normal')
// // 通过字体名使用字体
// PDF.setFont('font_blobs')
// for (let i = 1; i < pageCount; i++) {
// console.log(i)
// PDF.setPage(i)
// PDF.setFontSize(8)
// PDF.text('当前第 ' + String(i) + '页 共 ' + String(pageCount) + '页', PDF.internal.pageSize.width / 2, pageHeight + 35, {
// align: 'center'
// })
// }
// PDF.autoPrint()
// window.open(PDF.output('bloburl'), '_blank')
// })
// }
const isSplit = (nodes, index, pageHeight) => {
// 计算当前这块dom是否跨越了a4大小以此分割
if (nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight && nodes[index + 1] && nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight) {
return true
}
return false
}
const formatPdf = (ele) => {
const ST = document.documentElement.scrollTop || document.body.scrollTop
const SL = document.documentElement.scrollLeft || document.body.scrollLeft
document.documentElement.scrollTop = 0
document.documentElement.scrollLeft = 0
document.body.scrollTop = 0
document.body.scrollLeft = 0
// const ST = document.documentElement.scrollTop || document.body.scrollTop
// const SL = document.documentElement.scrollLeft || document.body.scrollLeft
document.documentElement.scrollTop = 0
document.documentElement.scrollLeft = 0
document.body.scrollTop = 0
document.body.scrollLeft = 0
// 获取滚动条的位置并赋值为0因为是el-dialog弹框并且内容较多出现了纵向的滚动条,截图出来的效果只能截取到视图窗口显示的部分,超出窗口部分则无法生成。所以先将滚动条置顶
const A4_WIDTH = 592.28
const A4_HEIGHT = 841.89
const imageWrapper = ele // 获取DOM
const pageHeight = imageWrapper.scrollWidth / A4_WIDTH * A4_HEIGHT + 80
// const lableListID = imageWrapper.querySelectorAll('.main-form-area')
const lableListID = imageWrapper.querySelectorAll('.answer-item')
// 进行分割操作当dom内容已超出a4的高度则将该dom前插入一个空dom把他挤下去分割
for (let i = 0; i < lableListID.length; i++) {
// console.log(lableListID[i])
const multiple = Math.ceil((lableListID[i].offsetTop + lableListID[i].offsetHeight) / pageHeight)
if (isSplit(lableListID, i, multiple * pageHeight)) {
// console.log(lableListID[i])
const divParent = lableListID[i].parentNode // 获取该div的父节点
const newNode = document.createElement('div')
newNode.className = 'emptyDiv'
newNode.style.background = '#ffffff'
const _H = multiple * pageHeight - (lableListID[i].offsetTop + lableListID[i].offsetHeight)
// 留白
newNode.style.height = _H + 'px'
newNode.style.width = '100%'
const next = lableListID[i].nextSibling // 获取div的下一个兄弟节点
// 判断兄弟节点是否存在
if (next) {
// 存在则将新节点插入到div的下一个兄弟节点之前即div之后
divParent.insertBefore(newNode, next)
} else {
// 不存在则直接添加到最后,appendChild默认添加到divParent的最后
divParent.appendChild(newNode)
}
}
}
}
window.Vue.prototype.$html2Pdf = async function (id, exportInfo) {
const ele = document.getElementById(id)
formatPdf(ele)
// a4纸的尺寸[595.28,841.89]html页面生成的canvas在pdf中图片的宽高
html2canvas(ele, {
// allowTaint: true,
// // taintTest: false,
// x: ele.getBoundingClientRect().left + 13, // 绘制的dom元素相对于视口的位置
// y: ele.getBoundingClientRect().top,
useCORS: true,
backgroundColor: '#FFF',
width: ele.offsetWidth - 15, // 因为多出的需要剪裁掉,
height: ele.offsetHeight,
// async: true,
scale: 3, // 放大倍数
dpi: 350 // 精度
// scrollY: ele.top, // 关键代码
// height: ele.height + 50 // 加高度,避免截取不全
}).then(canvas => {
const pdf = new jsPDF('p', 'mm', 'a4') // A4纸纵向
const ctx = canvas.getContext('2d')
const a4w = 190; const a4h = 277 // A4大小210mm x 297mm四边各保留10mm的边距显示区域190x277
const imgHeight = Math.floor(a4h * canvas.width / a4w) // 按A4显示比例换算一页图像的像素高度
let renderedHeight = 0
while (renderedHeight < canvas.height) {
const page = document.createElement('canvas')
page.width = canvas.width
page.height = Math.min(imgHeight, canvas.height - renderedHeight)// 可能内容不足一页
// 用getImageData剪裁指定区域并画到前面创建的canvas对象中
if (renderedHeight === 0) {
page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, (Math.min(imgHeight, canvas.height - renderedHeight) + 20)), 0, 0)
pdf.addImage(page.toDataURL('image/jpeg', 0.2), 'JPEG', 10, 0, a4w, Math.min(a4h, a4w * page.height / page.width)) // 添加图像到页面保留10mm边距
} else {
page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0)
pdf.addImage(page.toDataURL('image/jpeg', 0.2), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width)) // 添加图像到页面保留10mm边距
}
renderedHeight += imgHeight
if (renderedHeight < canvas.height) { pdf.addPage() }// 如果后面还有内容,添加一个空页
}
const pageCount = pdf.internal.getNumberOfPages()
pdf.addFileToVFS('blobs', font)
pdf.addFont('blobs', 'font_blobs', 'normal')
// 通过字体名使用字体
pdf.setFont('font_blobs')
pdf.setFontSize(8)
for (let i = 1; i <= pageCount; i++) {
pdf.setPage(i)
pdf.text('第 ' + String(i) + ' 页 共 ' + String(pageCount) + ' 页', pdf.internal.pageSize.width / 2, 287 + 5, {
align: 'center'
})
}
console.log(exportInfo, 11111111111111)
if (exportInfo) {
pdf.save(exportInfo.title + '.pdf')
} else {
pdf.autoPrint()
window.open(pdf.output('bloburl'), '_blank')
const emptyDivs = ele.querySelectorAll('.emptyDiv')
emptyDivs.forEach(item => {
item.parentNode.removeChild(item)
console.log(item)
})
}
})
}
window.Vue.prototype.$elementFullscreen = async function (ele, callback, todo) {
console.log(typeof ele)
if (!(ele instanceof HTMLElement)) {
ele = ele.$el
}
const div = document.createElement('div')
await ele.requestFullscreen()
window.Vue.prototype.$store.isFullscreen = true
console.log(todo)
todo && todo()
setTimeout(() => {
const fun = () => {
ele.removeEventListener('fullscreenchange', fun)
window.Vue.prototype.$store.isFullscreen = false
callback()
}
ele.addEventListener('fullscreenchange', fun)
}, 100)
console.log(ele)
}

View File

@@ -0,0 +1,51 @@
import { registerMicroApps, start } from 'qiankun'
import store from '../store'
// 子应用配置
export const apps = [
{
name: '子应用1',
entry: '//localhost:9099',
id: 'app1',
container: '#app1',
activeRule: '/app1',
// 测试传参并将store传递至子应用进行消息通信
props: { test: 1111, store }
},
{
name: '子应用2',
entry: '//localhost:8888',
id: 'app2',
type: 'qiankun',
container: '#app2',
activeRule: '/app2',
// 测试传参并将store传递至子应用进行消息通信
props: { test: 1111, store }
}
]
// 乾坤初始化方法
export default function qianKunInit () {
window.__POWERED_BY_QIANKUN_PARENT__ = true
registerMicroApps(apps, {
beforeLoad: [
(app) => {
console.log(app, '111111111111111111')
}],
destoryed: [
(app) => {
}
]
})
const mainEle = document.getElementById('qiankun-main')
apps.forEach(item => {
const child = document.createElement('div')
child.id = item.id
mainEle.appendChild(child)
item.container = child
console.log(child)
})
start({
prefetch: false, // 可选,是否开启预加载,默认为 true。 不开启
sandbox: true, // 可选,是否开启沙箱,默认为 true。// 从而确保微应用的样式不会对全局造成影响。
singular: true // 可选,是否为单实例场景,单实例指的是同一时间只会渲染一个微应用。默认为 true。
})
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,52 @@
export default (storage) => {
if (!storage) return
const skey = (key) => '' + key
return {
/**
* 获取
* @param {string} key key
* @param {any} defaultValue defaultValue
*/
get (key, defaultValue) {
try {
return JSON.parse(storage.getItem(skey(key))) || defaultValue
} catch (error) {
return defaultValue
}
},
/**
* 保存
* @param {string} key key
* @param {any} val 值
*/
save (key, val) {
if (val === undefined || val === null) return this.remove(key)
storage.setItem(skey(key), JSON.stringify(val))
},
/**
* 获取 所有key
*/
keys () {
return Object.keys(storage)
},
/**
* 删除
* @param {string} key key
*/
remove (key) {
storage.removeItem(skey(key))
},
/**
* 清空
*/
clear () {
storage.clear()
}
}
}