
安卓.9图启动图变形苹果storyboard 启动图片代做原生插件bug解决uniapp flutter开发
35岁被那个了,开发经验丰富,
原生Android iOS,uniapp flutter,vue,小程序都可以干,
同学朋友都是这行的,可接整体项目,可接项目咨询,项目设计,项目风险咨询等,
主要是性价比高,专业还便宜,
都在一线干的资深码农,如果你是老板请联系我,不一定就能省大钱办大事,还有惊喜,
如果你是一个技术需要解决问题请联系我,总之多问一嘴不收费,可能就有意外收获!QQ 1004898113
35岁被那个了,开发经验丰富,
原生Android iOS,uniapp flutter,vue,小程序都可以干,
同学朋友都是这行的,可接整体项目,可接项目咨询,项目设计,项目风险咨询等,
主要是性价比高,专业还便宜,
都在一线干的资深码农,如果你是老板请联系我,不一定就能省大钱办大事,还有惊喜,
如果你是一个技术需要解决问题请联系我,总之多问一嘴不收费,可能就有意外收获!QQ 1004898113
收起阅读 »
在uniapp插件市场上一直找不到合适的瀑布流组件,于是自己动手写了一个,并在项目中实践出来的瀑布流解决方案
一、我对于瀑布流布局组件的要求
- 要有骨架屏,能提前将基本结构展示给用户;
- 不要挨个渲染,否则如果有图片的话加载将会很慢;
- 可以实现多列瀑布流;
- 绝对不能出现错位渲染,很多瀑布流组件都出现这种情况,特别在页面跳转或Tabs切换下。
- 渲染过程中不能有卡顿影响用户体验。
- 应用于小程序、H5、App等
二、地址
uniapp插件地址:
https://ext.dcloud.net.cn/plugin?id=20167
组件文档地址:
https://github.com/Raito-Liao/raito-waterfall/blob/master/uni_modules/raito-waterfall/readme.md
三、实现讲解
1、计算渲染项的位置
原理都差不多,在获得渲染项的宽高后,将渲染项定位在最小高度的那一列的下面。
// raito-waterfall部分代码
export default {
methods: {
generateRenderList() {
const renderList = []
const {
columnCount,
columnWidth,
skeletonHeight,
gutter,
lrPading,
keyName,
cache
} = this
const columnHeights = new Array(columnCount).fill(0);
if (!keyName) {
throw new Error('keyName is required!')
}
this.data.forEach((item, index) => {
const itemKey = item[keyName]
if (!cache[itemKey]) {
cache[itemKey] = {
top: 0,
left: 0,
width: columnWidth, // item宽度
height: skeletonHeight // 骨架屏高度
}
}
if (index < columnCount) {
cache[itemKey].top = 0
cache[itemKey].left = lrPading index * (columnWidth gutter)
columnHeights[index] = cache[itemKey].height
} else {
const minHeight = Math.min(...columnHeights)
const minIndex = columnHeights.indexOf(minHeight);
cache[itemKey].top = minHeight gutter
cache[itemKey].left = lrPading minIndex * (columnWidth gutter)
columnHeights[minIndex] = cache[itemKey].height gutter
}
renderList.push({
...item,
_layoutRect: cache[itemKey],
_renderKey: itemKey
})
})
const maxHeight = Math.max(...columnHeights)
return {
renderList,
maxHeight
}
},
startRender() {
const {
maxHeight,
renderList
} = this.generateRenderList()
if (!renderList.length) {
return
}
this.renderList = renderList
this.waterfallBoxHeight = maxHeight
},
}
}
2、如何避免错位渲染?
这种情况发生于页面跳转或Tabs切换,导致获取不到元素的boundingClientRect,也就获取不到元素的高度,于是会导致计算错误。
function getRect(selector, context) {
return new Promise((resolve, reject) => {
const query = uni.createSelectorQuery().in(context);
query
.select(selector)
.boundingClientRect(rect => {
rect ? resolve(rect) : reject('Not Found');
})
.exec();
});
}
可以这样解决:当createSelectorQuery获取不到boundingClientRect时,使用createIntersectionObserver来监听元素,这样同样可以获取得到boundingClientRect。当重新回到页面或Tabs切换回来时,intersectionObserver会被触发。
// raito-waterfall-item部分代码
export default {
mounted() {
this.getExtraBoxWH().finally(() => {
/* 可能由于页面跳转、元素隐藏导致获取不到宽度和高度,于是通过监听元素来重新获取高度 */
if (!this.contentRect.extraBoxWidth || !this.contentRect.extraBoxHeight) {
this.startObserver();
}
});
},
beforeDestroy() {
if (this.intersectionObserver) {
this.intersectionObserver.disconnect();
this.intersectionObserver = null;
}
},
methods: {
startObserver() {
this.intersectionObserver = uni.createIntersectionObserver(this, {
thresholds: [0, 1],
initialRatio: 0,
observeAll: false
});
this.intersectionObserver.relativeToViewport();
this.intersectionObserver.observe('.content-box__extra', res => {
const { width, height } = res.boundingClientRect;
this.contentRect.extraBoxWidth = width;
this.contentRect.extraBoxHeight = height;
this.intersectionObserver.disconnect();
this.intersectionObserver = null;
});
},
// 获取extraBox的宽高
getExtraBoxWH() {
return getRect('.content-box__extra', this).then(rect => {
if (rect) {
this.contentRect.extraBoxWidth = rect.width;
this.contentRect.extraBoxHeight = rect.height;
}
});
},
}
}
3、防止数据频繁变化和渲染项高度变化导致卡顿,需要对其节流
import { isArraysEqual, throttle } from '../../util.js'
export default {
created() {
this.throttleRender = throttle(this.startRender.bind(this), 100) // 防止频繁调用
this.handleDataChange = throttle(this.handleDataChange.bind(this), 100) // 防止频繁调用
this.$watch('data', this.handleDataChange, {
deep: true,
immediate: true
})
},
methods: {
onHeightChange(item, height) {
const itemKey = item._renderKey
this.cache[itemKey].height = height
this.throttleRender()
},
handleDataChange(newData, oldData) {
if (isArraysEqual(newData, oldData)) {
return
}
this.startRender()
},
}
}
五、扫码预览
H5扫码体验(国内可能会慢一些)
一、我对于瀑布流布局组件的要求
- 要有骨架屏,能提前将基本结构展示给用户;
- 不要挨个渲染,否则如果有图片的话加载将会很慢;
- 可以实现多列瀑布流;
- 绝对不能出现错位渲染,很多瀑布流组件都出现这种情况,特别在页面跳转或Tabs切换下。
- 渲染过程中不能有卡顿影响用户体验。
- 应用于小程序、H5、App等
二、地址
uniapp插件地址:
https://ext.dcloud.net.cn/plugin?id=20167
组件文档地址:
https://github.com/Raito-Liao/raito-waterfall/blob/master/uni_modules/raito-waterfall/readme.md
三、实现讲解
1、计算渲染项的位置
原理都差不多,在获得渲染项的宽高后,将渲染项定位在最小高度的那一列的下面。
// raito-waterfall部分代码
export default {
methods: {
generateRenderList() {
const renderList = []
const {
columnCount,
columnWidth,
skeletonHeight,
gutter,
lrPading,
keyName,
cache
} = this
const columnHeights = new Array(columnCount).fill(0);
if (!keyName) {
throw new Error('keyName is required!')
}
this.data.forEach((item, index) => {
const itemKey = item[keyName]
if (!cache[itemKey]) {
cache[itemKey] = {
top: 0,
left: 0,
width: columnWidth, // item宽度
height: skeletonHeight // 骨架屏高度
}
}
if (index < columnCount) {
cache[itemKey].top = 0
cache[itemKey].left = lrPading index * (columnWidth gutter)
columnHeights[index] = cache[itemKey].height
} else {
const minHeight = Math.min(...columnHeights)
const minIndex = columnHeights.indexOf(minHeight);
cache[itemKey].top = minHeight gutter
cache[itemKey].left = lrPading minIndex * (columnWidth gutter)
columnHeights[minIndex] = cache[itemKey].height gutter
}
renderList.push({
...item,
_layoutRect: cache[itemKey],
_renderKey: itemKey
})
})
const maxHeight = Math.max(...columnHeights)
return {
renderList,
maxHeight
}
},
startRender() {
const {
maxHeight,
renderList
} = this.generateRenderList()
if (!renderList.length) {
return
}
this.renderList = renderList
this.waterfallBoxHeight = maxHeight
},
}
}
2、如何避免错位渲染?
这种情况发生于页面跳转或Tabs切换,导致获取不到元素的boundingClientRect,也就获取不到元素的高度,于是会导致计算错误。
function getRect(selector, context) {
return new Promise((resolve, reject) => {
const query = uni.createSelectorQuery().in(context);
query
.select(selector)
.boundingClientRect(rect => {
rect ? resolve(rect) : reject('Not Found');
})
.exec();
});
}
可以这样解决:当createSelectorQuery获取不到boundingClientRect时,使用createIntersectionObserver来监听元素,这样同样可以获取得到boundingClientRect。当重新回到页面或Tabs切换回来时,intersectionObserver会被触发。
// raito-waterfall-item部分代码
export default {
mounted() {
this.getExtraBoxWH().finally(() => {
/* 可能由于页面跳转、元素隐藏导致获取不到宽度和高度,于是通过监听元素来重新获取高度 */
if (!this.contentRect.extraBoxWidth || !this.contentRect.extraBoxHeight) {
this.startObserver();
}
});
},
beforeDestroy() {
if (this.intersectionObserver) {
this.intersectionObserver.disconnect();
this.intersectionObserver = null;
}
},
methods: {
startObserver() {
this.intersectionObserver = uni.createIntersectionObserver(this, {
thresholds: [0, 1],
initialRatio: 0,
observeAll: false
});
this.intersectionObserver.relativeToViewport();
this.intersectionObserver.observe('.content-box__extra', res => {
const { width, height } = res.boundingClientRect;
this.contentRect.extraBoxWidth = width;
this.contentRect.extraBoxHeight = height;
this.intersectionObserver.disconnect();
this.intersectionObserver = null;
});
},
// 获取extraBox的宽高
getExtraBoxWH() {
return getRect('.content-box__extra', this).then(rect => {
if (rect) {
this.contentRect.extraBoxWidth = rect.width;
this.contentRect.extraBoxHeight = rect.height;
}
});
},
}
}
3、防止数据频繁变化和渲染项高度变化导致卡顿,需要对其节流
import { isArraysEqual, throttle } from '../../util.js'
export default {
created() {
this.throttleRender = throttle(this.startRender.bind(this), 100) // 防止频繁调用
this.handleDataChange = throttle(this.handleDataChange.bind(this), 100) // 防止频繁调用
this.$watch('data', this.handleDataChange, {
deep: true,
immediate: true
})
},
methods: {
onHeightChange(item, height) {
const itemKey = item._renderKey
this.cache[itemKey].height = height
this.throttleRender()
},
handleDataChange(newData, oldData) {
if (isArraysEqual(newData, oldData)) {
return
}
this.startRender()
},
}
}
五、扫码预览
H5扫码体验(国内可能会慢一些)
收起阅读 »
unicloud之前运行好好的,但是突然访问云函数失败,报错FaasError: request has expired
前端详细报错:
Error: Cannot read properties of undefined (reading '0')
at _construct (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:2707)
at new Wrapper (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:17877)
at te._createSuperInternal (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:9512)
at new te (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:10070)
at _callee55$ (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:16718)
at tryCatch (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:17467)
at Generator.<anonymous> (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:17555)
at Generator.throw (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:17496)
at asyncGeneratorStep (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:17760)
at _throw (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:17782)(env: Windows,mp,1.06.2402040; lib: 3.5.6)
原因:
本地运行的电脑时间没有同步,不是最新时间。进入Linux系统的时候,切换为windows经常出现这个问题
前端详细报错:
Error: Cannot read properties of undefined (reading '0')
at _construct (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:2707)
at new Wrapper (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:17877)
at te._createSuperInternal (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:9512)
at new te (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:10070)
at _callee55$ (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:16718)
at tryCatch (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:17467)
at Generator.<anonymous> (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:17555)
at Generator.throw (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:17496)
at asyncGeneratorStep (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:17760)
at _throw (vendor.js?t=wechat&s=1725916079433&v=1c890918c06c7672a6a98d53434ae05f:17782)(env: Windows,mp,1.06.2402040; lib: 3.5.6)
原因:
本地运行的电脑时间没有同步,不是最新时间。进入Linux系统的时候,切换为windows经常出现这个问题

