vue2 函数式组件学习(文档)
1.特点
- 没有管理任何状态
- 没有监听任何传递给他的状态
- 没有生命周期钩子函数(没有this,不需要实例化)
- 只是接收一些props函数
日常开发中,经常会开发一些纯展示性的业务组件,如:详情、列表,他们有个共同点就是:
- 只要你传入数据,就进行展示
- 不需要定义任何状态,不需要生命周期钩子函数做处理
- 这个时候就可以用函数式组件
2.为什么使用它?
- 函数式组件不需要实例化,无状态,没有生命周期,所以渲染性比普通组件好
- 函数式组件结构更简单,代码更清晰明了
3.函数式组件与普通组件的区别?
1.函数式组件需要在声明组件是指定functional,使用click方法必须加 v-on=“listeners” 才生效
2.函数式组件不需要实例化,所以没有this,this通过render函数的第二个参数来代替。
3.函数式组件没有生命周期钩子函数,不能使用计算属性,watch等等。
4.函数式组件不能通过$emit对外暴露事件,调用事件只能通过context.listeners.click的方式调用外部传入的事件。
5.因为函数式组件是没有实例化的,所以在外部通过ref去引用组件时,实际引用的是HTMLElement。
1.函数式组件写法
父组件
<template>
<div class='page-demo-wrapper'>
<div class="item" v-for="(item,idx) in list" :key="idx">
<cell-item label="主题" value="组件" :arrow="false"></cell-item>
<cell-item label="姓名" :value="item.userName" @click="handleName"></cell-item>
<cell-item label="性别" :value="handleSex(item.sex)"></cell-item>
</div>
</div>
</template>
<script>
import CellItem from './components/CellItem2.vue'
export default {
name: 'Demo',
components: { CellItem },
data() {
return {
list: [{
userName: '测试函数式组件1',
sex: 'female'
}],
sexStatus: { 'male': '男','female': '女'}
}
},
methods: {
handleName() { console.log('编辑姓名') },
handleSex(val) {
if (val) {
return this.sexStatus[val]
}
}
}
}
</script>
<style scoped lang='less'>
.page-demo-wrapper {
.item {
margin: 15px;
background: #ffffff;
box-shadow: 0px 0px 5px 0px rgba(231, 56, 14, 0.25);
border-radius: 10px;
}
}
</style>
子组件
<template functional>
<div class="comp-demo-wrapper" v-on="listeners">
<div class="label">{{props.label}}</div>
<div class="value" :class="{'arrow': props.arrow == undefined? true: false}">{{props.value}}</div>
</div>
</template>
<style lang="less" scoped>
@PaddingSize: 15px;
.comp-demo-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px @PaddingSize;
position: relative;
font-size: 14px;
&::before {
content: '';
position: absolute;
bottom: 0;
left: @PaddingSize;
right: @PaddingSize;
height: 1px;
background: #efefef;
}
.label {
color: black;
}
.value {
color: #666;
position: relative;
text-align: right;
min-width: 100px;
&.arrow {
padding-right: 14px;
@ArrowSize: 8px;
&::after {
content: '';
// 如果是伪元素必须加 relative
position: absolute;
top: 50%;
right: 0;
width: @ArrowSize;
height: @ArrowSize;
border: 2px solid #999;
border-left: none;
border-bottom: none;
transform: translateY(-50%) rotate(45deg);
}
}
}
}
</style>
运行效果
2.动态样式
注意:
父组件要加class,子必须添加 data.staticClass 才能加上
父组件要加行内样式,子必须添加 :style=“data.staticStyle” 才能加上
父组件
<TipsInfo class="tips" style="background:red">您好!</TipsInfo>
.tips{
padding:10px;
}
子组件
<template functional>
<div :class="['comp-tips-wrapper', data.staticClass]" :style="data.staticStyle" >
<slot></slot>
</div>
</template>
<style lang="less" scoped>
.comp-tips-wrapper {
color: #ff6600;
font-size: 16px;
margin: 0;
line-height: 24px;
word-break: break-all;
}
</style>