如何缩减Vue 3中v-dialog的垂直占用空间?
Vue 3 v-dialog 垂直空间优化方案
我正在开发一个包含日期选择器和单选按钮(用于选择小时)的Vue 3 v-dialog组件,发现它在垂直方向占用了过多空间。我希望实现两个效果:
- 单选按钮的标签与按钮显示在同一行
- 减少分隔线的冗余空间
已经隐藏了选中日期,但还是没解决组件间的多余空间问题。

调用代码
<template> <v-container> <v-row> <v-col cols="12"> <date-dialog dialogTitle="Select the date" startDate="2018/01/01" endDate="2018/12/31" year="2018" :propDate="'2018-12-17T12:06:00'" :propHourFormated="'6'" @clicked="onDateClicked" /> </v-col> </v-row> </v-container> </template> <script> import DateDialog from './components/DateDialog.vue'; export default { methods: { onDateClicked(value){ console.log("Value is " + value) } }, components: { DateDialog, }, } </script> <style> /* 隐藏日期选择器头部 */ .v-date-picker-header { display: none } </style>
原对话框代码
<template> <div> <v-container class="fill-height"> <v-row> <v-col cols="12" sm="6" md="4" > <v-dialog ref="dialog" v-model="modal" :return-value.sync="date" persistent width="290px" > <template v-slot:activator="{ attrs }"> <v-text-field v-model="computedDateFormatted" :label="dialogTitle" prepend-icon="mdi-calendar" readonly @click="modal = true" v-bind="attrs" persistent-hint > </v-text-field> </template> <v-card width="360px"> <v-date-picker v-model="date" color="primary" :year="year" :min="startDate" :max="endDate" scrollable :title="dialogTitle" hide-actions > <!-- 隐藏选中日期 --> <template v-slot:header></template> </v-date-picker> <hr> <v-container> <v-radio-group v-model="computedHourFormatted" label="Time" inline @change="this.RBchanged"> <v-radio label="00" value="0"></v-radio> <v-radio label="06" value="6"></v-radio> <v-radio label="12" value="12"></v-radio> <v-radio label="18" value="18"></v-radio> </v-radio-group> </v-container> <hr> <v-card-actions> <v-btn text color="primary" @click="this.dialogOK" >OK </v-btn> <v-btn text color="primary" @click="this.dialogCancel" >Cancel </v-btn> </v-card-actions> </v-card> </v-dialog> </v-col> </v-row> </v-container> </div> </template> <script> export default { props: { dialogTitle:{ type:String}, startDate:{ type:String}, endDate:{ type:String}, year:{ type:String}, propHourFormated:{ type:String}, propDateFormated:{ type:String}, propDate:{ type:String}, }, methods:{ RBchanged(){ console.log('changed') console.log("VM "+this.hourFormatted); }, dialogOK(){ this.modal=false; console.log("OK " ); this.$emit('clicked',this.date); }, dialogCancel(){ console.log("Cancelled " ); this.date= new Date(this.propDate); this.dateFormatted= new Date(this.propDateFormatted); this.modal=false; this.$emit('clicked',this.date); }, formatDate (mydate) { if (!mydate) return null var hours="00",mins="00"; if(mydate.getHours() !== "" && mydate.getHours() !==0 ){ hours=mydate.getHours(); } return mydate.getDate()+"-"+ mydate.toLocaleString('en-GB', { month: 'long' })+" "+ mydate.getUTCFullYear() + " "+ hours+ ":" + mins ; }, formatHour(myhour) { return myhour.toString(); }, }, computed: { computedDateFormatted () { this.date.setHours(this.hourFormatted) return this.formatDate(this.date) }, computedHourFormatted:{ get() { console.log("XXXXget #" + this.date.getHours().toString()+"#"); return this.hourFormatted; }, set(value){ console.log("SET:Formating hours " + value); this.hourFormatted=value; } }, }, watch: { date (val) { this.dateFormatted = this.formatDate(this.date) }, }, data () { return { date: new Date(this.propDate), dateFormatted: new Date(this.propDate), hourFormatted: this.propHourFormated, modal: false, }}, }; </script>
优化后的解决方案
1. 调整单选按钮布局,实现标签与按钮同行
移除v-radio-group上的label属性,改用独立的v-label组件,并给容器减少内边距,确保单选按钮横向排列无换行:
<v-container class="pa-2"> <v-label class="mb-1">Time</v-label> <v-radio-group v-model="computedHourFormatted" inline @change="RBchanged"> <v-radio label="00" value="0"></v-radio> <v-radio label="06" value="6"></v-radio> <v-radio label="12" value="12"></v-radio> <v-radio label="18" value="18"></v-radio> </v-radio-group> </v-container>
2. 替换分隔线,减少垂直空间
用Vuetify的v-divider替换原生<hr>,并通过my-2类控制上下间距:
<v-divider class="my-2"></v-divider>
3. 移除不必要的高度设置
删除外层v-container的fill-height类,避免容器强制占满高度:
<v-container> <!-- 移除fill-height -->
4. 减少卡片内边距
给v-card添加pa-2类,缩小默认内边距:
<v-card width="360px" class="pa-2">
5. 优化日期选择器高度
添加自定义样式进一步压缩日期选择器的垂直空间:
<style scoped> .v-date-picker { min-height: auto; } </style>
完整优化后的对话框代码
<template> <div> <v-container> <v-row> <v-col cols="12" sm="6" md="4" > <v-dialog ref="dialog" v-model="modal" :return-value.sync="date" persistent width="290px" > <template v-slot:activator="{ attrs }"> <v-text-field v-model="computedDateFormatted" :label="dialogTitle" prepend-icon="mdi-calendar" readonly @click="modal = true" v-bind="attrs" persistent-hint > </v-text-field> </template> <v-card width="360px" class="pa-2"> <v-date-picker v-model="date" color="primary" :year="year" :min="startDate" :max="endDate" scrollable :title="dialogTitle" hide-actions > <template v-slot:header></template> </v-date-picker> <v-divider class="my-2"></v-divider> <v-container class="pa-2"> <v-label class="mb-1">Time</v-label> <v-radio-group v-model="computedHourFormatted" inline @change="RBchanged"> <v-radio label="00" value="0"></v-radio> <v-radio label="06" value="6"></v-radio> <v-radio label="12" value="12"></v-radio> <v-radio label="18" value="18"></v-radio> </v-radio-group> </v-container> <v-divider class="my-2"></v-divider> <v-card-actions> <v-btn text color="primary" @click="dialogOK" >OK </v-btn> <v-btn text color="primary" @click="dialogCancel" >Cancel </v-btn> </v-card-actions> </v-card> </v-dialog> </v-col> </v-row> </v-container> </div> </template> <script> export default { props: { dialogTitle:{ type:String}, startDate:{ type:String}, endDate:{ type:String}, year:{ type:String}, propHourFormated:{ type:String}, propDateFormated:{ type:String}, propDate:{ type:String}, }, methods:{ RBchanged(){ console.log('changed') console.log("VM "+this.hourFormatted); }, dialogOK(){ this.modal=false; console.log("OK " ); this.$emit('clicked',this.date); }, dialogCancel(){ console.log("Cancelled " ); this.date= new Date(this.propDate); this.dateFormatted= new Date(this.propDateFormatted); this.modal=false; this.$emit('clicked',this.date); }, formatDate (mydate) { if (!mydate) return null var hours="00",mins="00"; if(mydate.getHours() !== "" && mydate.getHours() !==0 ){ hours=mydate.getHours(); } return mydate.getDate()+"-"+ mydate.toLocaleString('en-GB', { month: 'long' })+" "+ mydate.getUTCFullYear() + " "+ hours+ ":" + mins ; }, formatHour(myhour) { return myhour.toString(); }, }, computed: { computedDateFormatted () { this.date.setHours(this.hourFormatted) return this.formatDate(this.date) }, computedHourFormatted:{ get() { console.log("XXXXget #" + this.date.getHours().toString()+"#"); return this.hourFormatted; }, set(value){ console.log("SET:Formating hours " + value); this.hourFormatted=value; } }, }, watch: { date (val) { this.dateFormatted = this.formatDate(this.date) }, }, data () { return { date: new Date(this.propDate), dateFormatted: new Date(this.propDate), hourFormatted: this.propHourFormated, modal: false, }}, }; </script> <style scoped> .v-date-picker { min-height: auto; } </style>
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

