Repository: Hzy0913/mpvue-calendar Branch: master Commit: a4024573605b Files: 35 Total size: 119.4 KB Directory structure: gitextract_lou6h3iy/ ├── .browserslistrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── README.zh.md ├── babel.config.js ├── example/ │ ├── App.vue │ └── main.js ├── package.json ├── public/ │ └── index.html ├── src/ │ ├── components/ │ │ ├── icon/ │ │ │ └── icon.css │ │ ├── swipe/ │ │ │ ├── declare.ts │ │ │ ├── index.vue │ │ │ ├── slide.vue │ │ │ ├── style.less │ │ │ └── utils.ts │ │ ├── timetable/ │ │ │ ├── computed.ts │ │ │ ├── controller.ts │ │ │ ├── declare.ts │ │ │ ├── index.vue │ │ │ └── style.less │ │ ├── tools/ │ │ │ ├── index.vue │ │ │ └── style.less │ │ └── utils/ │ │ └── index.ts │ ├── declare.ts │ ├── lunar.ts │ ├── mpvue-calendar.vue │ ├── shims-vue.d.ts │ └── style.less ├── tsconfig.json └── vue.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .browserslistrc ================================================ > 1% last 2 versions not dead ================================================ FILE: .editorconfig ================================================ root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false ================================================ FILE: .eslintignore ================================================ dist/* node_modules/* **/node_modules/* example/* src/lunar.ts ================================================ FILE: .eslintrc.js ================================================ module.exports = { root: true, env: { node: true, }, extends: [ 'plugin:vue/vue3-essential', '@vue/airbnb', '@vue/typescript/recommended', ], parserOptions: { ecmaVersion: 2020, }, rules: { 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'import/no-named-as-default': ['off'], 'comma-dangle': ['off', 'never'], 'spaced-comment': ['off', 'always'], 'func-names': ['off'], // 'indent': ['error', 2, {'SwitchCase': 1}], //暂时关闭 'indent': 0, //暂时关闭 'import/prefer-default-export': 0, //暂时关闭 'no-unused-expressions': ['off'], // 'max-len': ['warn', 100, 2, {'ignoreComments': true}], //暂时关闭 'max-len': 0, 'object-curly-spacing': 0, /* 暂时关闭 */ 'arrow-parens': 0, '@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/no-use-before-define': 0, 'array-callback-return': 0, 'class-methods-use-this': 0, 'default-case': 0, 'no-continue': 0, 'prefer-template': 0, 'consistent-return': 0, 'global-require': 0, 'import/extensions': 0, 'import/no-extraneous-dependencies': 0, 'import/no-unresolved': 0, 'no-bitwise': 0, 'no-case-declarations': 0, 'no-confusing-arrow': 0, 'no-mixed-operators': 0, 'no-param-reassign': 0, 'no-plusplus': 0, 'no-return-assign': 0, 'no-underscore-dangle': 0, 'prefer-object-spread': 0, 'no-unused-vars': 0, 'no-useless-concat': 0, 'object-curly-newline': 0, 'no-restricted-globals': 0, 'no-else-return': 0, 'space-infix-ops': 0, 'prefer-destructuring': ['error', { 'VariableDeclarator': { 'array': false, 'object': false }, 'AssignmentExpression': { 'array': false, 'object': false } }, { 'enforceForRenamedProperties': true }] }, }; ================================================ FILE: .gitignore ================================================ .DS_Store node_modules/ dist/ lib/ demo/ npm-debug.log yarn-error.log # Editor directories and files .idea .vscode *.suo *.ntvs* *.njsproj *.sln ================================================ FILE: .npmignore ================================================ node_modules build config example demo dist/demo.html dist/mpvue-calendar.umd.js static public src lib .babelrc .browserslistrc .editorconfig .eslintignore .eslintrc.js babel.config.js .postcssrc.js tsconfig.json vue.config.js yarn.lock .gitignore index.html package-lock.json mpvue-calendar.common.js ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2018-present, ZhaoYun (Ricky) Han Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================

mpvue-calendar logo

Downloads Version License

mpvue-calendar

> A feature-rich calendar component, support multiple modes and gesture sliding. For vue 3.0+

mpvue-calendar preview

- #### [Preview](http://preview.binlive.cn/mpvue-calendar#/ "Preview") - #### [Demo](https://github.com/Hzy0913/mpvue-calendar/blob/master/example/App.vue "Demo") - #### [中文文档](https://github.com/Hzy0913/mpvue-calendar/blob/master/README.zh.md "Docs") ## 💻 Install mpvue-calendar only support **vue@3.0+** ``` npm i mpvue-calendar -S ``` ## 🔨 Usage ```javascript import { ref } from 'vue' import Calendar from 'mpvue-calendar' export default { components: { Calendar, }, setup() { const remarks = ref({'2021-1-13': 'some tings'}) return { remarks, } } } ``` ## ⚙️ API | name | type | default | description | | ------------ | ------------ | ------------ | ------------ | | selectMode | String | 'select' | For the selection mode of calendar component, can be used by **'select'**, **'multi'**,**'range'**, **'multiRange'** mode | | mode | String | 'month'| Configure calendar display mode, the modes has **'month'**, **'week'**,**'monthRange'** | | selectDate | String / String[] / {start: String; end: String} / {start: String; end: String} [] | | In different selection modes, there are use different types. `String` type for **select** mode, `String[]` type for **multi** mode, `{start: String; end: String}` type for **range** mode, and `{start: String; end: String} []` type for **multiRange** mode. | | monthRange | String[] | | If you use **monthRange mode**, you need to set the content of the month to be displayed. for example `[2021-1, 2021-2, 2021-6, 2021-9]` | | remarks | Object | | Create remark for a day, key is date string, and value is remark content. for example `{ '2021-1-13': 'some things' }` | | tileContent | Object | | Create tile content for a day, key is date string, and value is `object`, object have **className** and **content**. for example `{ '2021-1-5': { className: 'tip-class', content: 'some tip' } } ` | | holidays | Object | | Custom holiday information, for example `{'2021-1-1': 'New Year'}` | | completion | Boolean | false | Complete the calendar table with 6 lines | | useSwipe | Boolean | true | The mobile terminal supports gesture sliding to switch calendar | | arrowLeft | String | | Left arrow image url of toolbar | | arrowRight | String | | Right arrow image url of toolbar | | monFirst | Boolean | false | The first day of the week begins on Monday | | backgroundText | Boolean | false | Displays the background text of the current month calendar | | language | String | | use **'en'** or **'cn'** language | | format | (year, month) => [String, String] | | Format the date display at the header. you need return a array, the contents of the array are year and month | | weeks | String[] | | Weekly display content of custom header, for example ['S', 'M', 'T', 'W', 'T', 'F', 'S'] | | begin | String | | Set the available date of the start, and the date before it will be disabled, for example ` '2021-1-5' ` | | end | String | | Set the available date of the end, and the date after it will be disabled, for example `'2021-2-5'` | | disabled | String[] | | Disable certain dates , for example `['2021-1-9', '2021-2-5']` | #### Chinese lunar If you need show chinese lunar, you need import lunar module. ```javascript import lunar from 'mpvue-calendar/dist/lunar' export default { ..., setup() { return { lunar, } } } ``` ## ⚙️ methods | name | type | description | | ------------ | ------------ | ------------ | | onSelect | (selectDate) => void | This function is triggered when the date is selected | | onMonthChange | (year, month, day) => void | The callback is triggered when the month is change | | next | (year, month) => void | Callback this method when triggered next month | | prev | (year, month) => void | Callback this method when triggered prev month | | setToday | ref method | Back today, you need to pass the ref parameter to call the internal method | ================================================ FILE: README.zh.md ================================================

