在你們都會用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
複製代碼
運行程序,咱們看下是否可以正常顯示並分析兩句打印less
優化以後的代碼,會更靈活,更具備觀賞性,既便捷高效,又方便維護dom
不少人在寫組件的時候,會依賴腳手架中的<template></template>
標籤,其實template
也存在必定的缺陷,例如:函數
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咱們能夠這樣寫ui
// 建立一個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