写了一个简单的vue日历组件,存在问题:父组件传递数据作为初始数据,显示初始日期,然后用户在子组件上操作,修改时间参数,我是通过定义一个局部变量,并用prop的值初始化,用户在界面操作,会修改值,修改的是我定义的局部变量,但是并没有界面显示的问题并没有发生变化,这是为啥?
模板代码:
<div :class="$style.root" :disabled="disabled">
<div :class="$style.head">
<span :class="$style.prev">
<span :class="$style.item" @click.stop="addYear(-1)"><i :class="$style.icon" role="u-icon-angle-double-left"><<</i></span>
<span :class="$style.item" @click.stop="addMonth(-1)"><i :class="$style.icon" role="u-icon-angle-left"><</i></span>
</span>
<span>{{showDate | format('yyyy-MM')}}</span>
<span :class="$style.next">
<span :class="$style.item" @click.stop="addMonth(1)"><i :class="$style.icon" role="u-icon-angle-right">></i></span>
<span :class="$style.item" @click.stop="addYear(1)"><i :class="$style.icon" role="u-icon-angle-double-right">>></i></span>
</span>
</div>
<div :class="$style.content">
<div :class="$style.week"><span :class="$style.item">日</span><span :class="$style.item">一</span><span :class="$style.item">二</span><span :class="$style.item">三</span><span :class="$style.item">四</span><span :class="$style.item">五</span><span :class="$style.item">六</span></div>
<div :class="$style.day"><span v-for="day in days_" :class="$style.item" :sel="showDate.toDateString() === day.toDateString() ? 'sel' : ''" :disabled="!!isOutOfRange(day)" :role="showDate.getMonth() !== day.getMonth() ? 'muted': ''" @click.stop="select(day)">{{day | format('dd')}}</span></div>
</div>
</div>
js代码:
const MS_OF_DAY = 24 * 3600 * 1000;
/**
* @class Calendar
* @extend Component
* @param {object} options = 绑定属性
* @param {Date|string=TODAY} options.date <=> 当前选择的日期
* @param {Date|string=null} options.minDate => 最小日期,如果为空则不限制
* @param {Date|string=null} options.maxDate => 最大日期,如果为空则不限制
* @param {boolean=false} options.readonly => 是否只读
* @param {boolean=false} options.disabled => 是否禁用
* @param {boolean=true} options.visible => 是否显示
*/
const Calendar = Base.extend({
name: 'u-calendar',
props: {
date: {
type: [String, Number, Date],
default() {
return new Date();
},
},
readonly: Boolean,
disabled: [String, Boolean],
minDate: [String, Object],
maxDate: [String, Object],
},
data() {
return {
days_: [],
showDate: this.date,
};
},
// computed: {
// date_() {
// const date = this.date;
// if (typeof date === 'string')
// return new Date(date);
// else if (typeof date === 'number')
// return new Date(date);
// else if (typeof date === 'object')
// return date;
// },
// },
filters: {
format(value, type) {
console.log(value);
if (!value)
return '';
const fix = (str) => {
str = '' + (String(str) || '');
return str.length <= 1 ? '0' + str : str;
};
const maps = {
yyyy(date) { return date.getFullYear(); },
MM(date) { return fix(date.getMonth() + 1); },
dd(date) { return fix(date.getDate()); },
HH(date) { return fix(date.getHours()); },
mm(date) { return fix(date.getMinutes()); },
ss(date) { return fix(date.getSeconds()); },
};
const trunk = new RegExp(Object.keys(maps).join('|'), 'g');
type = type || 'yyyy-MM-dd HH:mm';
value = new Date(value);
return type.replace(trunk, (capture) => maps[capture] ? maps[capture](value) : '');
},
},
created() {
this.update();
},
methods: {
/**
* @method update() 日期改变后更新日历
* @private
* @return {void}
*/
update() {
this.days_ = [];
this.showDate = this.transformDate(this.showDate);
const date = this.showDate;
const month = date.getMonth();
const mfirst = new Date(date); mfirst.setDate(1);
const mfirstTime = +mfirst;
const nfirst = new Date(mfirst); nfirst.setMonth(month + 1); nfirst.setDate(1);
const nfirstTime = +nfirst;
const lastTime = nfirstTime + ((7 - nfirst.getDay()) % 7 - 1) * MS_OF_DAY;
let num = -mfirst.getDay();
let tmpTime, tmp;
do {
tmpTime = mfirstTime + (num++) * MS_OF_DAY;
tmp = new Date(tmpTime);
this.days_.push(tmp);
} while (tmpTime < lastTime);
},
/**
* @method addYear(year) 调整年份
* @public
* @param {number=0} year 加/减的年份
* @return {Date} date 计算后的日期
*/
addYear(year) {
if (this.readonly || this.disabled || !year)
return;
if (isNaN(year))
throw new TypeError(year + ' is not a number!');
const date = this.showDate;
const oldMonth = date.getMonth();
date.setFullYear(date.getFullYear() + year);
if (date.getMonth() !== oldMonth)
date.setDate(0);
// this.date_ = date;
},
/**
* @method addMonth(month) 调整月份
* @public
* @param {number=0} month 加/减的月份
* @return {Date} date 计算后的日期
*/
addMonth(month) {
debugger;
if (this.readonly || this.disabled || !month)
return;
if (isNaN(month))
throw new TypeError(month + ' is not a number!');
const date = this.showDate;
const correctMonth = date.getMonth() + month;
date.setMonth(correctMonth);
// 如果跳月,则置为上一个月
if ((date.getMonth() - correctMonth) % 12)
date.setDate(0);
// this.date_ = date;
},
/**
* @method select(date) 选择一个日期
* @public
* @param {Date=null} date 选择的日期
* @return {void}
*/
select(date) {
if (this.readonly || this.disabled || this.isOutOfRange(date))
return;
this.showDate = new Date(date);
/**
* @event select 选择某一个日期时触发
* @property {object} sender 事件发送对象
* @property {object} date 当前选择的日期
*/
this.$emit('select', {
sender: this,
date,
});
},
/**
* @method goToday() 回到今天
* @public
* @return {void}
*/
goToda() {
if (this.readonly || this.disabled)
return;
this.showDate = new Date((new Date / MS_OF_DAY >> 0) * MS_OF_DAY);
},
/**
* @method isOutOfRange(date) 是否超出规定的日期范围
* @public
* @param {Date} date 待测的日期
* @return {boolean|Date} date 如果没有超出日期范围,则返回false;如果超出日期范围,则返回范围边界的日期
*/
isOutOfRange(date) {
let minDate = this.minDate;
let maxDate = this.maxDate;
// 不要直接在$watch中改变`minDate`和`maxDate`的值,因为有时向外绑定时可能不希望改变它们。
minDate = minDate && new Date((minDate / MS_OF_DAY >> 0) * MS_OF_DAY);
maxDate = maxDate && new Date((maxDate / MS_OF_DAY >> 0) * MS_OF_DAY);
// minDate && date < minDate && minDate,先判断是否为空,再判断是否超出范围,如果超出则返回范围边界的日期
return (minDate && date < minDate && minDate) || (maxDate && date > maxDate && maxDate);
},
transformDate(date) {
if (typeof date === 'string')
return new Date(date);
else if (typeof date === 'number')
return new Date(date);
else if (typeof date === 'object')
return date;
},
},
});
const DateRangeError = function (minDate, maxDate) {
this.name = 'DateRangeError';
this.message = 'Wrong Date Range where `minDate` is ' + minDate + ' and `maxDate` is ' + maxDate + '!';
};
DateRangeError.prototype = Object.create(RangeError.prototype);
Calendar.DateRangeError = DateRangeError.prototype.constructor = DateRangeError;
export default Calendar;
这边有一个轻量,基于原生js开发的vue日历组件,你可以基本上能满足你大部分功能。https://github.com/zwhGithub/...