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