摘要:以下也將以進行展開說明。這個鍵值來自于在命令行界面與用戶交互的操作結果。鍵名對應的值為命令行交互中得到的數據。關于項目模板的開發涉及到的問題差不多就介紹完了,為自己或團隊開發一份專屬的吧原文深度定制團隊自己的
眾所周知,使用 vue-cli 可以快速初始化一個基于 Vue.js 的項目,官方提供了 webpack、pwa、browserify-simple 等常用 templates。
當開發一個獨立項目的時候,使用官方提供的 template 確實非常方便,省去了繁瑣的依賴安裝配置、webpack 配置,甚至連項目結構也不用多加考慮。
但是,當我們需要開發多個系統,每個系統相對獨立但又有一些配置、依賴或邏輯相互通用的時候(例如集群的多后臺系統),每次使用官方提供的 template 初始化項目之后,都需要進一步調整(添加依賴、修改配置、增加通用組件等等),這顯然是十分麻煩的。
本著懶惰是第一生產力的初衷,我們需要定制一份自己的 template,以便我們...額...偷懶哈~
在開始定制我們自己的 Vue template 前,我們需要了解一些前置知識:
前置知識
模板結構
首先我們先來了解模板的主要結構,模板結構很簡單,主要包括兩個部分:
template 該目錄用于存放模板文件,初始化項目生成的文件來自于此。
meta.js / meta.json 用于描述初始化項目時命令行的交互動作。
Metalsmith
Metalsmith 在渲染項目文件流程中角色相當于 gulp.js,可以通過添加一些插件對構建文件進行處理,如重命名、合并等。
download-git-repo
使用 vue-cli 初始化項目時會使用該工具來下載目標倉庫。默認的 webpack 等模板直接下載 vue-templates 中對應的模板倉庫。
自定義的模板也可以是一個 GitHub 倉庫,使用如下命令來初始化項目:
vue init username/repo my-project
其中 username 為自定義模板倉庫所在的 GitHub 用戶或組織名,repo 為倉庫名。
Inquirer.js
vue-cli 在模板倉庫下載完成后,將通過 Inquirer.js 根據模板倉庫中的 meta.js 或 meta.json 文件中的設置,與用戶進行一些簡單的交互以確定項目的一些細節,如下圖:
該交互配置是可選的,當項目中沒有 meta.js 或 meta.json 文件時,模板倉庫下載完成后將直接進入模板構建階段。
Handlebars.js
在通過命令行交互確定了項目初始化的細節后,就該進入最后一道工序,按照模板初始化我們的項目啦!(≧▽≦)/
這里 vue-cli 選用的是 Handlebars.js —— 一個簡單高效的語義化模板構建引擎。
畫了一張圖,更有助于理清這些依賴在 vue-cli 初始化項目時的相互關聯:
定制模板主要圍繞著命令行交互(Inquirer.js)與模板文件開發(Handlebars.js)這兩部分。meta.js 配置文件(Inquirer.js)
由于 meta.js 相當于模板項目的配置文件(雖然非必選),所以這里先看看它主要能干些啥。
設置都在 meta.js 或 meta.json 中配置,推薦使用 meta.js,更靈活一些。以下也將以 meta.js 進行展開說明。
meta.js 一共可包含如下幾個字段,簡單列一下各字段功能:
helpers : 自定義 Handlebars.js 的輔助函數
prompts : 基于 Inquirer.js 的命令行交互配置
filters : 根據命令行交互的結果過濾將要渲染的項目文件
metalsmith : 配置 Metalsmith 插件,文件會像 gulp.js 中的 pipe 一樣依次經過各個插件處理
completeMessage : 將模板渲染為項目后,輸出一些提示信息,取值為字符串
complete : 與 completeMessage 功能相同,二選其一,取值為函數,函數最后需返回輸出的字符串
命令行交互(Inquirer.js)命令行交互主要是 meta.js 中 prompts 字段的配置,詳細的配置可以閱讀 Inquirer.js 的 README.md,這里說一下常用的交互配置:
// meta.js module.export = { // ... "prompts": { "isCustomName": { "type" : "confirm", "message": "是否自定義系統名稱?", }, "sysName": { "type" : "input", "when" : "isCustomName", "default" : "默認系統名稱", "message" : "請輸入系統名稱:", "required": true, "validate": function (val) { if (!val) return "(?) 請輸入系統名稱,該名稱將設為 index.html 的 title"; return true; }, }, // ... }, }
字段說明:
isCustomName 與 sysName : 交互字段名稱,可在后續條件交互或模板渲染時通過該字段讀取到交互結果
type : 交互類型,有 input, confirm, list, rawlist, expand, checkbox, password, editor 八種類型
message : 交互的提示信息
when : 進行該條件交互的先決條件,在該例子中,sysName 這個交互動作只在 isCustomName 交互結果為真時才會出現
default : 默認值,當用戶輸入為空時,交互結果即為此值
required : 默認為 false,該值是否為必填項
validate : 輸入驗證函數
注:示例中 default required validate 三個字段存在邏輯問題,僅為舉例方便放到一起。模板基本語法(Handlebars.js)
在模板編寫中,我們可以用 Mustache 語法在任何文本類型的文件中輸出在命令行交互中得到的一些數據:
// dev.js export default { //... token: "{{token}}", //... };
{{sysName}}
以 {%raw%}{{xxx}}{%endraw%} 即為一個 Mustache 句法標記。以上例子中 token 與 sysName 為匹配命令行交互數據對應的鍵名。
對 vue 有過了解的都知道,在模板標簽中直接輸出實例上的數據也是用的 Mustache 語法。模板渲染時的輔助函數(Handlebars.js)
如果定制 vue template 模板時不對這些數據做相應處理,在最終輸出由模板初始化的項目時,這些與命令行交互得到的數據無法匹配的 Mustache 句法標記會被移除。
此時我們需要使用反斜杠 {%raw%}{{xxx}}{%endraw%} 或者 {%raw%}{{{xxx}}}{%endraw%} 來跳過 Handlebars 的處理,直接輸出 {%raw%}{{xxx}}{%endraw%}
vue-cli 中為 Handlebars 預置了 if_eq 與 unless_eq 輔助函數,用于使用交互所得數據來處理模板中是否渲染的兩種邏輯關系,此外 Handlebars 中還內置了 if、unless、each 等 輔助函數。
// sys.js export default { {{#if_eq projType "admin"}} id: {{#if_eq sysId ""}}undefined{{else}}{{sysId}}{{/if_eq}}, {{/if_eq}} name: "{{sysName}}", };
如上,這里用了 if_eq 輔助函數,projType 代表將要匹配的鍵,"admin" 代表將要匹配的值。這個鍵值來自于在命令行界面與用戶交互的操作結果。該栗子中,當命令行交互數據中 CLI[projType] == "admin" 時,將在 sys.js 文件的導出數據中輸出 id 字段;id 的值來自一個嵌套的 if_eq 輔助函數,當 CLI[sysId] == "" 時,id 將被設置為 undefined 否則 ({%raw%}{{else}}{%endraw%})輸出 CLI[sysId] 命令行交互所得數據中的 sysId。
輔助函數使用語法: {%raw%}{{{%endraw%}# + 函數名 + " "(空格)+ 以空格分隔的參數列表 + }}自定義輔助函數(Handlebars.js)
以空格分隔的參數列表:未用引號包裹的參數名將被將為自動取值為命令行交互結果中對應的數據
有時候現有的輔助函數可能不能滿足我們的需求,通過 mate.js 中的 helpers 字段我們可以自定義輔助函數:
// mate.js module.exports = { "helpers": { "neither": function (k, v1, v2, options) { if (k !== v1 && k !== v2) { return options.fn(this); } return options.inverse(this); }, }, //... }
輔助函數可以接受若干的參數,最后一個參數 options 為輔助函數的鉤子,調用 options.fn(this) 即輸出該輔助函數運算結果為真時的內容,反之調用 options.inverse(this) 則輸出 {%raw%}{{else}}{%endraw%} 的內容(如果有的話)。
現在我們可以在模板中直接使用 neither 輔助函數了:
{{#neigher sysType "admin" "mobile"}} isAdmin = false isMobile = false {{else}} isAdminOrMobile = true {{/neigher}}按條件過濾渲染文件
輔助函數只可以控制文件內一部分內容的輸出與否,有時候我們需要根據交互結果控制某些文件本身是否輸出。
在 mate.js 中的 filters 字段中進行相應的設置,就可以達到控制文件輸出的效果:
module.exports = { //... "filters": { "project/config/test.env.js": "unit || e2e", "project/src/router/**/*": "router" }, //... }
filters 中鍵名是要控制輸出的文件的路徑,可使用字面量,也可使用 簡化的 glob 表達式。鍵名對應的值為命令行交互中得到的數據。
渲染時文件的操作在模板項目比較復雜或是有特殊需求的時候,比如:
按照條件不同需要渲染兩個文件名相同但內容完全不同的文件
模板模塊化,多個模板文件拼接渲染為一個項目文件
使用 GZip 壓縮一些非源碼資源
可以通過 mate.js 中的 metalsmith 字段配置相關插件來實現豐富的文件操作:
var renamer = require("metalsmith-renamer") module.exports = { //... "metalsmith": function(metalsmith, opts, helpers) { metalsmith.use(renamer({ index: { pattern: "project/**/+(Mobile|Admin)Index.vue", rename: function(fileName) { return "Index.vue"; } }, config: { pattern: "project/src/+(mobile|admin)Config.js", rename: "config.js" }, //... })) }, //... }
以上是 metalsmith-renamer 插件的簡單使用,更多插件可以在這里查找
使用 metalsmith 插件請注意:由于 vue-cli 在下載完成模板倉庫后并沒有 npm install 安裝模板的項目依賴這一操作,所以在打包模板倉庫的時候也需要將依賴目錄 node_modules 一同打包,metalsmith 的插件都很精簡,一般不會有什么嵌套依賴。不過還是建議在使用前查看一下插件的相關 Github 倉庫。
關于 vue 項目模板的開發涉及到的問題差不多就介紹完了,為自己或團隊開發一份專屬的 Vue Template 吧!
原文: 深度定制團隊自己的 Vue template
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92436.html
摘要:而則是用到到指令結合的方式去生成,批量生成元素。表格操作列自定義渲染的時,使用的是的函數,直接在中插入對應模板表格分頁都需要引入分頁組件配合使用兩者總體比較,要比簡潔許多。 element VS iview(最近項目UI框架在選型 ,做了個分析, 不帶有任何利益相關)主要從以下幾個方面來做對比使用率(npm 平均下載頻率,組件數量,star, issue…)API風格打包優化與設計師友...
摘要:是有贊前端團隊維護的移動端組件庫,提供了一整套基礎組件和業務組件。一關于距離首次發布剛好過去了半年時間,在這半年時間里團隊廣泛吸納社區的反饋和建議,持續對組件進行打磨優化,使得逐漸成長為一個輕量可靠的移動端組件庫。 Vant 是有贊前端團隊維護的移動端 Vue 組件庫,提供了一整套 UI 基礎組件和業務組件。通過 Vant 可以快速搭建出風格統一的頁面,提升開發效率。 showImg(...
摘要:一個高度可復用的組件則可以被稱為控件,是可以單獨投稿項目庫的。行為的定制化通過參數綁定實現組件行為的定制化。組件被銷毀時調用。當有組件復用的情況時請使用標識指定接收對象模型另外最好給事件名添加組件前綴。 轉自自己在開源中國的博客:https://my.oschina.net/u/7247... angular 1 也要面向組件編程 前端組件化是前端開發模式中一個不可逆轉的趨勢,三大主要...
閱讀 2178·2021-11-24 09:38
閱讀 3242·2021-11-08 13:27
閱讀 3083·2021-09-10 10:51
閱讀 3143·2019-08-29 12:20
閱讀 663·2019-08-28 18:28
閱讀 3459·2019-08-26 11:53
閱讀 2706·2019-08-26 11:46
閱讀 1515·2019-08-26 10:56