Vue表单类组件封装思路
核心步骤
- 子组件中:props通过value接收,事件触发input
- 父组件中:v-model给组件直接绑数据
src\components\BaseSelect.vue文件:
<template>
<div>
<select :value="value" @change="handleChange">
<option value="101">北京</option>
<option value="102">上海</option>
<option value="103">广州</option>
<option value="104">深圳</option>
</select>
</div>
</template>
<script>
export default {
props: {
value: String,
},
methods: {
handleChange(e) {
this.$emit('input', e.target.value)
},
},
}
</script>
src\App.vue文件:
<template>
<div>
<BaseSelect v-model="selectId"></BaseSelect>
</div>
</template>
<script>
import BaseSelect from './components/BaseSelect.vue'
export default {
data() {
return {
selectId: '102',
}
},
components: {
BaseSelect,
},
}
</script>
.sync修饰符
作用:可以实现子组件与父组件数据的双向绑定,简化代码。
特点:prop属性名可以自定义,非固定为value。
场景:封装弹框类的基础组件,visible属性:true显示、false隐藏。
本质:就是:属性名
和@update:属性名
合写。
src\components\BaseDialog.vue文件:
<template>
<div v-show="visible" class="base-dialog-mask">
<div class="base-dialog">
<div class="title">
<h3>温馨提示</h3>
<button class="close" @click="close">x</button>
</div>
<div class="content"><p>确认退出本系统么?</p></div>
<div class="footer">
<button>确认</button>
<button>取消</button>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
visible: Boolean,
},
methods: {
close() {
this.$emit('update:visible', false)
},
},
}
</script>
<style scoped>
.base-dialog-mask {
position: fixed;
left: 50%;
top: 50%;
width: 300px;
height: 200px;
box-shadow: 2px 2px 2px 2px #ccc;
transform: translate(-50%, -50%);
padding: 0 10px;
}
.base-dialog .title {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 2px solid #000;
}
.base-dialog .content {
margin-top: 38px;
}
.base-dialog .title .close {
width: 20px;
height: 20px;
cursor: pointer;
line-height: 10px;
}
.footer {
display: flex;
justify-content: flex-end;
margin-top: 26px;
}
.footer button {
width: 80px;
height: 40px;
}
.footer button:nth-child(1) {
margin-right: 10px;
cursor: pointer;
}
</style>
src\App.vue文件:
<template>
<div class="app">
<button @click="openDialog">退出按钮</button>
<BaseDialog :visible.sync="isShow"></BaseDialog>
</div>
</template>
<script>
import BaseDialog from './components/BaseDialog.vue'
export default {
data() {
return {
isShow: false,
}
},
methods: {
openDialog() {
this.isShow = true
},
},
components: {
BaseDialog,
},
}
</script>