在你們都會用vue
的時代,咱們又如何去區別是新手小白仍是資深vue
玩家呢? 如何讓本身與剛學vue
的人拉開差距呢? 其實,不少人對於vue
只停留在基礎使用。想要提高本身,就應該想辦法將其運用到更高的層次。前端
vue
的運用能力
組件
: 全局組件註冊Render函數
: 拯救繁亂的templateVue權限控制
: 高精度全局權限控制組件是咱們很是經常使用的東西,不少人使用組件都是經過一個一個文件去引用和註冊。若是一個組件在整個項目裏面的使用次數較多,每一次使用都須要引用並註冊,就會顯得特別麻煩vue
<template> <div> <h1>I am HelloWorld</h1> <Child1></Child1> </div> </template> <script> import Child1 from './child1.vue' // 引入 export default { name: 'HelloWorld', data(){ return{ } }, components:{ // 註冊 Child1 }, props: { msg: String }, methods:{ } } </script> <style scoped lang="less"> </style> 複製代碼
當咱們在項目須要重複屢次使用該組件,會致使出現不少重複的引入和註冊代碼,既繁瑣又不雅觀。所以咱們能夠經過一個全局的Js
文件來管理,將須要屢次使用的組件進行全局註冊vue-router
.js
文件管理全局組件// 1 - globalComponent.js import Vue from 'vue' // 引入vue // 處理首字母大寫 abc => Abc function changeStr(str){ return str.charAt(0).toUpperCase() + str.slice(1) } /* require.context(arg1,arg2,arg3) arg1 - 讀取文件的路徑 arg2 - 是否遍歷文件的子目錄 arg3 - 匹配文件的正則 關於這個Api的用法,建議小夥伴們去查閱一下,用途也比較普遍 */ const requireComponent = require.context('.', false, /\.vue$/) console.log('requireComponent.keys():',requireComponent.keys()) // 打印 requireComponent.keys().forEach(fileName => { const config = requireComponent(fileName) console.log('config:',config) // 打印 const componentName = changeStr( fileName.replace(/^\.\//, '').replace(/\.\w+$/, '') // ./child1.vue => child1 ) Vue.component(componentName, config.default || config) // 動態註冊該目錄下的全部.vue文件 }) 複製代碼
// 2 - 將globalComponent.js引入main.js import global from './components/globalComponent' 複製代碼
// 3 - 使用這類組件再也不須要引入和註冊,直接標籤使用便可
<template>
<div>
<h1>I am HelloWorld</h1>
<Child1></Child1>
</div>
</template>
複製代碼
運行程序,咱們看下是否可以正常顯示並分析兩句打印數組
假設咱們有不少路由,每個路由都經過傻瓜式的引入方式,會致使整個項目代碼量增多,繁瑣,更重要的一點是增長後期維護的難度。所以咱們也能夠經過上面相似的方式,對路由的引入和使用進行管理,實現分區引入路由,將不一樣功能下的路由進行區分,經過動態的方式進行引入,即方便快捷又增長可維護bash
.js
文件管理全部的路由總路由管理文件 - index.js
分區路由
- index.routes.js
- login.routes.js
在大型項目中,每每會有不少互不關聯的模塊,例如電商平臺中的商城,我的信息,這種狀況下就能夠對路由進行分區
複製代碼
// 分區路由文件寫法 export default { path:'/index', name:'Index', component: () => import('../views/Index.vue'), // 懶加載式引入,當跳轉到時才進行引入chunk children: [...] } 複製代碼
// 總路由管理文件 index.js 寫法 import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const routerList = [] // 路由數組 - 存放全部路由 function importAll(routerArr){ // 該函數用於將全部分區路由中的路由添加到路由數組 routerArr.keys().forEach( key => { console.log(key) routerList.push(routerArr(key).default) }) } importAll(require.context('.',true,/\.routes\.js/)) const routes = [ ...routerList ] const router = new VueRouter({ routes }) export default router 複製代碼
運行程序,咱們看下是否可以正常顯示並分析兩句打印markdown
優化以後的代碼,會更靈活,更具備觀賞性,既便捷高效,又方便維護less
不少人在寫組件的時候,會依賴腳手架中的<template></template>
標籤,其實template
也存在必定的缺陷,例如:dom
template
裏存在一值多判斷template
會使代碼冗餘,雜亂
VUE
給咱們提供了一個render
函數,咱們能夠經過這個函數巧妙的解決template
形成的問題函數
<template> <div> <h1>I am Home</h1> <!-- 假設按鈕有多種類型,經過value來顯示不一樣類型 --> <div v-if='value === 1'> <button>button1</button> </div> <div v-else-if='value === 2'> <button>button2</button> </div> <div v-else> <button>button3</button> </div> </div> </template> <script> export default { name: 'Home', data(){ return{ value:1 } }, methods:{ } } </script> <style scoped lang="less"> </style> 複製代碼
上面這種寫法,當出現多種類型的button,就會顯得雜亂無章,固然,不少人會選擇去封裝一個button組件,那麼這個組件的封裝,又是一個技巧點,利用VUE
的render
函數,減小沒必要要的template
,所以ru咱們能夠這樣寫優化
// 建立一個button.vue文件 寫法以下 <script> export default { props:{ type:{ type:String, default:'normal' }, text:{ type:String, default:'button' } }, render(h){ /* h 相似於 createElement, 接受2個參數 1 - 元素 2 - 選項 */ return h('button',{ // 至關於 v-bind:class class:{ btn:true, 'btn-success':this.type === 'success', 'btn-danger':this.type === 'danger', 'btn-warning':this.type === 'warning', 'btn-normal':this.type === 'normal', }, domProps:{ innerText: this.text || '默認' }, on:{ click:this.handleClick } }) }, methods:{ handleClick(){ this.$emit('myClick') } } } </script> <style scoped> .btn{ width: 100px; height:40px; line-height:40px; border:0px; border-radius:5px; color:#ffff; } .btn-success{ background:#2ecc71; } .btn-danger{ background:#e74c3c; } .btn-warning{ background:#f39c12; } .btn-normal{ background:#bdc3c7; } </style> 複製代碼
// 引入 <template> <div> <h1>I am Home</h1> <!-- 按鈕根據value顯示不一樣類型的button --> <Button type='success' text='button1' @myClick='...'></Button> </div> </template> <script> import Button from './button.vue' export default { name: 'Home', data(){ return{ value:1 } }, components:{ Button }, methods:{ } } </script> <style scoped lang="less"> </style> 複製代碼
上面這種寫法,根據value
來顯示不一樣類型的button
,咱們只須要經過value
去修改type,text
等,就能夠實現這一目的,而不須要去建立多個<button>
,經過v-if
去判斷
優化以後的代碼,避免了一值多判斷的缺點,減小冗餘,更加靈活, 這種方式較適合業務簡單,使用次數多的組件
權限的控制由前端處理的場景不少,例如根據後臺返回內容,判斷該人是否對此功能有權限,進而去修改元素
v-if / v-show
,這種狀況下,當這個功能在多處地方出現,就會致使咱們作不少不少沒必要要的重複代碼,若是判斷條件繁瑣的狀況,更加冗餘,代碼量也會增長不少。所以咱們能夠造一個小車輪,掛在全局上對權限進行處理
這種場景出現概率極高,尤爲是處理含有多種角色的項目,若是這一類型的權限判斷有屢次處理,每一次出現都經歷判斷的話,代碼將會異常難看且冗餘,所以咱們能夠經過全局權限判斷來處理
/* 在項目裏新建一個common文件夾用於存放全局 .js 文件 這種全局文件夾作法至關廣泛,通常項目裏都應該有這樣一個文件夾來管理全局的東西 */ // common/jurisdiction.js 用於存放與權限相關的全局函數/變量 export function checkJurisdiction(key) { // 權限數組 let jurisdictionList = ['1', '2', '3', '5'] let index = jurisdictionList.indexOf(key) console.log('index:',index) if (index > -1) { // 有權限 return true } else { // 無權限 return false } } 複製代碼
// 將全局權限Js掛載到全局中 // main.js import { checkJurisdiction } from './common/jurisdiction' // 優雅操做 - VUE自定義指令 Vue.directive('permission',{ inserted(el, binding){ // inserted → 元素插入的時候 let permission = binding.value // 獲取到 v-permission的值 if(permission){ let hasPermission = checkJurisdiction(permission) if(!hasPermission){ // 沒有權限 移除Dom元素 el.parentNode && el.parentNode.removeChild(el) } }else{ throw new Error('須要傳key') } } }) 複製代碼
// 使用方式 <template> <div> <h1>I am Home</h1> <!-- 按鈕根據value --> <div v-permission="'10'"> <button>權限1</button> </div> <div v-permission="'5'"> <button>權限2</button> </div> </div> </template> // 無需再經過value去判斷,直接經過v-permission的值進行判斷便可 複製代碼
運行程序,咱們看下是否可以正常顯示並分析打印
能夠看到v-permission = "'10'"
是沒有權限且不顯示,
v-permission = "'5'"
是具備權限且顯示
以上三個方面操做起來看似簡單,但不少人在寫代碼的時候,喜歡停留在業務上,只考慮可否實現,實際上,不少大型項目都須要有這些理念去減小代碼量,減小冗餘,在合適的場景下使用合適的方法才能提升本身的能力
❗ Tips: 若是文章有錯誤的地方,但願指出,以爲有用的小夥伴點個贊哦 QAQ