vue3+electron32+arco.design桌面端os模板|vite5+electron32仿mac/win客户端os程序
原创基于electron32.x+vite5+vue3 setup+pinia2+arco-design
实战开发全新桌面版os后台管理系统解决方案Vue3ElectronOS。内置了macos和windows两种风格桌面模板,自研可拖拽栅格布局桌面。
自研Electron32+Vite5+ArcoDesign桌面OS管理系统
运用技术
- 开发工具:VScode
- 技术框架:vite^5.4.1+vue^3.4.37+vue-router^4.4.3
- 跨平台框架:electron^32.0.1
- UI组件库:@arco-design/web-vue^2.56.0 (字节前端vue3组件库)
- 状态管理:pinia^2.2.2
- 拖拽插件:sortablejs^1.15.2
- 图表组件:echarts^5.5.1
- markdown编辑器:md-editor-v3^4.19.2
- 模拟数据:mockjs^1.1.0
- 打包构建:electron-builder^24.13.3
- electron+vite插件:vite-plugin-electron^0.28.7
基于electronjs封装高性能窗口多开器,采用自研栅格化拖拽布局引擎。
项目结构框架
electron32-winos基于vite.js
整合最新跨平台技术electron32.x
搭建项目模板。
目前electron32-vue3-os桌面os已经发布到我的原创作品集。
https://gf.bilibili.com/item/detail/1106958011
Electron主线程配置
/**
* electron主线程配置
* @author andy
*/
import { app, BrowserWindow } from 'electron'
import { WindowManager } from '../src/windows/index.js'
// 忽略安全警告提示 Electron Security Warning (Insecure Content-Security-Policy)
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = true
const createWindow = () => {
let win = new WindowManager()
win.create({isMajor: true})
// 系统托盘管理
win.trayManager()
// 监听ipcMain事件
win.ipcManager()
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if(BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', () => {
if(process.platform !== 'darwin') app.quit()
})
入口文件main.js
import { createApp } from 'vue'
import './style.scss'
import App from './App.vue'
import { launchApp } from '@/windows/actions'
// 引入路由及状态管理
import Router from './router'
import Pinia from './pinia'
// 引入插件
import Plugins from './plugins'
launchApp().then(config => {
if(config) {
// 全局窗口配置
window.config = config
}
// 初始化app实例
createApp(App)
.use(Router)
.use(Pinia)
.use(Plugins)
.mount('#app')
})
electron32-os桌面布局
<script setup>
import { appState } from '@/pinia/modules/app'
// 引入布局模板
import MacosLayout from './template/macos.vue'
import WindowsLayout from './template/windows.vue'
const appstate = appState()
const DeskLayout = {
macos: MacosLayout,
windows: WindowsLayout
}
</script>
<template>
<div class="vu__container" :style="{'--themeSkin': appstate.config.skin}">
<component :is="DeskLayout[appstate.config.layout]" />
</div>
</template>
<script setup>
import Wintool from '@/layouts/components/wintool/index.vue'
import Desk from '@/layouts/components/mac/desk.vue'
import Dock from '@/layouts/components/mac/dock.vue'
</script>
<template>
<div class="vu__layout flexbox flex-col">
<div class="vu__layout-header">
<Wintool />
</div>
<div class="vu__layout-body flex1 flexbox">
<Desk />
</div>
<div class="vu__layout-footer">
<Dock />
</div>
</div>
</template>
electron32-os桌面栅格模板
桌面json菜单配置项
/**
* label 图标标签
* imgico 图标(本地或网络图片) 支持Arco Design内置图标或自定义iconfont字体图标
* path 跳转路由地址
* link 跳转外部链接
* hideLabel 是否隐藏图标标签
* background 自定义图标背景色
* color 自定义图标颜色
* size 栅格布局(16种) 1x1 1x2 1x3 1x4、2x1 2x2 2x3 2x4、3x1 3x2 3x3 3x4、4x1 4x2 4x3 4x4
* onClick 点击图标回调函数
* children 二级菜单配置 * isNewin 新窗口打开路由页面
*/
桌面菜单示例代码
const deskMenu = [
{
uid: 'd137f210-507e-7e8e-1950-9deefac27e48',
list: [
{imgico: markRaw(Today), size: '2x2'},
{label: '日历', imgico: markRaw(Calendar3x3), size: '3x3'},
{label: 'Electron32', imgico: '/electron.svg', link: 'https://www.electronjs.org/'},
// ...
]
},
{
uid: 'g270f210-207e-6e8e-2650-9deefac27e48',
list: [
{label: 'Appstore', imgico: '/static/mac/appstore.png'},
// ...
]
},
{
uid: 't165f210-607e-4e8e-9950-9deefac27e48',
list: [
{label: 'Vue.js', imgico: '/vue.svg', link: 'https://vuejs.org/',},
{label: 'Vite.js官方文档', imgico: '/vite.svg', link: 'https://vitejs.dev/',},
// ...
]
},
{
uid: 'u327f210-207e-1e8e-9950-9deefac27e48',
list: [
{label: 'Electron32', imgico: '/electron.svg', link: 'https://www.electronjs.org/'},
{label: '首页', imgico: markRaw(IconHome), path: '/home', color: '#fff', isNewin: true},
{label: '工作台', imgico: 'elec-icon-dotchart', path: '/home/dashboard', color: '#fff'},
// ...
{
label: '用户中心',
children: [
{label: '主页', imgico: '/static/svg/ucenter.svg', path: '/setting'},
{label: '用户管理', imgico: markRaw(IconUserGroup), path: '/user', color: '#fff'},
// ...
]
},
{
label: '设置',
children: [
// ...
]
},
{
label: '收藏网址',
children: [
{label: 'Electron32', imgico: '/electron.svg', link: 'https://www.electronjs.org/'},
{label: 'Vite.js', imgico: '/vite.svg',},
// ...
]
},
{
label: '公众号', imgico: '/static/qrimg.png', color: '#07c160',
onClick: () => {
Modal.info({
// ...
})
}
},
]
}
]
Okay,综上就是electron32+vue3开发桌面端os系统的一些知识分享。
作者:xiaoyan2017
链接: https://segmentfault.com/a/1190000045245775
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原创基于electron32.x+vite5+vue3 setup+pinia2+arco-design
实战开发全新桌面版os后台管理系统解决方案Vue3ElectronOS。内置了macos和windows两种风格桌面模板,自研可拖拽栅格布局桌面。
自研Electron32+Vite5+ArcoDesign桌面OS管理系统
运用技术
- 开发工具:VScode
- 技术框架:vite^5.4.1+vue^3.4.37+vue-router^4.4.3
- 跨平台框架:electron^32.0.1
- UI组件库:@arco-design/web-vue^2.56.0 (字节前端vue3组件库)
- 状态管理:pinia^2.2.2
- 拖拽插件:sortablejs^1.15.2
- 图表组件:echarts^5.5.1
- markdown编辑器:md-editor-v3^4.19.2
- 模拟数据:mockjs^1.1.0
- 打包构建:electron-builder^24.13.3
- electron+vite插件:vite-plugin-electron^0.28.7
基于electronjs封装高性能窗口多开器,采用自研栅格化拖拽布局引擎。
项目结构框架
electron32-winos基于vite.js
整合最新跨平台技术electron32.x
搭建项目模板。
目前electron32-vue3-os桌面os已经发布到我的原创作品集。
https://gf.bilibili.com/item/detail/1106958011
Electron主线程配置
/**
* electron主线程配置
* @author andy
*/
import { app, BrowserWindow } from 'electron'
import { WindowManager } from '../src/windows/index.js'
// 忽略安全警告提示 Electron Security Warning (Insecure Content-Security-Policy)
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = true
const createWindow = () => {
let win = new WindowManager()
win.create({isMajor: true})
// 系统托盘管理
win.trayManager()
// 监听ipcMain事件
win.ipcManager()
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if(BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', () => {
if(process.platform !== 'darwin') app.quit()
})
入口文件main.js
import { createApp } from 'vue'
import './style.scss'
import App from './App.vue'
import { launchApp } from '@/windows/actions'
// 引入路由及状态管理
import Router from './router'
import Pinia from './pinia'
// 引入插件
import Plugins from './plugins'
launchApp().then(config => {
if(config) {
// 全局窗口配置
window.config = config
}
// 初始化app实例
createApp(App)
.use(Router)
.use(Pinia)
.use(Plugins)
.mount('#app')
})
electron32-os桌面布局
<script setup>
import { appState } from '@/pinia/modules/app'
// 引入布局模板
import MacosLayout from './template/macos.vue'
import WindowsLayout from './template/windows.vue'
const appstate = appState()
const DeskLayout = {
macos: MacosLayout,
windows: WindowsLayout
}
</script>
<template>
<div class="vu__container" :style="{'--themeSkin': appstate.config.skin}">
<component :is="DeskLayout[appstate.config.layout]" />
</div>
</template>
<script setup>
import Wintool from '@/layouts/components/wintool/index.vue'
import Desk from '@/layouts/components/mac/desk.vue'
import Dock from '@/layouts/components/mac/dock.vue'
</script>
<template>
<div class="vu__layout flexbox flex-col">
<div class="vu__layout-header">
<Wintool />
</div>
<div class="vu__layout-body flex1 flexbox">
<Desk />
</div>
<div class="vu__layout-footer">
<Dock />
</div>
</div>
</template>
electron32-os桌面栅格模板
桌面json菜单配置项
/**
* label 图标标签
* imgico 图标(本地或网络图片) 支持Arco Design内置图标或自定义iconfont字体图标
* path 跳转路由地址
* link 跳转外部链接
* hideLabel 是否隐藏图标标签
* background 自定义图标背景色
* color 自定义图标颜色
* size 栅格布局(16种) 1x1 1x2 1x3 1x4、2x1 2x2 2x3 2x4、3x1 3x2 3x3 3x4、4x1 4x2 4x3 4x4
* onClick 点击图标回调函数
* children 二级菜单配置 * isNewin 新窗口打开路由页面
*/
桌面菜单示例代码
const deskMenu = [
{
uid: 'd137f210-507e-7e8e-1950-9deefac27e48',
list: [
{imgico: markRaw(Today), size: '2x2'},
{label: '日历', imgico: markRaw(Calendar3x3), size: '3x3'},
{label: 'Electron32', imgico: '/electron.svg', link: 'https://www.electronjs.org/'},
// ...
]
},
{
uid: 'g270f210-207e-6e8e-2650-9deefac27e48',
list: [
{label: 'Appstore', imgico: '/static/mac/appstore.png'},
// ...
]
},
{
uid: 't165f210-607e-4e8e-9950-9deefac27e48',
list: [
{label: 'Vue.js', imgico: '/vue.svg', link: 'https://vuejs.org/',},
{label: 'Vite.js官方文档', imgico: '/vite.svg', link: 'https://vitejs.dev/',},
// ...
]
},
{
uid: 'u327f210-207e-1e8e-9950-9deefac27e48',
list: [
{label: 'Electron32', imgico: '/electron.svg', link: 'https://www.electronjs.org/'},
{label: '首页', imgico: markRaw(IconHome), path: '/home', color: '#fff', isNewin: true},
{label: '工作台', imgico: 'elec-icon-dotchart', path: '/home/dashboard', color: '#fff'},
// ...
{
label: '用户中心',
children: [
{label: '主页', imgico: '/static/svg/ucenter.svg', path: '/setting'},
{label: '用户管理', imgico: markRaw(IconUserGroup), path: '/user', color: '#fff'},
// ...
]
},
{
label: '设置',
children: [
// ...
]
},
{
label: '收藏网址',
children: [
{label: 'Electron32', imgico: '/electron.svg', link: 'https://www.electronjs.org/'},
{label: 'Vite.js', imgico: '/vite.svg',},
// ...
]
},
{
label: '公众号', imgico: '/static/qrimg.png', color: '#07c160',
onClick: () => {
Modal.info({
// ...
})
}
},
]
}
]
Okay,综上就是electron32+vue3开发桌面端os系统的一些知识分享。
作者:xiaoyan2017
链接: https://segmentfault.com/a/1190000045245775
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。