Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
Background to the case
This project adopts the technology stack of VUe2. X + elementUi. At the end of the project development, due to some special reasons, all the date selector components need to be added to the lunar calendar, holidays, etc. The date component basically uses the El-Data-picker component. Due to various reasons such as the large project and the complex business of the component used, the el-Data-picker component can only be removed and rebuilt.
1. Pull the separate component out and run normally
- Will be in
node_modules
>element-ui
>packages
Under thedate-picker
Make a copy of the contents of the component folder into your own projectcomponents
Directory; - in
main.js
Import and drop folderscomponents
Under folderdate-picker
component
// Import the modified element's datepicker
import DatePicker from './components/datePicker/index'
Vue.use(ElementUI)
Vue.use(DatePicker)
Copy the code
- At this time
npm run dev
The project does not run properly and reports the following errorscrollbar
There was a problem with the build.
At this point you need to putdate-picker
There are two entries under the folderscrollbar
Code to comment out (ElementUi is introduced globally in this project)
4. When we restarted the project, we found that the project started normally anddate-picker
componentLooks like it’s workingIn fact, there is an interaction problem >When we putdate-picker
Components in thedialog
When you pop up in the window component, you will notice that the date picker does not show up when it is opened twice.
At this point, I deeply suspected that it was because of this way of introductiondate-picker
> picker.vue
Inside the source codeel-input
infocus
What’s wrong with getting focus when I play layer by layerdebugger
When looking for the root of the problem, keep looking for the picture below
At this point js logic code is not a problem, when I am puzzled, I suddenly want to see the corresponding pagedom
Render the case at this timeThe corresponding DOM structure is found in the page
5. When the corresponding DOM structure is discovered, one dom is also foundelement
thepopup-manager
Reset for this componentz-index
Properties, thez-index
Normally it increments, but here it’s possible that because I pulled the component out again, the component corresponds toz-index
And we start over. The simple solution is to give thedom
Set a bigger onez-index
.
2, Modify datePicker component, add lunar calendar and holidays
- It can be found by observation
datePicker
Component’s date pickerdatePicker
>src
>basic
>date-table.vue
File, and we only need to put the corresponding lunar calendar and holiday display in{{ cell.text }}
Just below the code. - To get the corresponding lunar date, a method commonly used on the network is used here. The code is shown below (with adjustments to the getLunarFestival function of this code later) :
// date.js
/** * @1900-2100 range of Gregorian calendar, lunar calendar interchange *@charset UTF8 *@Author Jea Yang (JJonline@JJonline.Cn)
* @Time The 2014-7-21 *@Time 2016-8-13 Fixed 2033HEX, Attribution Annals *@Time 2016-9-25 Fixed lunar LeapMonth Param Bug
* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
* @Version Solar2lunar (1987,11,01); //[you can ignore params of prefix 0] * @calendar: calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0] */
export default {
/** * Calendar 1900-2100 run size information table *@Array Of Property
* @return Hex* /
lunarInfo: [0x04bd8.0x04ae0.0x0a570.0x054d5.0x0d260.0x0d950.0x16554.0x056a0.0x09ad0.0x055d2.0x04ae0.0x0a5b6.0x0a4d0.0x0d250.0x1d255.0x0b540.0x0d6a0.0x0ada2.0x095b0.0x14977.0x04970.0x0a4b0.0x0b4b5.0x06a50.0x06d40.0x1ab54.0x02b60.0x09570.0x052f2.0x04970.0x06566.0x0d4a0.0x0ea50.0x16a95.0x05ad0.0x02b60.0x186e3.0x092e0.0x1c8d7.0x0c950.0x0d4a0.0x1d8a6.0x0b550.0x056a0.0x1a5b4.0x025d0.0x092d0.0x0d2b2.0x0a950.0x0b557.0x06ca0.0x0b550.0x15355.0x04da0.0x0a5b0.0x14573.0x052b0.0x0a9a8.0x0e950.0x06aa0.0x0aea6.0x0ab50.0x04b60.0x0aae4.0x0a570.0x05260.0x0f263.0x0d950.0x05b57.0x056a0.0x096d0.0x04dd5.0x04ad0.0x0a4d0.0x0d4d4.0x0d250.0x0d558.0x0b540.0x0b6a0.0x195a6.0x095b0.0x049b0.0x0a974.0x0a4b0.0x0b27a.0x06a50.0x06d40.0x0af46.0x0ab60.0x09570.0x04af5.0x04970.0x064b0.0x074a3.0x0ea50.0x06b58.0x05ac0.0x0ab60.0x096d5.0x092e0.0x0c960.0x0d954.0x0d4a0.0x0da50.0x07552.0x056a0.0x0abb7.0x025d0.0x092d0.0x0cab5.0x0a950.0x0b4a0.0x0baa4.0x0ad50.0x055d9.0x04ba0.0x0a5b0.0x15176.0x052b0.0x0a930.0x07954.0x06aa0.0x0ad50.0x05b52.0x04b60.0x0a6e6.0x0a4e0.0x0d260.0x0ea65.0x0d530.0x05aa0.0x076a3.0x096d0.0x04afb.0x04ad0.0x0a4d0.0x1d0b6.0x0d250.0x0d520.0x0dd45.0x0b5a0.0x056d0.0x055b2.0x049b0.0x0a577.0x0a4b0.0x0aa50.0x1b255.0x06d20.0x0ada0.0x14b63.0x09370.0x049f8.0x04970.0x064b0.0x168a6.0x0ea50.0x06b20.0x1a6c4.0x0aae0.0x092e0.0x0d2e3.0x0c960.0x0d557.0x0d4a0.0x0da50.0x05d55.0x056a0.0x0a6d0.0x055d4.0x052d0.0x0a9b8.0x0a950.0x0b4a0.0x0b6a6.0x0ad50.0x055a0.0x0aba4.0x0a5b0.0x052b0.0x0b273.0x06930.0x07337.0x06aa0.0x0ad50.0x14b55.0x04b60.0x0a570.0x054e4.0x0d160.0x0e968.0x0d520.0x0daa0.0x16aa6.0x056d0.0x04ae0.0x0a9d4.0x0a2d0.0x0d150.0x0f252.0x0d520,]./ / 2100
/** * The days of each month in the Gregorian calendar *@Array Of Property
* @return Number* /
solarMonth: [31.28.31.30.31.30.31.31.30.31.30.31]./** ** ** ** ** ** ** **@Array Of Property trans [" a ", "b", "c", "ding", "e", "f", "age", "xin" and "I" and "j"] *@return Cn string
*/
Gan: ['\u7532'.'\u4e59'.'\u4e19'.'\u4e01'.'\u620a'.'\u5df1'.'\u5e9a'.'\u8f9b'.'\u58ec'.'\u7678',]./** ** ** ** **@Array Of Property
* @trans[" son ", "ugly", "Yin" and "frame", ""," the third ", "afternoon", "not", "shen", "unitary" and "xu-gou", "hai"] *@return Cn string
*/
Zhi: ['\u5b50'.'\u4e11'.'\u5bc5'.'\u536f'.'\u8fb0'.'\u5df3'.'\u5348'.'\u672a'.'\u7533'.'\u9149'.'\u620c'.'\u4ea5',]./** ** The Chinese Zodiac *@Array Of Property
* @trans[" mouse ", "cow", "tiger", "rabbit", "dragon", "snake", "horse", "sheep", "monkey", "chicken", "dog", "pig"] *@return Cn string
*/
Animals: ['\u9f20'.'\u725b'.'\u864e'.'\u5154'.'\u9f99'.'\u86c7'.'\u9a6c'.'\u7f8a'.'\u7334'.'\u9e21'.'\u72d7'.'\u732a',]./** * Solar calendar */
festival: {
1-1 ' ': { title: New Year's Day },
'2-14': { title: 'Valentine's Day' },
'5-1': { title: Labor Day },
'5-4': { title: Youth Day },
'6-1': { title: Children's Day },
'9-10': { title: Teachers' Day },
10-1 ' ': { title: National Day },
'12 to 25': { title: 'Christmas' },
'3-8': { title: Women's Day },
'3-12': { title: Arbor Day },
4-1 ' ': { title: April Fool's Day },
'5-12': { title: Nurse's Day },
7 '1': { title: 'Party Founding Day' },
'8-1': { title: Army Day },
'12 to 24': { title: 'Silent Night'}},/** * Lunar Festival */
lfestival: {
'12-30': { title: 'New Year's eve },
1-1 ' ': { title: 'New Year' },
1-15 ' ': { title: Lantern Festival },
'5-5': { title: Dragon Boat Festival },
'8-15': { title: Mid-Autumn Festival },
'9-9': { title: 'Double Ninth Festival' },
7 '7': { title: 'festival'}},/** * Returns a solar calendar holiday defined by default */
getFestival() {
return this.festival
},
/** * returns the default definition of the contents of the holiday */
getLunarFestival(y,m,d) {
return this.lfestival
},
/ * * * *@param {Object} Enter the data according to the format of festival, set the solar calendar festival */
setFestival(param = {}) {
this.festival = param
},
/ * * * *@param {Object} Enter data in the format of LFestival to set lunar festival */
setLunarFestival(param = {}) {
this.lfestival = param
},
/** * 24 solar terms quick reference *@Array Of Property
* @trans[" slight cold, "" it", "spring", "rain", the "insects awaken", "spring", "qingming festival", "gu yu", "summer", "grain full", "grain in ear", "the summer solstice", "slight heat", "great heat", "beginning of autumn", "the end of heat" and "millennium", "the autumnal equinox", "cold dew", "frost", "the beginning of winter," "light snow", "snow", "winter solstice" ] *@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',]./** * the 24 solar terms in 1900-2100 *@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 [' day ',' one ',' two ',' three ',' four ',' five ',' six ',' seven ',' eight ',' nine ',' ten '] *@return Cn string
*/
nStr1: ['\u65e5'.'\u4e00'.'\u4e8c'.'\u4e09'.'\u56db'.'\u4e94'.'\u516d'.'\u4e03'.'\u516b'.'\u4e5d'.'\u5341',]./** ** Date to lunar name list *@Array Of Property
* @trans [' chu ',' ten ',' 20 ',' 30 '] *@return Cn string
*/
nStr2: ['\u521d'.'\u5341'.'\u5eff'.'\u5345']./** ** month to lunar name list *@Array Of Property
* @trans [' is', 'a', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'winter', 'la'] *@return Cn string
*/
nStr3: ['\u6b63'.'\u4e8c'.'\u4e09'.'\u56db'.'\u4e94'.'\u516d'.'\u4e03'.'\u516b'.'\u4e5d'.'\u5341'.'\u51ac'.'\u814a',]./** * Returns the total number of days * in year Y of the lunar calendar@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 += this.lunarInfo[y - 1900] & i ? 1 : 0
}
return sum + this.leapDays(y)
},
/** * return lunar y year leap month which month; Returns 0 * if y has no leap month@param lunar Year
* @return Number (0-12)
* @eg:var leapMonth = calendar.leapMonth(1987) ; //leapMonth=6 */
leapMonth: function(y) {
// Leap code \ 4U 95f0
return this.lunarInfo[y - 1900] & 0xf
},
/** * returns the number of leap months in y of the lunar calendar 0 * if there is no leap month in that year@param lunar Year
* @return Number (0, 29, 30) *@eg:var leapMonthDay = calendar.leapDays(1987) ; //leapMonthDay=29 */
leapDays: function(y) {
if (this.leapMonth(y)) {
return this.lunarInfo[y - 1900] & 0x10000 ? 30 : 29
}
return 0
},
/** * Returns the total number of days in m (non-leap month) in y year of the lunar calendar. Use the leapDays method * to calculate the number of days when M is a leap month@param lunar Year
* @return Number (-1, 29, 30) *@egVar MonthDay = calendar. MonthDays (1987,9); //MonthDay=29 */
monthDays: function(y, m) {
if (m > 12 || m < 1) {
return -1
} // The month parameter ranges from 1 to 12
return this.lunarInfo[y - 1900] & (0x10000 >> m) ? 30 : 29
},
/** * return to Gregorian calendar (!) Y Number of days in m months *@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
} // Return -1 if the argument is incorrect
var ms = m - 1
if (ms == 1) {
// The leap level rule in February will return 28 or 29 after confirmation
return (y % 4= =0 && y % 100! =0) || y % 400= =0 ? 29 : 28
} else {
return this.solarMonth[ms]
}
},
/** * The lunar year is converted to the ganzhi year *@param LYear Number of years in a Lunar year *@return Cn string
*/
toGanZhiYear: function(lYear) {
var ganKey = (lYear - 3) % 10
var zhiKey = (lYear - 3) % 12
if (ganKey == 0) ganKey = 10 // If the remainder is 0, it is the last celestial trunk
if (zhiKey == 0) zhiKey = 12 // If the remainder is 0, it is the last branch
return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]},/** * Gregorian calendar month, day to determine the constellation *@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\u79e 4\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' / / a
},
/** * The offset is passed to return the dry branch *@param Offset Indicates the offset with respect to the offset *@return Cn string
*/
toGanZhi: function(offset) {
return this.Gan[offset % 10] + this.Zhi[offset % 12]},/** * pass to Gregorian calendar (!) Year Y gets the date of the NTH solar term * in the Gregorian calendar@param Y Gregorian calendar year (1900-2100); N The solar terms of the 24 solar terms (1~24); N =1(minor cold) *@return day Number
* @eg:var _24 = calendar.getterm (1987,3); / / _24 = 4; It means the beginning of spring on February 4, 1987
getTerm: function(y, n) {
if (y < 1900 || y > 2100) {
return -1
}
if (n < 1 || n > 24) {
return -1
}
var _table = this.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])},/** * returns the Chinese colloquial representation of the month passed into the lunar calendar@param lunar month
* @return Cn string
* @eg:var cnMonth = calendar.toChinaMonth(12) ; //cnMonth=' 12 '*/
toChinaMonth: function(m) {
= > \ u6708 / / month
if (m > 12 || m < 1) {
return -1
} // Return -1 if the argument is incorrect
var s = this.nStr3[m - 1]
s += '\u6708' // Add the month
return s
},
/** * incoming lunar date number returns Chinese character representation *@param lunar day
* @return Cn string
* @eg:var cnDay = calendar.toChinaDay(21) ; //cnMonth=' 21 '*/
toChinaDay: function(d) {
/ / day = > \ 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 = this.nStr2[Math.floor(d / 10)]
s += this.nStr1[d % 10]}return s
},
/** * The year can be roughly converted => The exact demarcation line is "Start of Spring" *@param y year
* @return Cn string
* @eg:var animal = calendar.getAnimal(1987) ; / / animal = 'rabbit' * /
getAnimal: function(y) {
return this.Animals[(y - 4) % 12]},/** ** <=>JSON *@param y solar year
* @param m solar month
* @param d solar day
* @return JSON object
* @eg: the console log (calendar. Solar2lunar,11,01 (1987)); * /
solar2lunar: function(y, m, d) {
let {workday, holiday} = this.initHoliday()
// The parameter ranges from 1900.1.31 to 2100.12.31
y = parseInt(y)
m = parseInt(m)
d = parseInt(d)
// Year limit
if (y < 1900 || y > 2100) {
return -1 // undefined is converted to a number to NaN
}
// The maximum number of parameters in the Gregorian calendar
if (y == 1900 && m == 1 && d < 31) {
return -1
}
// Did not transfer the date
if(! y) {var objDate = new Date()}else {
var objDate = new Date(y, parseInt(m) - 1, d)
}
var i,
leap = 0,
temp = 0
// Modify ymD parameters
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 = this.lYearDays(i)
offset -= temp
}
if (offset < 0) {
offset += temp
i--
}
// Is it today
var isTodayObj = new Date(),
isToday = false
if (
isTodayObj.getFullYear() == y &&
isTodayObj.getMonth() + 1 == m &&
isTodayObj.getDate() == d
) {
isToday = true
}
/ / week
var nWeek = objDate.getDay(),
cWeek = this.nStr1[nWeek]
// The number indicates the day of the week, following China's custom of starting on Monday
if (nWeek == 0) {
nWeek = 7
}
/ / the lunar New Year
var year = i
var leap = this.leapMonth(i) // Leap which month
var isLeap = false
// Leap month
for (i = 1; i < 13 && offset > 0; i++) {
/ / leap month
if (leap > 0 && i == leap + 1 && isLeap == false) {
--i
isLeap = true
temp = this.leapDays(year) // Calculate the number of leap months in lunar calendar
} else {
temp = this.monthDays(year, i) // Calculate the number of days in a common lunar month
}
// Remove leap months
if (isLeap == true && i == leap + 1) {
isLeap = false
}
offset -= temp
}
// Leap months cause array subscripts to overlap inversely
if (offset == 0 && leap > 0 && i == leap + 1) {
if (isLeap) {
isLeap = false
} else {
isLeap = true
--i
}
}
if (offset < 0) {
offset += temp
--i
}
/ / the lunar month
var month = i
/ / the lunar day
var day = offset + 1
//
var sm = m - 1
var gzY = this.toGanZhiYear(year)
// The two solar terms of the month
// bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
var firstNode = this.getTerm(y, m * 2 - 1) // Returns the start date of the month
var secondNode = this.getTerm(y, m * 2) // Returns the start date of the month
// Correct dry branch moon according to 12 solar terms
var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
if (d >= firstNode) {
gzM = this.toGanZhi((y - 1900) * 12 + m + 12)}// The solar term of the incoming date
var isTerm = false
var Term = null
if (firstNode == d) {
isTerm = true
Term = this.solarTerm[m * 2 - 2]}if (secondNode == d) {
isTerm = true
Term = this.solarTerm[m * 2 - 1]}// The difference between the day of the month and 1900/1/1
var dayCyclical = Date.UTC(y, sm, 1.0.0.0.0) / 86400000 + 25567 + 10
var gzD = this.toGanZhi(dayCyclical + d - 1)
// The constellation to which the date belongs
var astro = this.toAstro(m, d)
var solarDate = y + The '-' + (m + ' ').padStart(2.0) + The '-' + (d + ' ').padStart(2.0)
var lunarDate = year + The '-' + month + The '-' + day
var festival = this.festival
var lfestival = this.getLunarFestival(year, month, day)
var festivalDate = m + The '-' + d
var lunarFestivalDate = month + The '-' + day
return {
isWork: workday.includes(solarDate),
isHoliday: holiday.includes(solarDate),
date: solarDate,
lunarDate: lunarDate,
festival: festival[festivalDate] ? festival[festivalDate].title : null.lunarFestival: lfestival[lunarFestivalDate]
? lfestival[lunarFestivalDate].title
: null.lYear: year,
lMonth: month,
lDay: day,
Animal: this.getAnimal(year),
IMonthCn: (isLeap ? '\u95f0' : ' ') + this.toChinaMonth(month),
IDayCn: this.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,
}
},
/** * Get detailed Gregorian calendar, lunar object information <=>JSON *@param y lunar year
* @param m lunar month
* @param d lunar day
* @param IsLeapMonth Lunar month is leap or not@return JSON object
* @eg: the console log (calendar. Lunar2solar,9,10 (1987)); * /
lunar2solar: function(y, m, d, isLeapMonth) {
// The parameter ranges from 1900.1.31 to 2100.12.1
y = parseInt(y)
m = parseInt(m)
d = parseInt(d)
varisLeapMonth = !! isLeapMonthvar leapOffset = 0
var leapMonth = this.leapMonth(y)
var leapDay = this.leapDays(y)
if(isLeapMonth && leapMonth ! = m) {return -1
} // The leap month in the calendar year is not the same as the month in which the leap month is passed
if ((y == 2100 && m == 12 && d > 1) || (y == 1900 && m == 1 && d < 31)) {
return -1
} // The maximum value is exceeded
var day = this.monthDays(y, m)
var _day = day
//bugFix 2016-9-25
//if month is leap, _day use leapDays method
if (isLeapMonth) {
_day = this.leapDays(y, m)
}
if (y < 1900 || y > 2100 || d > _day) {
return -1
} // Check the validity of the parameter
// Calculate the lunar time difference
var offset = 0
for (var i = 1900; i < y; i++) {
offset += this.lYearDays(i)
}
var leap = 0,
isAdd = false
for (var i = 1; i < m; i++) {
leap = this.leapMonth(y)
if(! isAdd) {// Handle leap months
if (leap <= i && leap > 0) {
offset += this.leapDays(y)
isAdd = true
}
}
offset += this.monthDays(y, i)
}
// The leap month lunar calendar needs to supplement the time difference of the previous leap month in that year
if (isLeapMonth) {
offset += day
}
// The first day of the first lunar month in 1900 is 0 hours 0 minutes 0 seconds on January 30, 1900 (this time is also the beginning point of this lunar calendar)
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 `${cY}${cM}${cD}`
// return this.solar2lunar(cY, cM, cD)
},
// Annual holiday schedule
initHoliday: function(){
let workday = ['2018-01-01'.'2018-02-02'] // Define it here
let holiday = ['2018-03-01'.'2018-04-02']
return {workday,holiday}
}
}
Copy the code
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
import calendar from '@/utils/date.js' // Import the defined date.js
// This code is the contents of the rows() function in method, which can be matched by searching for text in the file
if(! row[0]) {
row[0] = { type: 'week'.text: getWeekNumber(nextDate(startDate, i * 7 + 1)), lunar: calendar.solar2lunar(this.year, this.month, nextDate(startDate, i * 7 + 1))}}if (j + i * 7 >= numberOfDaysFromPreviousMonth) {
cell.text = count++
cell.lunar = calendar.solar2lunar(this.year, this.month + 1, cell.text) // A new one
} else {
cell.text = dateCountOfLastMonth - (numberOfDaysFromPreviousMonth - j % 7) + 1 + i * 7
cell.type = 'prev-month'
cell.lunar = calendar.solar2lunar(this.year, this.month, cell.text) // A new one}}else {
if (count <= dateCountOfMonth) {
cell.text = count++
cell.lunar = calendar.solar2lunar(this.year, this.month + 1, cell.text) // A new one
} else {
cell.text = count++ - dateCountOfMonth
cell.type = 'next-month'
cell.lunar = calendar.solar2lunar(this.year, this.month + 2, cell.text) // A new one}}Copy the code
- Render the structure related to lunar calendar and holidays under the corresponding DOM element (CSS style is omitted here, self-modified, various state style has a lot of adjustment, self-processing for the style), the key code is as follows:
<div :class="{'is-weekend': [6,7]. Includes (cell.lunar. NWeek), 'is-work':cell.lunar.>
<span>
{{ cell.text }}
</span>
// The section tag is used here for a special reason, explained in the next step
<section style="position: relative; top: 14px;">{{cell.lunar.lunarFestival? cell.lunar.lunarFestival:(cell.lunar.festival ? Lunar: (cell. Lunar.IDayCn == 'lunar '? cell.lunar.IMonthCn:cell.lunar.IDayCn )) }}</section>
</div>
Copy the code
At this time the lunar calendar, holidays, weekends can be displayed normally. Just when I thought I could relax, I found a new problem.
When I click on the lunar calendar area, there is no trigger date selection issue
Now I find that the selected date is delegated to the entire date component by event delegate, and the section tag cannot trigger the selected event. If we use span or div tags, we cannot tell which target is referring to. Delegate the section click event to the entire outer component at the same time. The key codes are as follows:
handleClick (event) {
let target = event.target
if (target.tagName === 'SPAN' || target.tagName == 'SECTION') {
target = target.parentNode.parentNode
}
if (target.tagName === 'DIV') {
target = target.parentNode
}
}
Copy the code
Four, New Year’s Eve festival problems
What you want at this point is basically done, and the mood is also comfortable. However, soon there was another problem, that is, when the twelfth lunar month only 29 days, the New Year’s Eve corresponds to the twelfth lunar month 29, not the twelfth lunar month 30, and the festival in my code is the date object directly corresponding
/** * Lunar Festival */
lfestival: {
'12-30': { title: 'New Year's eve },
1-1 ' ': { title: 'New Year' },
1-15 ' ': { title: Lantern Festival },
'5-5': { title: Dragon Boat Festival },
'8-15': { title: Mid-Autumn Festival },
'9-9': { title: 'Double Ninth Festival' },
7 '7': { title: 'festival'}},Copy the code
“MonthDays” () “monthDays” () “monthDays” () “” monthDays” () “” monthDays” () “” monthDays” () “” monthDays” () “” monthDays” ()” This means that THERE is no way for me to tell the difference between setting New Year’s Eve for the 29th of the 12th month and setting New Year’s Eve for the 30th of the 12th month. I also began to doubt the correctness of this method. After consulting materials for many times, I found that this method is used on the Internet. This method can only be left at that. The back of the original want to study how to get the New Year’s Eve in JS, also did not understand, here if there is a big guy know, can you guide me?
Finally, in my insistence, it is not the proper way to find a way: general idea is through the lunar date backwards to calculate the corresponding Gregorian calendar date, if the corresponding date of the Gregorian calendar, the lunar month, 30 then also means that the lunar 30 exist, if calculated backwards 30 corresponds to the solar calendar lunar return 1, means that this month, only 29 days. From this we can tell whether New Year’s Eve is the 30th or 29th day of the 12th month.
Key code modifications are as follows:
/** * y, m, and d are the corresponding lunar year, month, and day respectively
getLunarFestival(y,m,d) {
if (m == 12 && d == 29) {
if (this.lunar2solar(y,m,30) = = -1) {
delete this.lfestival['12-30']
this.lfestival['12-29'] = {title: 'New Year's eve}}else {
delete this.lfestival['12-29']
this.lfestival['12-30'] = {title: 'New Year's eve}}}return this.lfestival
},
Copy the code
conclusion
At this point, the second development of the calendar component is complete, also is a basic understanding of the calendar component, this wanted to find other components how to deal with the New Year’s Eve festival, at least has not found the corresponding processing. Here is another successful picture! Demo code address.