vue 日历组件 数据问题

写了一个简单的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;
阅读 7.8k
1 个回答
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题