我有一个正在处理的 Vue 日历。单击一天时,我想在所选日期的星期下方打开一个全 Angular 框,显示当天的详细信息(想想谷歌图片布局)我知道如何在 Vue 中传递数据,但我该如何添加它本周行下的详细信息(组件, View ?)? (见我的 CodePen
<div class="calendar">
<div class="header z-depth-2">
<a @click="lastMonth" class="waves-effect waves-light btn"><i class="material-icons left">chevron_left</i>Last Month</a>
<p>{{month}} {{year}}</p>
<a @click="nextMonth" class="waves-effect waves-light btn"><i class="material-icons right">chevron_right</i>Next Month</a>
</div>
<ul class="dates month">
<li class="dow" v-for="dow in days">{{dow}}</li>
<li v-for="blank in firstDayOfMonth" class="day"></li>
<li v-for="date in daysInMonth" @click="openday(date)"
class="day" :class="{'today': date == initialDate && month == initialMonth && year == initialYear}">
<span>{{date}}</span>
</li>
</ul>
</div>
JS
new Vue({
el: '.calendar',
data: {
today: moment(),
dateContext: moment(),
days: ['S', 'M', 'T', 'W', 'T', 'F', 'S']
},
methods:{
nextMonth: function () {
var t = this;
t.dateContext = moment(t.dateContext).add(1, 'month');
},
lastMonth: function () {
var t = this;
t.dateContext = moment(t.dateContext).subtract(1, 'month');
}
},
computed: {
year: function () {
var t = this;
return t.dateContext.format('YYYY');
},
month: function () {
var t = this;
return t.dateContext.format('MMMM');
},
daysInMonth: function () {
var t = this;
return t.dateContext.daysInMonth();
},
currentDate: function () {
var t = this;
return t.dateContext.get('date');
},
firstDayOfMonth: function () {
var t = this;
var firstDay = moment(t.dateContext).subtract((t.currentDate - 1), 'days');
return firstDay.weekday();
},
//Previous Code Above
initialDate: function () {
var t = this;
return t.today.get('date');
},
initialMonth: function () {
var t = this;
return t.today.format('MMMM');
},
initialYear: function () {
var t = this;
return t.today.format('YYYY');
}
}
})
最佳答案
因为您没有行的概念(您只是自动换行),所以您无法真正插入一个占据一行的框。我在这里所做的是插入一个 absolute
ly 定位的 div,这样我就可以让它全宽,但它会覆盖下面的行,而不是将它们移开。
如果您将其修改为有数周,您可以在周之间插入一个详细信息框。
不过,基本的工作原理是,当您单击一个日期时为当前选定的日期设置一个数据项,然后清除该项目以关闭详细信息框(在此处单击详细信息框即可) . HTML 由 v-if
控制。
new Vue({
el: '.calendar',
data: {
today: moment(),
dateContext: moment(),
days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
selectedDate: null
},
methods: {
nextMonth: function() {
var t = this;
t.dateContext = moment(t.dateContext).add(1, 'month');
},
lastMonth: function() {
var t = this;
t.dateContext = moment(t.dateContext).subtract(1, 'month');
},
openday(date) {
this.selectedDate = date;
},
dismiss() {
this.selectedDate = null;
}
},
computed: {
year: function() {
var t = this;
return t.dateContext.format('YYYY');
},
month: function() {
var t = this;
return t.dateContext.format('MMMM');
},
daysInMonth: function() {
var t = this;
return t.dateContext.daysInMonth();
},
currentDate: function() {
var t = this;
return t.dateContext.get('date');
},
firstDayOfMonth: function() {
var t = this;
var firstDay = moment(t.dateContext).subtract((t.currentDate - 1), 'days');
return firstDay.weekday();
},
//Previous Code Above
initialDate: function() {
var t = this;
return t.today.get('date');
},
initialMonth: function() {
var t = this;
return t.today.format('MMMM');
},
initialYear: function() {
var t = this;
return t.today.format('YYYY');
}
}
})
*,
*:before,
*:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
body {
font-size: 1.5em;
font-weight: 100;
color: rgba(255, 255, 255, 1);
background: #222222;
}
.calendar {
transform: translate3d(0, 0, 0);
width: 100vw;
}
.header {
display: flex;
padding: 0 1em;
justify-content: space-between;
align-items: center;
width: 100%;
background-color: #333;
}
.fade-enter {
/*overflow: hidden;*/
opacity: 0;
}
.fade-enter-active {
animation: fadeIn 1s ease-out;
opacity: 1;
}
.month.in.next {
animation: moveFromTopFadeMonth .4s ease-out;
opacity: 1;
}
.month.out.next {
animation: moveToTopFadeMonth .4s ease-in;
opacity: 1;
}
.month.in.prev {
animation: moveFromBottomFadeMonth .4s ease-out;
opacity: 1;
}
.month.out.prev {
animation: moveToBottomFadeMonth .4s ease-in;
opacity: 1;
}
.dates {
display: flex;
flex-wrap: wrap;
}
.day {
width: 14%;
padding: 1em;
text-align: center;
cursor: pointer;
}
.dow {
width: 14%;
text-align: center;
padding: 1em;
color: teal;
font-weight: bold;
}
.detail-panel {
width: 100vw;
background-color: darkred;
color: white;
height: 10rem;
position: absolute;
left: 0;
}
.today {
color: teal;
font-weight: bold;
}
.day-name {
font-size: 1em;
text-transform: uppercase;
margin-bottom: 5px;
color: rgba(255, 255, 255, .5);
letter-spacing: .7px;
}
.day-number {
font-size: 24px;
letter-spacing: 1.5px;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/materialize/0.98.2/css/materialize.min.css" rel="stylesheet" />
<div class="calendar">
<div class="header z-depth-2">
<a @click="lastMonth" class="waves-effect waves-light btn"><i class="material-icons left">chevron_left</i>Last Month</a>
<p>{{month}} {{year}}</p>
<a @click="nextMonth" class="waves-effect waves-light btn"><i class="material-icons right">chevron_right</i>Next Month</a>
</div>
<ul class="dates month">
<li class="dow" v-for="dow in days">{{dow}}</li>
<li v-for="blank in firstDayOfMonth" class="day"></li>
<li v-for="date in daysInMonth" class="day" :class="{'today': date == initialDate && month == initialMonth && year == initialYear}">
<span @click="openday(date)">{{date}}</span>
<div class="detail-panel" v-if="selectedDate === date" @click="dismiss">Hi there I see you selected {{date}}</div>
</li>
</ul>
</div>
关于javascript - Vue动态添加详情内容行的方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44639209/