容較多請耐心閱讀,你認(rèn)真讀完一定獲益匪淺
這是一個基于vuecli+element-plus共同搭建的一個開源vue3動態(tài)路由和動態(tài)菜單開源框架,總體來說這個項目是非常優(yōu)秀。你通過使用它直接實(shí)現(xiàn)動態(tài)路由和菜單管理功能,實(shí)現(xiàn)快速開發(fā)。支持二級菜單管理和嵌套路由管理。
"element-plus": "^1.0.2-beta.70",
"vue": "^3.0.0",
"vue-router": "^4.0.0-0"
1、unituicli3是一個基于vue3搭建的一個項目,它是與時俱進(jìn)的,極具時代性,緊跟vue3的腳步。
2、項目僅僅集成了element-plus和vue-router兩個必備的JavaScript庫,除此之外沒有再集成任何JavaScript庫。這也就意味著你可以根據(jù)自己的項目需要去安裝自己需要的JavaScript庫,避免因為項目集成庫過多給你帶來煩惱。
3、強(qiáng)勁的組件管理器,我們?yōu)榱藥椭銓?shí)現(xiàn)可視化管理動態(tài)路由和菜單,我們內(nèi)置了《組件管理》功能組件,使路由和菜單管理可視化。同時我們?yōu)榱烁玫貙?shí)現(xiàn)項目管理,在vue2版本的基礎(chǔ)上新增了可選json導(dǎo)出功能,讓你可以快速實(shí)現(xiàn)json數(shù)據(jù)生成,生成用戶權(quán)限路由和菜單。
4、美麗的視圖框架,我們內(nèi)置了一個后臺管理UI框架,你可以通過使用它實(shí)現(xiàn)admin項目的快速生成和搭建。當(dāng)然你也可以自己搭建自己喜歡的UI框架結(jié)構(gòu)。
5、更少的干擾。為了讓項目更加純凈,將項目控制權(quán)更多的交給開發(fā)者,我們新建了unitui文件夾位于src文件夾下用于存放我們內(nèi)置的部分,為了便于你項目的啟動和理解你可以直接將ivews和components文件夾內(nèi)容清空,重新搭建你的組件,因為這些目錄下的文件這些并不重要。
名稱 功能 | 介紹 | 功能 |
動態(tài)路由 | 用于可視化將vue文件加載到路由中,實(shí)現(xiàn)訪問 | 掛載vue、刪除、選擇生成json,嵌套路由管理 |
動態(tài)菜單 | 將菜單與動態(tài)路由相配合,實(shí)現(xiàn)菜單點(diǎn)擊訪問路由 | 菜單增、刪、改,二級菜單管理 |
Unituicli3因為《組件管理》而顯得強(qiáng)大,因為這是核心組件,將動態(tài)路由(添加、刪除、修改)、嵌套路由和菜單管理(添加、刪除、修改)變得可視化,而且支持json數(shù)據(jù)生成使前后端間交互變得可能,你只需要將生成的json儲存在數(shù)據(jù)庫便可實(shí)現(xiàn)權(quán)限編輯。
我們雖然盡力減少對開發(fā)者的影響,但是做出一些修改是不可避免的。
import { createApp } from 'vue'
import ElementPlus from 'element-plus';
import App from './App.vue'
import router from './router'
import '@/unitui/init_route.js'//這是為了實(shí)現(xiàn)防止刷新路由丟失
const app = createApp(App)
app.use(ElementPlus)
app.use(router).mount('#app')
// 注冊全局組件
import Uicon from './unitui/sub/Uicon.vue'
app.component('Uicon',Uicon)
你如果不是使用elementPlus作為你的UI你可以參考上面內(nèi)容做出適當(dāng)修改
這是一個全局注冊的圖標(biāo)選擇器,你可以在任意組件通過<Uicon v-model=”icon”></Uicon>使用圖標(biāo)選擇器,它掛載在main.js文件中,你如不是使用element你需要做出修改,否則可能影響圖標(biāo)選擇的功能使用。
實(shí)際效果
這是一個非常重要的內(nèi)置組件,它主要用于模擬登錄時的操作和信息生成,它會讀取位于assets/json/文件夾下的兩個json生成菜單和路由信息,json內(nèi)容模擬后端返回的內(nèi)容。
其中最重要的是路由的生成,你在登錄后路由json信息返回后調(diào)用init_route方法,代碼如下:
init_route(route_data) {
//依據(jù)后端返回的json數(shù)據(jù)生成路由
const init_route_data = []; //定義一個路由數(shù)組儲存生成的路由信息
for (let index = 0; index < route_data.length; index++) {
//循環(huán)后端返回的json
//循環(huán)
if (route_data[index].children != undefined) {
//有children時生成路由數(shù)組方法
init_route_data[index] = {
path: route_data[index].path, //路由url
name: route_data[index].name, //路由名
component: () => import(`@/${route_data[index].component}`),
// component: (resolve) => require([`@/views/${route_data[index].component}`], resolve), //加載后端json描述的vue文件
meta: {
//路由一些附加信息
show_site: route_data[index].meta.show_site, //是否全屏顯示
web_title: route_data[index].meta.web_title //網(wǎng)站標(biāo)題
},
children: [] //嵌套路由
};
for (let i = 0; i < route_data[index].children.length; i++) {
init_route_data[index].children[i] = {
path: route_data[index].children[i].path, //路由url
name: route_data[index].children[i].name, //路由名
component: () => import(`@/${route_data[index].children[i].component}`),
// component:(resolve) => require([`@/views/${route_data[index].children[i].component}`], resolve), //加載后端json描述的vue文件
meta: {
//路由一些附加信息
show_site: route_data[index].children[i].meta.show_site, //是否全屏顯示
web_title: route_data[index].children[i].meta.web_title //網(wǎng)站標(biāo)題
}
};
}
} else {
//沒有children時生成路由數(shù)組方法
init_route_data[index] = {
path: route_data[index].path, //路由url
name: route_data[index].name, //路由名
component: () => import(`@/${route_data[index].component}`),
// component:(resolve) => require([`@/views/${route_data[index].component}`], resolve), //加載后端json描述的vue文件
meta: {
show_site: route_data[index].meta.show_site, //是否全屏顯示
web_title: route_data[index].meta.web_title //網(wǎng)站標(biāo)題
}
};
// console.log(index);
}
}
// console.log(init_route_data); //打印生成初始化路由數(shù)組
for (let index = 0; index < route_data.length; index++) {
//由于addRoutes已經(jīng)廢棄,所以需要循環(huán)使用addRoute進(jìn)行數(shù)組添加
this.$router.addRoute(init_route_data[index]); //循環(huán)添加數(shù)組
}
this.init_menu(); //執(zhí)行菜單生成方法
},
其他三個你可以隨意修改
在vue2動態(tài)路由項目之中,在app.vue文件mounted方法中調(diào)用路由生成方法,可以實(shí)現(xiàn)刷新路由防丟失,但是在vue3中采用同樣方式,則會出現(xiàn)異常,原因是我們跳轉(zhuǎn)發(fā)生在路由添加前,所以會出現(xiàn)刷新后頁面沒有內(nèi)容,所以我們在unitui文件夾下新建init_route.js寫下和login.vue文件中路由初始化相似的內(nèi)容,然后再main.js中引入。
init_route.js內(nèi)容:
import router from '@/router'
function init_route() {
//依據(jù)后端返回的json數(shù)據(jù)生成路由
if (sessionStorage.getItem("route_data") != null) {
const route_data = JSON.parse(sessionStorage.getItem("route_data"));
// console.log(route_data);
const init_route_data = []; //定義一個路由數(shù)組儲存生成的路由信息
for (let index = 0; index < route_data.length; index++) {
//循環(huán)后端返回的json
//循環(huán)
if (route_data[index].children != undefined) {
//有children時生成路由數(shù)組方法
init_route_data[index] = {
path: route_data[index].path, //路由url
name: route_data[index].name, //路由名
component: () => import(`@/${route_data[index].component}`),
// component: (resolve) => require([`@/views/${route_data[index].component}`], resolve), //加載后端json描述的vue文件
meta: {
//路由一些附加信息
show_site: route_data[index].meta.show_site, //是否全屏顯示
web_title: route_data[index].meta.web_title //網(wǎng)站標(biāo)題
},
children: [] //嵌套路由
};
for (let i = 0; i < route_data[index].children.length; i++) {
init_route_data[index].children[i] = {
path: route_data[index].children[i].path, //路由url
name: route_data[index].children[i].name, //路由名
component: () =>
import(`@/${route_data[index].children[i].component}`),
// component:(resolve) => require([`@/views/${route_data[index].children[i].component}`], resolve), //加載后端json描述的vue文件
meta: {
//路由一些附加信息
show_site: route_data[index].children[i].meta.show_site, //是否全屏顯示
web_title: route_data[index].children[i].meta.web_title //網(wǎng)站標(biāo)題
}
};
}
} else {
//沒有children時生成路由數(shù)組方法
init_route_data[index] = {
path: route_data[index].path, //路由url
name: route_data[index].name, //路由名
component: () => import(`@/${route_data[index].component}`),
// component:(resolve) => require([`@/views/${route_data[index].component}`], resolve), //加載后端json描述的vue文件
meta: {
show_site: route_data[index].meta.show_site, //是否全屏顯示
web_title: route_data[index].meta.web_title //網(wǎng)站標(biāo)題
}
};
// console.log(index);
}
}
// console.log(init_route_data); //打印生成初始化路由數(shù)組
for (let index = 0; index < route_data.length; index++) {
//由于addRoutes已經(jīng)廢棄,所以需要循環(huán)使用addRoute進(jìn)行數(shù)組添加
router.addRoute(init_route_data[index]); //循環(huán)添加數(shù)組
}
// 這里放置刷新
// console.log('app');
// const index=window.location.href.lastIndexOf("#")
// const url=window.location.href.substring(index+1,window.location.href.length);
// this.$router.push(url)
}
}
init_route()
在main.js中引用:
import '@/unitui/init_route.js'//這是為了實(shí)現(xiàn)防止刷新路由丟失
此時便可完成刷新自動初始化
我們通過在app.vue文件中通過獲取路由中meta. show_site的值(0全屏顯示,1顯示在視圖內(nèi)),然后使用 v-if控制不同router-view的顯示來實(shí)現(xiàn)顯示位置的控制。
App.vue源碼:
<template>
<div>
<router-view v-if="!$route.meta.show_site" />
<el-container v-if="$route.meta.show_site">
<div @mouseenter="change_aside_menu('enter')" @mouseleave="change_aside_menu('leave')">
<el-aside :width="isCollapse?'65px':'200px'">
<Aside :Collapse="isCollapse"></Aside>
</el-aside>
</div>
<el-container>
<el-header>
<Header></Header>
</el-header>
<el-main>
<router-view></router-view>
</el-main>
<el-footer>
<Footer></Footer>
</el-footer>
</el-container>
</el-container>
</div>
</template>
1、如果你不喜歡我們的ui框架,你需要開發(fā)新的ui時,沒有ui框架的支持《組件管理》功能可能不能正常顯示(顯示空白),你可以將unitui/ subadmin/ SubAdmin.vue文件中style部分改為:
#sub_admin_back {
width: 100%;
/* 非ui框架將height寫為height: 100vh; */
height: 100vh;
background-size: cover;
position: relative;
background-color: #ffffff;
border-radius: 10px;
}
1、沒能盡可能減少對框架的干擾,你仍然需要保持對main.js的適當(dāng)修改。
你喜歡可以關(guān)注我、獲取最新ui信息
為最強(qiáng)安卓視頻播放器,老玩家都知道KODI是安卓端影音玩家必裝App,因為KODI不是手機(jī)或者TV盒子的本地視頻播放器那么簡單。
除了播放本地視頻以外,KODI還可以通過網(wǎng)絡(luò)掛載播放NAS上的電影和電視劇、看電視直播等等,功能非常強(qiáng)悍,這里給新手朋友們分享下手機(jī)KODI關(guān)聯(lián)NAS的教程,覺得有用的話記得關(guān)注點(diǎn)贊收藏三聯(lián)哈。
KODI最早叫XBMC,全稱是XBox Media Center,翻譯過來就是Xbox媒體中心。
Xbox作為性價比最高的藍(lán)光機(jī)不是亂吹,于是乎XBMC也跟著火了起來,后面改名KODI,目前已支持到Windows、Linux、安卓和蘋果,可以說是全平臺制霸。
https://npcitem.jd.hk/100023437264.html
官方下載地址:點(diǎn)我
https://kodi.tv/download/
部分NAS老玩家覺得KODI不好用,因為很多KODI的關(guān)聯(lián)教程使用的是SMB協(xié)議傳輸,這個落后的協(xié)議確實(shí)會導(dǎo)致播放卡頓。
解決方案是使用NFS或者FTP協(xié)議,個人推薦是NFS協(xié)議,威聯(lián)通和群暉目前都已經(jīng)支持到NFS v4,具體管不管用請根據(jù)下文教程配置后自行體驗,好不好看療效。
威聯(lián)通和群暉的配置方法完全不一樣,這一段做分別講解。
Part.1:威聯(lián)通配置NFS共享文件夾
先說威聯(lián)通吧,畢竟今年雙十一入手威聯(lián)通的用戶太多了。
打開威聯(lián)通的控制臺,找到網(wǎng)絡(luò)&文件服務(wù),點(diǎn)擊Win/Mac/NFS/WebDAV。
點(diǎn)擊Linux NFS服務(wù),將這里的三個選項都勾選上,點(diǎn)擊應(yīng)用。
還是剛才的頁面,點(diǎn)擊下圖中的設(shè)置網(wǎng)絡(luò)共享,跳轉(zhuǎn)到FileStation配置共享文件夾。
找到需要進(jìn)行NFS共享的文件夾,這里我以Movie文件夾為例,點(diǎn)擊右側(cè)的編輯權(quán)限按鈕。
點(diǎn)擊選擇編輯權(quán)限類別,選擇NFS主機(jī)訪問。
選中剛才的Movie文件夾,勾選上訪問權(quán)限,Squash權(quán)限改為讀寫,賬戶改為所有用戶。
Part.2:群暉配置NFS共享文件夾
進(jìn)入群暉的控制面板,點(diǎn)擊文件服務(wù),在SMB/AFP/NFS的TAB下找到NFS,勾選開啟。
點(diǎn)擊藍(lán)色字體的共享文件夾,跳轉(zhuǎn)進(jìn)入文件夾配置。
選中想要通過NFS共享的文件夾,這里我想要的是Movie文件夾,選中后點(diǎn)擊編輯。
點(diǎn)擊NFS權(quán)限,正常這里是空的,點(diǎn)擊新增。
跳轉(zhuǎn)后這里需要做三個修改:
IP填*,即所有其他設(shè)備均可訪問這個文件夾
Squash將默認(rèn)的無映射切換成映射Root為Admin
勾選下面的三個選項
完成操作后確認(rèn)保存。
做完NAS上的NFS共享配置后,開始KODI的關(guān)聯(lián)操作,首先進(jìn)入KODI,點(diǎn)擊進(jìn)入文件區(qū)。
接著點(diǎn)擊添加視頻。
點(diǎn)擊瀏覽。
下拉找到網(wǎng)絡(luò)文件系統(tǒng)(NFS),點(diǎn)擊之后會卡頓個幾秒,不要慌張,因為在搜索局域網(wǎng)內(nèi)開啟了NFS的服務(wù)器。
搜索完成后,這里會顯示該網(wǎng)絡(luò)下所有開啟了NFS服務(wù)的設(shè)備,這組網(wǎng)絡(luò)下只有一臺,點(diǎn)擊。
接著會顯示這臺NAS下開放NFS共享的文件夾,這里能看到我剛配置的Movie文件夾,點(diǎn)一下進(jìn)入這個文件夾后,確認(rèn)。
畢竟KODI還有掛載手機(jī)文件夾的功能,多了容易混亂,還是為這個NAS的掛載文件夾重命名比較好,起一個你能記得住的名字。
點(diǎn)擊“”該目錄包含”,由于這個文件夾里面都是電影,所以類型選擇電影。
確認(rèn)后回到電影這個類別,能看到剛才創(chuàng)建好的qnap共享文件夾。
點(diǎn)進(jìn)去可以看到該文件夾下面的所有電影(這里只有一部測試樣片)。
播放這個經(jīng)典的美女烤鴨4K電視作為測試,幾乎是秒開,延遲大約50ms樣子。
做個回拉操作測試,加載有110ms左右的延遲,但是播放期間絕對不可能卡頓,大家可以自行嘗試,4K播放毫無壓力。
推薦下和本文關(guān)聯(lián)度比較高的設(shè)備。
NAS:威聯(lián)通(QNAP)TS-453Dmini
https://item.jd.com/100016702340.html
推薦理由:聊到今天最強(qiáng)性價比,當(dāng)然是威聯(lián)通453Dmini啊,J4125+8G+雙2.5G網(wǎng)口=2150元,請問還有誰?除了高性價比以外,QTS5.0相比4.x也進(jìn)化了不少,最顯著的就是5.10LTS的內(nèi)核升級,之前卡頓問題緩解很多,放心入手吧,我也會出不少教程的。
NAS:群暉(Synology)DS920+
https://item.jd.com/100014187272.html
推薦理由:群暉的DSM系統(tǒng)目前是無法替代的存在,今年群暉也沒新款了,據(jù)說明年Q2才會發(fā)布新機(jī),購買的話建議一步到位直接920+吧。
手機(jī):一加 OnePlus 9 Pro
https://item.jd.com/100019141914.html
推薦理由:MD,真的是怕啥來啥,現(xiàn)在用的手機(jī)不小心摔了下,屏幕有點(diǎn)失靈,目前對比之后想要這款,目前對比之后想要買這款,三星 Amelod E4材質(zhì)2K+120Hz高刷LTPO柔性屏,支持DisplayMateA+、HDR10+,并且拿過13項DisplayMateA+顯示紀(jì)錄,旗艦配置驍龍888+LPDDR5+UFS3.1猛如虎,主要饞的是索尼IMX789+索尼IMX766自由曲面抗畸變鏡頭,OIS光學(xué)防抖,8K30幀+4K120幀視頻拍攝,配合哈蘇影像系統(tǒng)出的片子真不錯,IP68防水配上2年售后質(zhì)保很良心。
路由器:中興 AX5400Pro
https://item.jd.com/100027895572.html
推薦理由:中興剛送過來做測試的新款WiFi6硬路由,還在預(yù)售中,無線信號強(qiáng)度穩(wěn)得有點(diǎn)嚇人,具體到時候看我評測吧,老粉絲都知道我很少這么夸市售的硬路由,很負(fù)責(zé)任的告訴大家真的強(qiáng),有緣看到本文可以直接無腦下單。
KODI的玩法其實(shí)非常多,怕篇幅太長你們懶得看,關(guān)于看電視直播這些下一篇再聊。
是編程樂趣,一個10年.Net開發(fā)經(jīng)驗老程序員,點(diǎn)擊右上方“關(guān)注”,每天為你分享開源項目和編程知識。
推薦一個可以將Html頁面轉(zhuǎn)為PDF的開源項目。
01
項目簡介
這是一個基于.Net開發(fā)的開源項目,本質(zhì)是用 Webkit 引擎將 HTML 頁面轉(zhuǎn)換為 PDF,可以用在控制臺、 Web 應(yīng)用程序和 Web API中。
02
使用示例
1、創(chuàng)建轉(zhuǎn)化器
//同步轉(zhuǎn)化器
var converter = new BasicConverter(new PdfTools());
//異步轉(zhuǎn)化器
var converter = new SynchronizedConverter(new PdfTools());
在多線程程序和 Web 服務(wù)器中可以使用異步轉(zhuǎn)換器,避免轉(zhuǎn)換任務(wù)阻塞其他線程。
2、定義文檔格式
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Landscape,
PaperSize = PaperKind.A4Plus,
},
Objects = {
new ObjectSettings() {
PagesCount = true,
HtmlContent = @"<h1>標(biāo)題1</h1>
內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容",
WebSettings = { DefaultEncoding = "utf-8" },
HeaderSettings = { FontSize = 9, Right = "Page [page] of [toPage]", Line = true, Spacing = 2.812 }
}
}
}
3、轉(zhuǎn)換
byte[] pdf = converter.Convert(doc);
if (!Directory.Exists("Files"))
{
Directory.CreateDirectory("Files");
}
using (FileStream stream = new FileStream(@"Files\" + DateTime.UtcNow.Ticks.ToString() + ".pdf", FileMode.Create))
{
stream.Write(pdf, 0, pdf.Length);
}
效果如下:
03
項目地址
https://github.com/rdvojmoc/DinkToPdf
- End -
推薦閱讀
一個用于操作Excel文件的.NET開源庫
基于ASP.NET MVC開發(fā)的、開源的個人博客系統(tǒng)
推薦一個Star 1.3K報表.Net開源項目
.Net開發(fā)的跨平臺Word模板引擎
基于.NetCore開源的Windows的GIF錄屏工具
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。