引言
在Vue的单页面的应用中我们已经习惯了使用了模板语法、js代码、以及样式的三部曲实现,这样的普适的写法已经能够满足大部分的开发需求,Vue在官网中还提供了许多灵活的高效的语法、API来提供给开发者使用,我们下面来看看这些好用有趣的。
正文
一、混入(mixin)
混入 (mixin) 提供了一种非常灵活的方式,来分发Vue组件中的可复用功能。一个混入对象可以包含任意组件选项即生命周期、基础数据、实例方法、当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。当我们在每个单页面中都需要使用到数据、方法都可以在一个外部的对象中
定义然后导入到对应的实例中。就是可以认为是实例的加强。
// 单页面组件
<template>
<div class=''>
{{mixinData}} // '我是混入的数据'(可以引入到混入的对象的data)
</div>
</template>
<script>
import mixin from'./mixin'
export default {
mixins:[mixin],
data () {
return {
innerData:'我是单页面本身的数据'
};
},
methods: {
mixins(){
alert('我是单页面的方法')
}
},
created() {
alert('我是单页面本身created的生命周期')
this.mixins() //
},
}
// 混入的对象mixin
export default {
created(){
alert('我是mixin内部的created的生命周期')
},
data(){
return {
mixinData:'我是混入的数据'
}
},
methods: {
mixins(){
alert('我是mixin内部的方法')
}
},
}
输出的结果:我是mixin内部的created的生命周期
-> 我是单页面本身created的生命周期
-> 我是单页面的方法
总结注意敲黑板
:
- 同名钩子函数(created,mounted等)将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。
- 值为对象的选项,例如methods、components和directives等将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对
一切以组件优先
- 数据对象data在发生冲突时以组件数据优先
二、渲染函数
VUE在模板文件中使用的还是html js css 分离的模板语法来构建单页面的应用,但是笔者感觉对html的标签的控制略显不足,对于根据数据的不同展示不一样的标签可能会出现支持不够的情况,或者说需要完全遍历所有的可能的情况。这样无疑是冗余的也是低效的。
这边我们引入官方的实例来更好的解释。
<template>
<div class=''> // 根绝参数来渲染出不同的行标签你会发现下面的代码是冗余的,不但代码冗长,而且在每一个级别的标题中重复书写了 <slot></slot>
<h1 v-if="type === 1">
<slot></slot>
</h1>
<h2 v-else-if="type === 2">
<slot></slot>
</h2>
<h3 v-else-if="type === 3">
<slot></slot>
</h3>
</div>
</template>
<script>
export default {
props: {
type: {
type: Number, // 引入了一个父组件传入的参数
default: 1
},
},
}
</script>
<style lang='less' scoped>
</style>
如果需要更多的行标签
那么template中的又会逐渐增多,同时会增加判断语句的反复执行。这样既费力又不讨好的事情我们应该避免。于是我们会引入render()
来进行渲染。也就是使用render
函数来代替template标签
中关于标签的渲染。
子组件
import Vue from 'vue'
Vue.component('Heading',{
render:function(createElement){
return createElement(`h${this.type}`,this.$slots.default) // 这行代码完成了模板渲染中的关于h标签的选择部分
},
props: {
type: {
type: Number,
default: 1
},
},
})
<!--父组件-->
<Heading :type="2">123</Heading> // 渲染结果 <h2>123</h2>
createElement
是渲染函数可接受的参数,使用createElement可以构建出可供渲染的树结构。第一个参数为标签、第二个为标签对应属性值,第三个个可以嵌套的createElement数组
也就是子标签的数组。数组内部的createElement选项
也可以嵌套。详细的解决方案以及实例可以查看官方文档,这里是提供一种思路。
import Vue from 'vue'
Vue.component('Heading',{
render:function(createElement){
return createElement(`div`,[createElement('h1','h1的内容'),createElement('h2','h2的内容')])
},
})
上述的渲染函数出来的dom等同于:
<div>
<h1>h1的内容</h1>
<h2>h2的内容</h2>
</div>
三、函数式组件
函数式组件区别于一般组件的是没有生命周期、响应式数据、计算属性等,也就是说函数式组件可以理解为它是一个没有vue实例的组件,他只接受一个
props
的传参,这个也为他带来了渲染快速的特点。
个人的使用场景:我会使用在多同级组件的封装。例如我这边有个展示的需求,我想要通过卡片、列表等可选择的展示方式展示同一份数据源。如果我们将这些代码都写在一个组件中
解耦度低
,如果我们将展示都写成组件,全部引入父组件这样代码又出现了冗余
。于是我们可以提供一个组件来分发
符合条件的组件。既可以单独使用各个展示组件,又可以使用同一封装的组件。
// 父组件
<template>
<div class='father'>
<card-component v-if="type===card"></card-component> // 不同组件我们需要都引入到父组件中
<list-component v-if="type===list"></list-component>
<circle-component v-if="type===circle"></circle-component>
</div>
</template>
<script>
export default {
data () {
return {
type:'card'
};
},
}
</script>
//重写父组件
<template>
<div class='father'>
<function-component :type="type"></function-component> // 函数组件分发
</div>
</template>
//函数组件
<template functional> // functional是标记模板语法这个组件是函数式组件,如果不使用模板就应该设置functional:true
<div class='father'>
<card-component v-if="prop.type===card"></card-component> // 不同组件我们引入函数组件
<list-component v-if="prop.type===list"></list-component>
<circle-component v-if="prop.type===circle"></circle-component>
</div>
</template>
结束
如果有新的还是会持续更新的哟。