使用react得的小伙伴对函数式组件一定不陌生,函数式组件最直观的叫法则是渲染函数render function,因为写出来真的就是个用来渲染的函数而已,。Vue中将组件标记为functional即为函数式组件,这意味着它是无状态(没有响应式数据),也没有实例(没有this上下文),不管理任何状态的组件。因此它具有渲染开销低,执行速度快、逻辑更清晰、可以返回多个根节点等特点。
业务组件设计思想:
- 接收提示文字内容(只收不存不改)
- 控制对话框显示与否的变量只依靠外部,自身不存
- 生命周期-取决于外部
编写一个复用性比较强的组件,应该注意的是数据流单向传递,始终做到父=》子传递数据,避免页面逻辑混乱。
下面使用函数式组件手写一个对话框:
父组件:
<template>
<div class="parent">
<h1>函数式组件练习,手写一个高性能通用对话框</h1>
<button class="btn" @click="btn1()">点击按钮1</button>
<button class="btn" @click="btn2()">点击按钮2</button>
{{isShow}}
<!-- <MessageBox :value="isShow" @input="(val)=>{isShow = val}"/> -->
<MessageBox
:key="Math.random()"
v-model="isShow"
:title="conf.title"
:message="conf.message"
@submit="onsubmit"
@cancel="oncancel"/>
</div>
</template>
<script>
import MessageBox from '@/componentsCommon/MessageBox.vue'
export default {
name: "Params",
components:{
MessageBox
},
data(){
return{
isShow: false,
conf:{
title: "",
message: ""
}
}
},
methods:{
onsubmit(){
console.log("onsubmit");
},
oncancel(){
console.log("ononcancelsubmit");
},
btn1(){
this.isShow = true,
this.conf.title = "对话框1温馨提示"
this.conf.message = "对话框1确认关闭吗?"
},
btn2(){
this.isShow = true,
this.conf.title = "对话框2温馨提示"
this.conf.message = "对话框2确认关闭吗?"
},
}
}
</script>
上面代码中使用,key值是为了避免框架认为是相同得一个组件,不改变任何值,就地复用,为了保证每次得到得key都不相同,所以使用Math.random()随机生成一个浮点数,在vue虚拟DOM使用diff算法对比时key值不同,就会重新创建DOM。
对话框函数式组件(子组件):
<script>
export default {
//标记成为函数式组件
functional: true,
name: "MessageBox",
props: {
value:{
type: Boolean,
required:true
},
title: {
type: String,
required: false
},
message: {
type: String,
required: false
}
},
render(h, context){
const { input, submit, cancel } = context.listeners
const { value, title, message} = context.props
function close(tag) {
tag ? submit():cancel()
input(false)
}
console.log(context);
return(
<transition name="fade">
{
value &&
<div class="msg-box">
<h1>子组件</h1>
<h1>{ title }</h1>
<hr/>
<h1>{ message }</h1>
<button onClick={ e=>close(true)}>确认</button>
<button onClick={ e=>close(false)}>取消</button>
</div>
}
</transition>
)
}
}
</script>
以上使用函数式组件编写的对话框组件不需要生命周期,不需要存储自身的数据,完全依赖外部的特点,在性能上要比普通对话框性能能得到一定程度的优化。