mpvue-calendar logo

Downloads Version License

mpvue-calendar

> 一款功能丰富的日历组件,支持多种模式和手势滑动。 基于vue 3.0+

mpvue-calendar preview

- #### [预览](http://preview.binlive.cn/mpvue-calendar#/ "Preview") - #### [例子](https://github.com/Hzy0913/mpvue-calendar/blob/master/example/App.vue "Demo") ## 💻 安装 mpvue-calendar 只支持 **vue@3.0+** ``` npm i mpvue-calendar -S ``` ## 🔨 使用 ```javascript import { ref } from 'vue' import Calendar from 'mpvue-calendar' export default { components: { Calendar, }, setup() { const remarks = ref({'2021-1-13': 'some tings'}) return { remarks, } } } ``` ## ⚙️ API | name | type | default | description | | ------------ | ------------ | ------------ | ------------ | | selectMode | String | 'select' | 对于日历组件的选择模式,可以通过传入 **'select'**, **'multi'**, **'range'**, **'multiRange'** 参数使用 | | mode | String | 'month'| 配置日历显示模式,可以通过传入 **'month'**, **'week'**,**'monthRange'** 使用该功能 | | selectDate | String / String[] / {start: String; end: String} / {start: String; end: String} [] | |在不同的选择模式下,需要对应不同的数据类型。 `String` 类型对应在 'select' 模式下,`String[]` 数组类型对应在 'multi' 模式下,`{start: String; end: String}` 类型对应在 'range' 模式下,`{start: String; end: String}[]` 数组类型对应在 'multiRange' 模式下 | | monthRange | String[] | |如果使用monthRange模式,则需要设置要显示的月份的内容。 例如[2021-1、2021-2、2021-3] | | remarks | Object | | 创建某一天的备注,key是日期字符串,value是备注内容。 例如{'2021-1-13':'一些备注'} | | tileContent | Object | | 创建某一天的贴片内容,key是日期字符串,value是object类型,`object`有**className**和**content**字段。例如{2021-1-5':{className:'tip class',content:'some tip'} | | holidays | Object | | 自定义节假日信息,例如{'2021-1 ':'New Year'} | | completion | Boolean | false | 用6行补全日历表格 | | useSwipe | Boolean | true | 启用移动端支持手势滑动切换日历 | | arrowLeft | String | | 工具栏左侧箭头图片 | | arrowRight | String | | 工具栏右侧箭头图片 | | monFirst | Boolean | false | 一周的第一天从星期一开始 | | backgroundText | Boolean | false | 显示当前月份的背景文本 | | language | String | | 使用 **'en'** 或 **'cn'** 语言 | | format | (year, month) => [String, String] | | 格式化头部的日期显示。 您需要返回一个数组,该数组的内容是对应的年和月 | | weeks | String[] | | 自定义标题的每周显示内容,例如['星期一', '星期二', '星期三', '星期四', ...] | | begin | String | | 设置开始的可用日期,在此之前的日期将被禁用,例如 '2021-1-5' | | end | String | | 设置结束的可用日期,在此之后的日期将被禁用,例如 '2021-2-5' | | disabled | String[] | | 禁用某些日期,例如 `['2021-1-9', '2021-2-5']`| #### 农历 如果你需要展示中国农历,你需要导入农历模块。 ```javascript import lunar from 'mpvue-calendar/dist/lunar' export default { ..., setup() { return { lunar, } } } ``` ## ⚙️ methods | name | type | description | | ------------ | ------------ | ------------ | | onSelect | (selectDate) => void | 选择日期时触发此函数 | | onMonthChange | (year, month, day) => void | 当月份发生变化时会触发该回调 | | next | (year, month) => void | 进入下月时触发该回调方法| | prev | (year, month) => void | 进入上月时触发该回调方法 | | setToday | ref method | 回到今天,您需要传递ref参数来调用组件内部方法 | ================================================ FILE: babel.config.js ================================================ module.exports = { presets: [ '@vue/cli-plugin-babel/preset', ], }; ================================================ FILE: example/App.vue ================================================ ================================================ FILE: example/main.js ================================================ import { createApp } from 'vue'; import App from './App.vue' createApp(App).mount('#app') ================================================ FILE: package.json ================================================ { "name": "mpvue-calendar", "version": "3.0.1", "description": "vue calendar mpvue-calendar vue-calendar", "main": "dist/mpvue-calendar.umd.min.js", "scripts": { "start": "vue-cli-service serve", "build": "npm run build:calendar && npm run build:lunar && npm run remove", "build:calendar": "vue-cli-service build --target lib --name mpvue-calendar './src/mpvue-calendar.vue'", "build:lunar": "vue-cli-service build --target lib --name lunar --dest lib './src/lunar.ts'", "remove": "cp ./lib/lunar.umd.min.js ./dist/lunar.js", "demo": "vue-cli-service build --dest demo './example/main.js'", "lint": "vue-cli-service lint", "publish": "npm publish --registry https://registry.npmjs.org" }, "repository": { "type": "git", "url": "git+https://github.com/Hzy0913/mpvue-calendar.git" }, "keywords": [ "vue", "calendar", "mpvue-calendar", "calendar component", "日历组件" ], "author": "hzy", "license": "MIT", "bugs": { "url": "https://github.com/Hzy0913/mpvue-calendar/issues" }, "homepage": "https://github.com/Hzy0913/mpvue-calendar#readme", "dependencies": { "core-js": "^3.6.5", "vue": "^3.0.0" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^2.33.0", "@typescript-eslint/parser": "^2.33.0", "@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-plugin-typescript": "~4.5.0", "@vue/cli-service": "~4.5.0", "@vue/compiler-sfc": "^3.0.0", "@vue/eslint-config-airbnb": "^5.0.2", "@vue/eslint-config-typescript": "^5.0.2", "eslint": "^6.7.2", "eslint-plugin-import": "^2.20.2", "eslint-plugin-vue": "^7.0.0-0", "less": "^3.12.2", "less-loader": "^7.1.0", "typescript": "~3.9.3" } } ================================================ FILE: public/index.html ================================================ mpvue-calendar
================================================ FILE: src/components/icon/icon.css ================================================ @font-face { font-family: "calendar-iconfont"; src: url('data:font/truetype;charset=utf-8;base64,d09GRgABAAAAAASEAAsAAAAABuwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY7d0f0Y21hcAAAAYAAAABTAAABhmJUzs9nbHlmAAAB1AAAALcAAADIzC0F5mhlYWQAAAKMAAAALwAAADYS7IZUaGhlYQAAArwAAAAcAAAAJAfeA4RobXR4AAAC2AAAAAwAAAAMDAAAAGxvY2EAAALkAAAACAAAAAgANgBkbWF4cAAAAuwAAAAfAAAAIAEOACluYW1lAAADDAAAAUUAAAJtPlT+fXBvc3QAAARUAAAALQAAAEOUPjuMeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeMj5jYm7438AQw9zA0AAUZgTJAQDdSgvleJztkMERgDAIBPdIzMOxEB8W5MvuTRsRMHbhzSwHR/IBWIDiHE4FXYjQ6akyL6yZ13zT3IXd6jYGfO6S75q7xT81fm1Z9zlZXOsl+j5BD35IDU4AeJwVzUEOwUAYBeD/mfxTEso/mkEJoYluqgtajUjYsHEOSytncROJK/QErjNMd+8lL+8jEP3eqq8uNCPiokK1L4t1ihzVCSPMEekAep3mQCh4tpVm95JWz2QGj3iyiN3LZMJBODU49IMuDxk32YifuI89X4+xqwcsHUtEjfVVWt1p5MvWNs9RY4RowNLrJ7Tq8ZKNN7wmvMp8jBc7PDpW3RPfPrISV5ss4QEO9pxcdrix/gMMIyHOAHicY2BkYGAAYmNBZtV4fpuvDNwsDCBw/dlCBQT9fzMLA3MKkMvBwAQSBQDyNAlAAHicY2BkYGBu+N/AEMPCAAJAkpEBFTADAEcJAmwEAAAABAAAAAQAAAAAAAAAADYAZHicY2BkYGBgZpBlANEMDExAzAWEDAz/wXwGAAuHATgAeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicY2BigAAuBuyAmZGJkZmRhYEnKzMxryS/tDgjMS+dC8qpzC9lYAAAiPIJlAAAAA=='); } .iconfont { font-family:"calendar-iconfont" !important; font-size:16px; font-style:normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .icon-arrow-right:before { content: "\e602"; } .icon-arrow-left:before { content: "\e501"; } ================================================ FILE: src/components/swipe/declare.ts ================================================ interface SwipeInterface { initialSlide?: number; auto?: number; speed: number; timetableHeight?: number; loop?: boolean; useSwipe?: boolean; } interface SlideInterface { className?: string; useSwipe?: boolean; } type startType = { x: number; y: number; time: number; } type deltaType = { x: number; y: number; } export { SwipeInterface, SlideInterface, startType, deltaType, } ================================================ FILE: src/components/swipe/index.vue ================================================ ================================================ FILE: src/components/swipe/slide.vue ================================================ ================================================ FILE: src/components/swipe/style.less ================================================ .vc-calendar-swipe { overflow: hidden; width: 100%; .swipe-wrap{ width: 100%; overflow: hidden; position: relative; .swipe-slide{ width: 100%; height: 100%; float: left; position: relative; } } } ================================================ FILE: src/components/swipe/utils.ts ================================================ export function hasTransitions() { const element = document.createElement('div'); const property = ['transitionProperty', 'WebkitTransition', 'MozTransition', 'OTransition', 'msTransition']; for (let value of property) {// eslint-disable-line if ((element.style as any)[value] !== undefined) return true; } return false; } ================================================ FILE: src/components/timetable/computed.ts ================================================ import { computedNextMonth, computedPrevMonth, getToday, computedNextYear } from '../utils'; function date2ymd(date: string): number[] { const [y, m, d] = date.split('-'); return [Number(y), Number(m), Number(d)]; } function date2timeStamp(date: string): number { const [y, m, d] = date2ymd(date); return +new Date(y, m - 1, d); } function getLunarInfo(y: string, m: string, d: string, lunar: any) { const date = `${y}-${m}-${d}`; if (!lunar) { return { date }; } const lunarInfo = lunar.solar2lunar(y, m, d) as any; const { Term, lMonth, lDay, lYear } = lunarInfo || {}; const { lunarHoliday, gregorianHoliday } = lunar || {}; const lunarValue = lunarInfo.IDayCn; const yearEve = lMonth === 12 && lDay === lunar.monthDays(lYear, 12) ? '除夕' : undefined; const lunarInfoObj = { date, lunar: Term || lunarValue, gregorianHoliday: gregorianHoliday?.[`${m}-${d}`], lunarHoliday: lunarHoliday?.[`${lMonth}-${lDay}`] || yearEve, isTerm: !!yearEve || lunarInfo.isTerm }; return lunarInfoObj; } const setRemark = (function () { let remarksInfo: any = {}; return function () { return { update(remarks: any = {}) { remarksInfo = remarks; }, getRemark(date: string) { if (remarksInfo) { return { remark: remarksInfo[date] }; } } }; }; }()); function computedPrevDay(year: string, month: string, day: string | number): string { if ((Number(day) - 1) === 0) { const prevMonth = computedPrevMonth(month); if (prevMonth === 12) { //prev year const prevYear = Number(year) - 1; const prevDay = new Date(prevYear, prevMonth - 2, 0).getDate(); return `${prevYear}-${prevMonth}-${prevDay}`; } else { //current year and prev month const prevDay = new Date(Number(year), prevMonth, 0).getDate(); return `${year}-${prevMonth}-${prevDay}`; } } else { return `${year}-${month}-${Number(day) - 1}`; } } function computedNextDay(year: string, month: string, day: string): string { const lastDateOfCurrentMonth = new Date(Number(year), Number(month), 0).getDate(); //last date of current month if ((Number(day) + 1) > lastDateOfCurrentMonth) { const nextMonth = computedNextMonth(month); if (nextMonth === 1) { //next year const nextYear = computedNextYear(year, month); const nextDay = new Date(nextYear, 0, 1).getDate(); return `${nextYear}-1-${nextDay}`; } else { //current year and next month const nextDay = new Date(Number(year), nextMonth - 1, 1).getDate(); return `${year}-${nextMonth}-${nextDay}`; } } else { return `${year}-${month}-${Number(day) + 1}`; } } type rangeOptionType = { date: string; isWeekMode: boolean; rangeDate: [string, string]; getLunarInfo: (year: number, month: number, day: number) => any; getEvents: (year: number, month: number, day: number) => any; } function isCurrentMonthToday(date: string) { const todayString = getToday(); return todayString === date; } function rangeOption({selectDate, date}: any) { const { start, end } = selectDate; if (start === date) { const notCompleteClassName = end ? '' : ' selected-range-not-complete'; return 'vc-day-selected selected-range-start' + notCompleteClassName; } if (end === date) { return 'vc-day-selected selected-range-end'; } if (start && end && date) { const startTimeStamp: number = date2timeStamp(start); const endTimeStamp: number = date2timeStamp(end); const currentTimeStamp: number = date2timeStamp(date); if (startTimeStamp < currentTimeStamp && currentTimeStamp < endTimeStamp) { return 'vc-day-selected selected-range-includes'; } } } function multiRangeOption({selectDate = [], date}: any) { let className; selectDate.some((selectItem: any) => { const { start, end } = selectItem; if (start === date) { const notCompleteClassName = end ? '' : ' selected-range-not-complete'; className = 'vc-day-selected selected-range-start' + notCompleteClassName; return true; } if (end === date) { className = 'vc-day-selected selected-range-end'; return true; } if (start && end && date) { const startTimeStamp: number = date2timeStamp(start); const endTimeStamp: number = date2timeStamp(end); const currentTimeStamp: number = date2timeStamp(date); if (startTimeStamp < currentTimeStamp && currentTimeStamp < endTimeStamp) { className = 'vc-day-selected selected-range-includes'; return true; } } }); return className; } function multiOption({selectDate, date}: any) { return selectDate.includes(date) ? 'vc-day-selected' : undefined; } function selectOption({date, selectDate}: any) { return selectDate === date ? 'vc-day-selected' : undefined; } type selectOptionType = { date: string; playload: any; isWeekMode: boolean; weekSwitch: boolean; selectDate: string; getLunarInfo: (year: number, month: number, day: number) => any; getEvents: (year: number, month: number, day: number) => any; } const disabledDate = (function () { let disabledDates: any = {}; return function () { return { update(disabled: any[] = []) { disabledDates = disabled.reduce((previousValue, currentValue) => { previousValue[currentValue] = true; return previousValue; }, {}); return disabledDate; }, isDisabled(date: string) { return !!disabledDates[date]; } }; }; }()); const setTileContent = (function () { let tileContentInfo: any = {}; return function () { return { update(tileContent: any) { tileContentInfo = tileContent || []; }, getTileContent(date: string) { return { tileContent: (tileContentInfo || {})[date] }; } }; }; }()); export { getToday, rangeOption, multiOption, multiRangeOption, selectOption, disabledDate, setRemark, setTileContent, getLunarInfo, computedPrevMonth, computedNextYear, isCurrentMonthToday, date2timeStamp, computedNextDay, computedPrevDay, date2ymd, }; ================================================ FILE: src/components/timetable/controller.ts ================================================ import { date2timeStamp } from './computed'; function singleSelect(selectDate: string, date: string) { return date; } function multiSelect(selectDate: string[] = [], date: string) { const index = selectDate.indexOf(date); if (~index) { selectDate.splice(index, 1); return selectDate; } selectDate.push(date); return selectDate; } function rangeSelect(selectDate: { start?: string; end?: string }, date: string) { const { start, end } = selectDate; if (start && end) { return { start: date, end: '' }; } if (start) { if (start === date) { return {}; } if (date2timeStamp(start) > date2timeStamp(date)) { return { start: date, end: start }; } return { start, end: date, }; } return { start: date, end, }; } function multiRange(selectDates: { start?: string; end?: string }[], date: string) { const selects = [...selectDates]; let deleteIndex; if (!selects.length) { selects.push({start: date}); return selects; } const searchResult = selects.some((selectItem: any, index: number) => { const { start, end } = selectItem; if (start && end) { if (date2timeStamp(start) < date2timeStamp(date) && date2timeStamp(date) < date2timeStamp(end)) { return true; } if (start === date || end === date) { deleteIndex = index; return true; } } else if (start) { const selectItemDate: { start: string; end: string } = { start: '', end: '' }; if (start === date) { deleteIndex = index; return true; } if (date2timeStamp(start) > date2timeStamp(date)) { selectItemDate.start = date; selectItemDate.end = start; } else { selectItemDate.start = start; selectItemDate.end = date; } let isIncludeOtherRange; if (selects.length > 1) { isIncludeOtherRange = selects.some((item: any, i: number) => { if (i === selects.length - 1) return; const { start: prevItemDate } = item; if (date2timeStamp(selectItemDate.start) < date2timeStamp(prevItemDate) && date2timeStamp(prevItemDate) < date2timeStamp(selectItemDate.end)) { return true; } }); } if (!isIncludeOtherRange) { selectItem.start = selectItemDate.start; selectItem.end = selectItemDate.end; } return true; } }); if (typeof deleteIndex === 'number') { selects.splice(deleteIndex, 1); } else if (!searchResult) { selects.push({start: date}); } return selects; } export { singleSelect, multiSelect, rangeSelect, multiRange, }; ================================================ FILE: src/components/timetable/declare.ts ================================================ interface TimeTableInterface { monFirst?: boolean; format?: (year: string | number, month: string | number) => any[]; weeks: string[]; tableMode: 'month' | 'week' | 'monthRange'; lunar?: any; useSwipe: boolean; tableIndex?: number; timestamp?: number; year?: string | number month?: string | number day?: string | number begin?: string; end?: string; completion: boolean; holidays?: {[key: string]: string}; tileContent: {className?: string, tileContent?: string}[]; remarks: {[key: string]: string}; selectMode: 'select' | 'multi' | 'range' | 'multiRange'; selectDate?: string | string[] | {start?: string, end?: string} | {start?: string, end?: string}[] disabled: string[]; }; interface SwipeInterface { initialSlide?: number; auto?: number; speed: number; loop?: boolean; } interface SlideInterface { className?: string; } type startType = { x: number; y: number; time: number; } type deltaType = { x: number; y: number; } export { SwipeInterface, SlideInterface, startType, deltaType, TimeTableInterface, } ================================================ FILE: src/components/timetable/index.vue ================================================ ================================================ FILE: src/components/timetable/style.less ================================================ .vc-calendar-timetable{ background: #fff; padding-bottom: 10px; .vc-calendar-timetable-wrap{ .vc-calendar-body{ .vc-calendar-row{ overflow: hidden; .vc-calendar-day{ -webkit-tap-highlight-color:transparent; width: 14.285714285714285%; position: relative; float: left; color: #7C86A2; cursor: pointer; padding: 1%; box-sizing: border-box; &:before{ content: ''; padding-top: 100%; display: block; position: relative; z-index: 1; } &.selected-range-includes{ &:after{ content: ''; display: block; position: absolute; width: 100%; height: 86%; background: #E8F4FF ; top: 7%; z-index: 1; } } &.selected-range-start{ &:after{ content: ''; display: block; position: absolute; width: 100%; height: 86%; background: #E8F4FF ; top: 7%; z-index: 0; left: 50%; } &.selected-range-not-complete, &.vc-calendar-row-last{ &:after{ content: none; } } } .vc-calendar-day-container{ position: absolute; left: 0; right: 0; top: 0; bottom: 0; padding: 1%; z-index: 3; } &.vc-day-selected{ &:before{ background: #60CDFF; overflow: hidden; border-radius: 4%; } .vc-calendar-date{ color: #fff; } &.selected-range-includes{ .vc-calendar-date{ color: #7C86A2; } } } &.vc-calendar-dayoff{ .vc-calendar-date { color: #FF6260; } } .vc-calendar-date{ width: 100%; display: block; position: absolute; text-align: center; top: 50%; transform: translateY(-50%); } .vc-calendar-almanac{ display: block; position: absolute; bottom: 8%; font-size: 12px; width: 100%; text-align: center; &.vc-calendar-holiday, &.vc-calendar-isTerm{ color: #FF6260; } } .vc-calendar-slot-element{ font-size: 12px; position: absolute; top: 0; } .vc-calendar-text{ font-size: 12px; position: absolute; bottom: 0; width: 100%; display: block; text-align: center; } &.vc-calendar-disabled{ pointer-events: none; .vc-calendar-day-container{ .vc-calendar-date, .vc-calendar-almanac{ color: #ccc; } } &.vc-calendar-prev-month-day, &.vc-calendar-next-month-day{ pointer-events: inherit; } } } } .vc-calendar-rang-head{ .vc-calendar-rang-week-box{ width: 100%; display: flex; align-items: center; height: 30px; margin-top: 10px; span{ flex: 1; text-align: center; color: #6B7897; } } .vc-calendar-rang-year-month-box{ background: #fafafa; padding: 10px 0; color: #646464; text-align: center; font-size: 16px; } } .vc-calendar-content{ position: relative; .vc-calendar-month-background-text{ position: absolute; top: 50%; text-align: center; width: 100%; font-size: 200px; transform: translateY(-50%); font-weight: 900; color: #f4f5f9; } } } } } ================================================ FILE: src/components/tools/index.vue ================================================ ================================================ FILE: src/components/tools/style.less ================================================ .vc-calendar-tools { margin: auto; width: 100%; background: #fff; user-select: none; position: relative; .vc-calendar-tools-container { height: 40px; font-size: 20px; line-height: 40px; color: #5e7a88; -webkit-box-shadow: 0 4px 8px rgba(25, 47, 89, .1); box-shadow: 0 4px 8px rgba(25, 47, 89, .1); border-top: 1px solid hsla(0, 0%, 78.4%, .1); z-index: 5; position: relative; } .vc-calendar-week-head{ .vc-calendar-week-head-container{ width: 100%; display: flex; align-items: center; height: 30px; padding-top: 10px; .vc-calendar-week-item{ flex: 1; text-align: center; color: #6B7897; } } } .vc-calendar-prev, .vc-calendar-next { cursor: pointer; img { width: 34px; height: 34px; } } .vc-calendar-prev { width: 14.28571429%; float: left; text-align: center; } .vc-calendar-next { width: 14.28571429%; float: right; text-align: center; } .vc-calendar-info { font-size: 16px; width: 50%; margin: 0 auto; height: 100%; display: flex; justify-content: center; align-items: center; cursor: pointer; .vc-calendar-month { color: #5e7a88; } .vc-calendar-year { color: #5e7a88; } } .vc-calendar-picker{ color: #5e7a88; opacity: 0; position: absolute; top: 0px; background: #fff; width: 100%; height: 100%; z-index: 4; display: none; box-sizing: border-box; >div{ height: 50%; } &.vc-picker-show{ animation-name: pickerShow; animation-duration: .3s; animation-timing-function: cubic-bezier(0.075, 0.82, 0.165, 1); animation-fill-mode: both; display: block; @keyframes pickerShow { from { top: -30%; opacity: 0; } to { top: 0; opacity: 1; } } } .vc-calendar-months{ display: flex; flex-wrap: wrap; padding: 10px 5px; position: relative; box-sizing: border-box; .piecker-month-active{ i{ background: #60CDFF; color: #fff; border-radius: 5px; box-shadow: 2px 2px 2px rgba(0, 81, 118, .1); } } &:after { content: ''; display: block; width: 94%; height: 1px; background-color: #eee; position: absolute; bottom: 0; left: 3%; } span{ flex-basis: 25%; text-align: center; font-size: 16px; position: relative; i{ position: absolute; font-style: normal; text-align: center; word-break: keep-all; left: 50%; top: 50%; transform: translate3d(-50%, -50%, 0); padding: 5% 22%; cursor: pointer; } } } .vc-calendar-years{ display: flex; flex-wrap: wrap; padding: 10px 5px; box-sizing: border-box; .piecker-year-active{ i{ background: #60CDFF; color: #fff; border-radius: 5px; box-shadow: 2px 2px 2px rgba(0, 81, 118, .1); } } span{ flex-basis: 20%; text-align: center; margin-bottom: 10px; font-size: 16px; position: relative; i{ position: absolute; font-style: normal; text-align: center; word-break: keep-all; left: 50%; top: 50%; transform: translate3d(-50%, -50%, 0); padding: 5% 22%; cursor: pointer; } } } } } ================================================ FILE: src/components/utils/index.ts ================================================ function noop() {} // eslint-disable-line function computedNextYear(year: string | number, month: string | number): number { if ((Number(month) + 1) > 12) { return Number(year) + 1; } return Number(year); } function computedPrevYear(year: string | number, month: string | number): number { if ((Number(month) - 1 - 1) < 0) { return Number(year) - 1; } return +year; } function date2ymd(date: string): number[] { const [y, m, d] = date.split('-'); return [Number(y), Number(m), Number(d)]; } function offloadFn(fn: any) { setTimeout(fn || noop, 0); } function language(): string { return (navigator.language || (navigator as any).browserLanguage).toLowerCase(); } function isZh(languageValue?: string) { if (languageValue) { return languageValue === 'cn'; } return language() === 'zh-cn'; } const enWeeks = ['Sun', 'Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat']; const zhWeeks = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; const enMonths = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec']; const zhMonths = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']; function getWeeks(languageParam: string) { return isZh(languageParam) ? zhWeeks : enWeeks; } function getMonths(languageParam: string | undefined) { return isZh(languageParam) ? zhMonths : enMonths; } function computedNextMonth(month: string | number) { if ((Number(month) + 1) > 12) { return 1; } else { return Number(month) + 1; } } function computedPrevMonth(month: string | number): number { if ((Number(month) - 1) === 0) { return 12; } else { return Number(month) - 1; } } function getDateByCount(date: string, count: number): string { const [y, m, d] = date2ymd(date); const timestamp = +new Date(y, m - 1, d); const dateObj = new Date(timestamp + count * 86400000); const year = dateObj.getFullYear(); const month = dateObj.getMonth(); const day = dateObj.getDate(); return `${year}-${month + 1}-${day}`; } function getPrevDate(year: string | number, month: string | number, day?: string | number): any[] { if (day) { return date2ymd(getDateByCount(`${year}-${month}-${day}`, -7)); } return [computedPrevYear(year, month), computedPrevMonth(month)]; } function getNextDate(year: string | number, month: string | number, day?: string | number): any[] { if (day) { return date2ymd(getDateByCount(`${year}-${month}-${day}`, 7)); } return [computedNextYear(year, month), computedNextMonth(month)]; } function delay(time?: number) { return new Promise(resolve => setTimeout(() => resolve(), time || 0)); } function getToday(needArray?: boolean) { const now = new Date(); const year = now.getFullYear(); const month = now.getMonth() + 1; const day = now.getDate(); if (needArray) { return [year, month, day]; } return [year, month, day].join('-'); } function getSomeNextMonths(year: string | number, month: string | number, count: number) { let currentYear = year; let currentMonth = month; return Array.from({length: count}).map((v, index) => { if (!index) { return `${currentYear}-${currentMonth}`; } const [y, m] = getNextDate(currentYear, currentMonth); currentYear = y; currentMonth = m; return `${currentYear}-${currentMonth}`; }); } export { noop, isZh, delay, language, offloadFn, zhWeeks, enWeeks, date2ymd, getDateByCount, computedNextMonth, computedPrevMonth, getPrevDate, getNextDate, getToday, getWeeks, getMonths, computedPrevYear, computedNextYear, getSomeNextMonths, }; ================================================ FILE: src/declare.ts ================================================ interface CalendarInterface { monFirst?: boolean; completion?: boolean; useSwipe?: boolean; weeks?: string[]; className?: string; language?: string; holidays: {[key: string]: string}; tileContent: {[key: string]: any }; remarks: {[key: string]: any }; disabled: string[]; begin: string[]; end: string[]; monthRange: string[]; mode: 'monthRange' | 'week' | 'month'; selectMode: 'select' | 'multi' | 'range' | 'multiRange'; lunar: any; selectDate: any; format: (year: string, month: string) => string[]; } export { CalendarInterface, } ================================================ FILE: src/lunar.ts ================================================ // @ts-nocheck /** * @1900-2100区间内的公历、农历互转 * @charset UTF-8 * @Author Jea杨(JJonline@JJonline.Cn) * @Time 2014-7-21 * @Time 2016-8-13 Fixed 2033hex、Attribution Annals * @Time 2016-9-25 Fixed lunar LeapMonth Param Bug * @Version 1.0.2 * @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0] * @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0] */ var calendar = { /** * 农历1900-2100的润大小信息表 * @Array Of Property * @return Hex */ lunarInfo:[0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909 0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919 0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929 0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939 0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949 0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959 0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969 0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979 0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989 0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,//1990-1999 0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009 0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019 0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029 0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039 0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049 /**Add By JJonline@JJonline.Cn**/ 0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50, 0x06b20,0x1a6c4,0x0aae0,//2050-2059 0x0a2e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069 0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079 0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089 0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099 0x0d520],//2100 /** * 公历每个月份的天数普通表 * @Array Of Property * @return Number */ solarMonth:[31,28,31,30,31,30,31,31,30,31,30,31], /** * 农历节日 * @return String */ lunarHoliday: { '1-1': '春节', '1-15': '元宵节', '2-2': '龙头节', '5-5': '端午节', '7-7': '七夕节', '7-15': '中元节', '8-15': '中秋节', '9-9': '重阳节', '10-1': '寒衣节', '10-15': '下元节', '12-8': '腊八节', '12-23': '小年', }, /** * 阳历节日 * @return String */ gregorianHoliday: { '1-1': '元旦', '2-14': '情人节', '3-8': '妇女节', '3-12': '植树节', '5-1': '劳动节', '5-4': '青年节', '6-1': '儿童节', '7-1': '建党节', '8-1': '建军节', '9-10': '教师节', '10-1': '国庆节', '12-24': '平安夜', '12-25': '圣诞节', }, /** * 天干地支之天干速查表 * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"] * @return Cn string */ Gan:["\u7532","\u4e59","\u4e19","\u4e01","\u620a","\u5df1","\u5e9a","\u8f9b","\u58ec","\u7678"], /** * 天干地支之地支速查表 * @Array Of Property * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] * @return Cn string */ Zhi:["\u5b50","\u4e11","\u5bc5","\u536f","\u8fb0","\u5df3","\u5348","\u672a","\u7533","\u9149","\u620c","\u4ea5"], /** * 天干地支之地支速查表<=>生肖 * @Array Of Property * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"] * @return Cn string */ Animals:["\u9f20","\u725b","\u864e","\u5154","\u9f99","\u86c7","\u9a6c","\u7f8a","\u7334","\u9e21","\u72d7","\u732a"], /** * 24节气速查表 * @Array Of Property * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"] * @return Cn string */ solarTerm:["\u5c0f\u5bd2","\u5927\u5bd2","\u7acb\u6625","\u96e8\u6c34","\u60ca\u86f0","\u6625\u5206","\u6e05\u660e","\u8c37\u96e8","\u7acb\u590f","\u5c0f\u6ee1","\u8292\u79cd","\u590f\u81f3","\u5c0f\u6691","\u5927\u6691","\u7acb\u79cb","\u5904\u6691","\u767d\u9732","\u79cb\u5206","\u5bd2\u9732","\u971c\u964d","\u7acb\u51ac","\u5c0f\u96ea","\u5927\u96ea","\u51ac\u81f3"], /** * 1900-2100各年的24节气日期速查表 * @Array Of Property * @return 0x string For splice */ sTermInfo:['9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa','9778397bd19801ec9210c965cc920e','97b6b97bd19801ec95f8c965cc920f', '97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd197c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e','97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec95f8c965cc920e','97bcf97c3598082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9210c8dc2','9778397bd19801ec9210c9274c920e','97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f','97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e','97bd07f1487f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e','97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c91aa','97b6b97bd197c36c9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e', '97b6b7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b70c9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c91aa','97b6b7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','977837f0e37f149b0723b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc9210c8dc2','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0723b06bd','7f07e7f0e37f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f595b0b0bb0b6fb0722','7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f149b0723b0787b0721', '7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0723b06bd', '7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd','7f07e7f0e37f14998083b0787b0721','7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14898082b0723b02d5','7f07e7f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66aa89801e9808297c35','665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721', '7f0e36665b66a449801e9808297c35','665f67f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721','7f0e26665b66a449801e9808297c35','665f67f0e37f1489801eb072297c35', '7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722'], /** * 数字转中文速查表 * @Array Of Property * @trans ['日','一','二','三','四','五','六','七','八','九','十'] * @return Cn string */ nStr1:["\u65e5","\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341"], /** * 日期转农历称呼速查表 * @Array Of Property * @trans ['初','十','廿','卅'] * @return Cn string */ nStr2:["\u521d","\u5341","\u5eff","\u5345"], /** * 月份转农历称呼速查表 * @Array Of Property * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊'] * @return Cn string */ nStr3:["\u6b63","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341","\u51ac","\u814a"], /** * 返回农历y年一整年的总天数 * @param lunar Year * @return Number * @eg:var count = calendar.lYearDays(1987) ;//count=387 */ lYearDays:function(y) { var i, sum = 348; for(i=0x8000; i>0x8; i>>=1) { sum += (calendar.lunarInfo[y-1900] & i)? 1: 0; } return(sum+calendar.leapDays(y)); }, /** * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0 * @param lunar Year * @return Number (0-12) * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6 */ leapMonth:function(y) { //闰字编码 \u95f0 return(calendar.lunarInfo[y-1900] & 0xf); }, /** * 返回农历y年闰月的天数 若该年没有闰月则返回0 * @param lunar Year * @return Number (0、29、30) * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29 */ leapDays:function(y) { if(calendar.leapMonth(y)) { return((calendar.lunarInfo[y-1900] & 0x10000)? 30: 29); } return(0); }, /** * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法 * @param lunar Year * @return Number (-1、29、30) * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29 */ monthDays:function(y,m) { if(m>12 || m<1) {return -1}//月份参数从1至12,参数错误返回-1 return( (calendar.lunarInfo[y-1900] & (0x10000>>m))? 30: 29 ); }, /** * 返回公历(!)y年m月的天数 * @param solar Year * @return Number (-1、28、29、30、31) * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30 */ solarDays:function(y,m) { if(m>12 || m<1) {return -1} //若参数错误 返回-1 var ms = m-1; if(ms==1) { //2月份的闰平规律测算后确认返回28或29 return(((y%4 == 0) && (y%100 != 0) || (y%400 == 0))? 29: 28); }else { return(calendar.solarMonth[ms]); } }, /** * 农历年份转换为干支纪年 * @param lYear 农历年的年份数 * @return Cn string */ toGanZhiYear:function(lYear) { var ganKey = (lYear - 3) % 10; var zhiKey = (lYear - 3) % 12; if(ganKey == 0) ganKey = 10;//如果余数为0则为最后一个天干 if(zhiKey == 0) zhiKey = 12;//如果余数为0则为最后一个地支 return calendar.Gan[ganKey-1] + calendar.Zhi[zhiKey-1]; }, /** * 公历月、日判断所属星座 * @param cMonth [description] * @param cDay [description] * @return Cn string */ toAstro:function(cMonth,cDay) { var s = "\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf"; var arr = [20,19,21,21,21,22,23,23,23,23,22,22]; return s.substr(cMonth*2 - (cDay < arr[cMonth-1] ? 2 : 0),2) + "\u5ea7";//座 }, /** * 传入offset偏移量返回干支 * @param offset 相对甲子的偏移量 * @return Cn string */ toGanZhi:function(offset) { return calendar.Gan[offset%10] + calendar.Zhi[offset%12]; }, /** * 传入公历(!)y年获得该年第n个节气的公历日期 * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 * @return day Number * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春 */ getTerm:function(y,n) { if(y<1900 || y>2100) {return -1;} if(n<1 || n>24) {return -1;} var _table = calendar.sTermInfo[y-1900]; var _info = [ parseInt('0x'+_table.substr(0,5)).toString() , parseInt('0x'+_table.substr(5,5)).toString(), parseInt('0x'+_table.substr(10,5)).toString(), parseInt('0x'+_table.substr(15,5)).toString(), parseInt('0x'+_table.substr(20,5)).toString(), parseInt('0x'+_table.substr(25,5)).toString() ]; var _calday = [ _info[0].substr(0,1), _info[0].substr(1,2), _info[0].substr(3,1), _info[0].substr(4,2), _info[1].substr(0,1), _info[1].substr(1,2), _info[1].substr(3,1), _info[1].substr(4,2), _info[2].substr(0,1), _info[2].substr(1,2), _info[2].substr(3,1), _info[2].substr(4,2), _info[3].substr(0,1), _info[3].substr(1,2), _info[3].substr(3,1), _info[3].substr(4,2), _info[4].substr(0,1), _info[4].substr(1,2), _info[4].substr(3,1), _info[4].substr(4,2), _info[5].substr(0,1), _info[5].substr(1,2), _info[5].substr(3,1), _info[5].substr(4,2), ]; return parseInt(_calday[n-1]); }, /** * 传入农历数字月份返回汉语通俗表示法 * @param lunar month * @return Cn string * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月' */ toChinaMonth:function(m) { // 月 => \u6708 if(m>12 || m<1) {return -1} //若参数错误 返回-1 var s = calendar.nStr3[m-1]; s+= "\u6708";//加上月字 return s; }, /** * 传入农历日期数字返回汉字表示法 * @param lunar day * @return Cn string * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一' */ toChinaDay:function(d){ //日 => \u65e5 var s; switch (d) { case 10: s = '\u521d\u5341'; break; case 20: s = '\u4e8c\u5341'; break; break; case 30: s = '\u4e09\u5341'; break; break; default : s = calendar.nStr2[Math.floor(d/10)]; s += calendar.nStr1[d%10]; } return(s); }, /** * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春” * @param y year * @return Cn string * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔' */ getAnimal: function(y) { return calendar.Animals[(y - 4) % 12] }, /** * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON * @param y solar year * @param m solar month * @param d solar day * @return JSON object * @eg:console.log(calendar.solar2lunar(1987,11,01)); */ solar2lunar:function (y,m,d) { //参数区间1900.1.31~2100.12.31 if(y<1900 || y>2100) {return -1;}//年份限定、上限 if(y==1900&&m==1&&d<31) {return -1;}//下限 if(!y) { //未传参 获得当天 var objDate = new Date(); }else { var objDate = new Date(y,parseInt(m)-1,d) } var i, leap=0, temp=0; //修正ymd参数 var y = objDate.getFullYear(),m = objDate.getMonth()+1,d = objDate.getDate(); var offset = (Date.UTC(objDate.getFullYear(),objDate.getMonth(),objDate.getDate()) - Date.UTC(1900,0,31))/86400000; for(i=1900; i<2101 && offset>0; i++) { temp=calendar.lYearDays(i); offset-=temp; } if(offset<0) { offset+=temp; i--; } //是否今天 var isTodayObj = new Date(),isToday=false; if(isTodayObj.getFullYear()==y && isTodayObj.getMonth()+1==m && isTodayObj.getDate()==d) { isToday = true; } //星期几 var nWeek = objDate.getDay(),cWeek = calendar.nStr1[nWeek]; if(nWeek==0) {nWeek =7;}//数字表示周几顺应天朝周一开始的惯例 //农历年 var year = i; var leap = calendar.leapMonth(i); //闰哪个月 var isLeap = false; //效验闰月 for(i=1; i<13 && offset>0; i++) { //闰月 if(leap>0 && i==(leap+1) && isLeap==false){ --i; isLeap = true; temp = calendar.leapDays(year); //计算农历闰月天数 } else{ temp = calendar.monthDays(year, i);//计算农历普通月天数 } //解除闰月 if(isLeap==true && i==(leap+1)) { isLeap = false; } offset -= temp; } if(offset==0 && leap>0 && i==leap+1) if(isLeap){ isLeap = false; }else{ isLeap = true; --i; } if(offset<0){ offset += temp; --i; } //农历月 var month = i; //农历日 var day = offset + 1; //天干地支处理 var sm = m-1; var gzY = calendar.toGanZhiYear(year); //月柱 1900年1月小寒以前为 丙子月(60进制12) var firstNode = calendar.getTerm(year,(m*2-1));//返回当月「节」为几日开始 var secondNode = calendar.getTerm(year,(m*2));//返回当月「节」为几日开始 //依据12节气修正干支月 var gzM = calendar.toGanZhi((y-1900)*12+m+11); if(d>=firstNode) { gzM = calendar.toGanZhi((y-1900)*12+m+12); } //传入的日期的节气与否 var isTerm = false; var Term = null; if(firstNode==d) { isTerm = true; Term = calendar.solarTerm[m*2-2]; } if(secondNode==d) { isTerm = true; Term = calendar.solarTerm[m*2-1]; } //日柱 当月一日与 1900/1/1 相差天数 var dayCyclical = Date.UTC(y,sm,1,0,0,0,0)/86400000+25567+10; var gzD = calendar.toGanZhi(dayCyclical+d-1); //该日期所属的星座 var astro = calendar.toAstro(m,d); return {'lYear':year,'lMonth':month,'lDay':day,'Animal':calendar.getAnimal(year),'IMonthCn':(isLeap?"\u95f0":'')+calendar.toChinaMonth(month),'IDayCn':calendar.toChinaDay(day),'cYear':y,'cMonth':m,'cDay':d,'gzYear':gzY,'gzMonth':gzM,'gzDay':gzD,'isToday':isToday,'isLeap':isLeap,'nWeek':nWeek,'ncWeek':"\u661f\u671f"+cWeek,'isTerm':isTerm,'Term':Term,'astro':astro}; }, /** * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON * @param y lunar year * @param m lunar month * @param d lunar day * @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可] * @return JSON object * @eg:console.log(calendar.lunar2solar(1987,9,10)); */ lunar2solar:function(y,m,d,isLeapMonth) { //参数区间1900.1.31~2100.12.1 var isLeapMonth = !!isLeapMonth; var leapOffset = 0; var leapMonth = calendar.leapMonth(y); var leapDay = calendar.leapDays(y); if(isLeapMonth&&(leapMonth!=m)) {return -1;}//传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同 if(y==2100&&m==12&&d>1 || y==1900&&m==1&&d<31) {return -1;}//超出了最大极限值 var day = calendar.monthDays(y,m); var _day = day; //bugFix 2016-9-25 //if month is leap, _day use leapDays method if(isLeapMonth) { _day = calendar.leapDays(y,m); } if(y < 1900 || y > 2100 || d > _day) {return -1;}//参数合法性效验 //计算农历的时间差 var offset = 0; for(var i=1900;i0) { offset+=calendar.leapDays(y);isAdd = true; } } offset+=calendar.monthDays(y,i); } //转换闰月农历 需补充该年闰月的前一个月的时差 if(isLeapMonth) {offset+=day;} //1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点) var stmap = Date.UTC(1900,1,30,0,0,0); var calObj = new Date((offset+d-31)*86400000+stmap); var cY = calObj.getUTCFullYear(); var cM = calObj.getUTCMonth()+1; var cD = calObj.getUTCDate(); return calendar.solar2lunar(cY,cM,cD); } }; export default calendar; ================================================ FILE: src/mpvue-calendar.vue ================================================ ================================================ FILE: src/shims-vue.d.ts ================================================ declare module "*.vue" { import Vue from 'vue' export default Vue } ================================================ FILE: src/style.less ================================================ .mpvue-calendar{ position: relative; width: 300px; &.mpvue-calendar-mode-week{ .vc-calendar-info{ cursor: inherit; } .vc-calendar-timetable{ .vc-calendar-timetable-wrap{ .vc-calendar-body{ .vc-calendar-content{ .vc-calendar-month-background-text{ font-size: 80px; } } } } } } } ================================================ FILE: tsconfig.json ================================================ { "compilerOptions": { "target": "esnext", "module": "esnext", "strict": true, "jsx": "preserve", "importHelpers": true, "moduleResolution": "node", "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "sourceMap": true, "baseUrl": ".", "types": [ "webpack-env" ], "paths": { "@/*": [ "src/*", "example/*" ] }, "lib": [ "esnext", "dom", "dom.iterable", "scripthost" ] }, "include": [ "src/**/*.ts", "src/**/*.tsx", "src/**/*.vue" ], "exclude": [ "node_modules" ] } ================================================ FILE: vue.config.js ================================================ const path = require("path"); module.exports = { publicPath: process.env.NODE_ENV === 'production' ? '/mpvue-calendar/' : '/', configureWebpack: { context: path.resolve(__dirname, './'), entry: { app: process.env.NODE_ENV === 'production' ? './src/mpvue-calendar.vue' : './example/main.js' }, }, css: { extract: false }, productionSourceMap: false, lintOnSave: process.env.NODE_ENV !== 'production' }