1 render函数与template
render函数与template有什么异同点:
相同点: 都是类编译器
不同点(Vue的渲染过程): template是vue的模板语法,在编译时,会通过render函数创建真实的元素,然后根据真实的元素会生成虚拟dom,然后再根据虚拟dom生成真实的元素。
*template和render是互补的关系,复杂的可以用render处理
优化:
<template>
<div style="height: 400px">
<!-- 高复用性; 模板更加间接明了; 集中化处理 -->
<Button :type="type" :text="text"></Button>
</div>
</template>
<script>
import Button from './Button.vue'
export default {
data() {
return {
type: 'success',
text: 'successBtn'
}
},
components: {
Button
}
}
</script>
<script>
export default {
name: 'MzButton',
props: {
type: {
type: String,
default: ''
},
text: {
type: String,
default: ''
},
},
render(h) { // 相当于createElement,用来创建真实元素
return h('button', {
class: { // v-bind: class
btn: true,
'btn-success': this.type === 'success',
'btn-error': this.type === 'error',
'btn-warning': this.type === 'warning',
'normal': !this.type
},
domProps: {
innerText: this.text || '默认按钮'
}
})
}
}
</script>
<style scoped>
.btn {
width: 100px;
height: 40px;
color: white;
transition: all .5s;
}
.btn-error {
background: red;
}
.btn-success {
background: green;
}
.btn-warning {
background: yellow;
}
.normal {
background: blue;
}
</style>
2 将abc转化为Abc
function changeStr(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
3 全局组件的引入
01 创建一个common文件夹,放置所有的组件,如下面的child组件
<template>
<h1>
我是MzChild组件
</h1>
</template>
<script>
export default {
name: 'MzChild',
}
</script>
02 在common文件夹下面创建一个global.js, 管理所有组件
常规引入注册:
import Vue from 'vue'
// import Child from './Child'
// import Button from './Button'
// Vue.component('MzChild', Child)
// Vue.component('MzButton', Button)
高级引入(使用require.context):
import Vue from 'vue'
function changeStr(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
/***
* require.context => webpack Api(动态引入文件)
* params: 当前路径,是否匹配子集,文件格式
*/
const requireComponent= require.context('./', false, /\.vue$/)
// console.dir(requireComponent.keys()) // 要找的所有路径
requireComponent.keys().forEach(fileName => {
// 获取当前组件
const currentCom = requireComponent(fileName)
// 获取当前组件的组件名 默认将./Button.vue 变成 MzButton
const defaultComName = 'Mz' + changeStr(fileName.replace(/^\.\//, '').replace(/\.\w+$/,''))
const comName = currentCom.default.name || defaultComName
// 全局注册组件
Vue.component(comName, currentCom.default || currentCom)
})
03 在入口文件(main.js)中引入global
import MzUi from './common/global.js' // 引入所有组件
04 使用
<MzChild></MzChild>
4 按钮权限控制的实现(自定义指令)
<MzChild v-permission="'1'"></MzChild>
import Vue from 'vue'
function checkArray(key) {
const arr = ['1', '4', '5', '7'] // 后端返回的权限表
const i = arr.indexOf(key)
return i > -1
}
Vue.directive('permission', {
inserted(el, binding) {
const permissionValue = binding.value // 元素上绑定的权限值
if (permissionValue) {
// 判断该用户是否有权限
const hasPermission = checkArray(permissionValue)
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
} else {
throw new Error('请插入权限值')
}
}
})