UNPKG

nly-adminlte-vue

Version:
1,732 lines (1,596 loc) 49 kB
# FormDatepicker > 日期选择器可以选择范围日期,单个日期,选择时间,以及渲染成其他任何组件 ## 日期值的获取和格式化 ### value `value` 是日期选择器选择的时间,给 `date-range` 传值可以初始化日期选择器的初始值。 ```html <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' /> <!-- value.name --> <!-- date-picker.vue --> ``` `value` 是可以双向绑定数据的,即使用 `v-model` 指令来绑定, 这样可以设定日期选择器的初始化,也能获取到他的修改值 ```html <template> <div> <nly-form-daterangepicker v-model="dateRange" /> <nly-form-group label="起始时间"> <nly-form-input v-model="dateRange.startDate" type="text" /> </nly-form-group> <nly-form-group label="结束时间"> <nly-form-input v-model="dateRange.endDate" type="text" /> </nly-form-group> </div> </template> <script> export default { data() { return { dateRange: { startDate: "2019-12-10", endDate: "2019-12-20" } }; } }; </script> <!-- v-model value.name --> <!-- date-picker.vue --> ``` **注意** - 默认渲染下, 不支持从日期选择器中输入日期来调整日历上的时间 ### locale-data 格式化默认显示时间 可以使用 `locale-data` 来设置输入框显示的数据格式,比如设置 `:locale-data = "{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }"` 来使数据显示格式为 2020-01-01 08:30:22 `value` 是日期选择器选择的时间,给 `value` 传值可以初始化日期选择器的初始值。 ```html <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" /> <!-- locale-data.name --> <!-- date-picker.vue --> ``` `locale-data` 可以用来设置一些自定义配置,比如设置中文。 **注意** - 这里有个 bug,如果星期的名称太长,比如 星期一 这样,会导致日历挤出 dropdown 的包裹,建议星期名称只设置一个字 - 这个 bug 暂时不会修复 ```html <template> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :locale-data="localeData" show-week-numbers show-dropdowns :ranges="ranges" /> </template> <script> export default { data() { return { localeData: { direction: "ltr", format: "mm/dd/yyyy", separator: " - ", applyLabel: "确定", cancelLabel: "取消", weekLabel: "周", customRangeLabel: "Custom Range", daysOfWeek: ["日", "一", "二", "三", "四", "五", "六"], monthNames: [ "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月" ], firstDay: 0 }, ranges: false }; }, mounted() { let today = new Date(); today.setHours(0, 0, 0, 0); let yesterday = new Date(); yesterday.setDate(today.getDate() - 1); yesterday.setHours(0, 0, 0, 0); let thisMonthStart = new Date(today.getFullYear(), today.getMonth(), 1); let thisMonthEnd = new Date(today.getFullYear(), today.getMonth() + 1, 0); this.ranges = { 今天: [today, today], 昨天: [yesterday, yesterday], 本月: [thisMonthStart, thisMonthEnd], 今年: [ new Date(today.getFullYear(), 0, 1), new Date(today.getFullYear(), 11, 31) ], 上个月: [ new Date(today.getFullYear(), today.getMonth() - 1, 1), new Date(today.getFullYear(), today.getMonth(), 0) ] }; } }; </script> <!-- locale-data.name --> <!-- date-picker.vue --> ``` ### update 获取选择时间 不使用 `v-model` 指令,也可以通过 update 函数来获取日期选择器选择的时间, 默认获取的时间是 GMT 时间, 格式需要自己定义函数来修改 ```html <template> <div> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" @update="update" /> <p> <span>起始时间: {{startDate}}</span> </p> <p> <span>结束时间: {{endDate}}</span> </p> </div> </template> <script> export default { data() { return { startDate: null, endDate: null }; }, methods: { update(value) { this.startDate = this.gmtFormat(value.startDate); this.endDate = this.gmtFormat(value.endDate); }, gmtFormat(time) { let date = new Date(time); let Str = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds(); return Str; } } }; </script> <!-- locale-data.name --> <!-- date-picker.vue --> ``` ### 最小和最大时间限制 设置 `min-date` 和 `max-date` prop 可以限制日期选择器的 时间选择范围,超出这个范围的时间是无法选择的,且日历上也无法联动现实超出这个范围的时间 ```html <template> <div> <nly-form-daterangepicker :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" :min-date="minDate" :max-date="maxDate" v-model="dateRange" show-dropdowns /> <nly-form-group label="起始时间"> <nly-form-input v-model="dateRange.startDate" type="text" /> </nly-form-group> <nly-form-group label="结束时间"> <nly-form-input v-model="dateRange.endDate" type="text" /> </nly-form-group> </div> </template> <script> export default { data() { return { dateRange: { startDate: "2019-12-10", endDate: "2019-12-20" }, minDate: "2019-5-1 04:00:00", maxDate: "2021-1-1 04:00:00" }; } }; </script> <!-- min & max date.name --> <!-- date-picker.vue --> ``` ## 渲染输入框的一些设置 ### prepend 和 append `prepend` 和 `append` prop 可以设置前后显示文字,渲染成类似 icon 的效果 ```html <template> <div> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" :prepend="prepend" :append="append" /> <nly-form-group label="prepend 输入框前面图标" label-cols-xs="auto" class="mt-2" > <nly-form-input v-model="prepend" size="sm" /> </nly-form-group> <nly-form-group label="append 输入框前面图标" label-cols-xs="auto"> <nly-form-input v-model="append" size="sm" /> </nly-form-group> </div> </template> <script> export default { data() { return { prepend: "", append: "" }; } }; </script> <!-- prepend and append .name --> <!-- date-picker.vue --> ``` 也可以使用 `prepend-html` 和 `append-html` prop 来设置输入框前后显示的内容。由于是 html 字符串,请谨慎使用 ```html <template> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" :prepend-html="prepend" :append-html="append" /> </template> <script> export default { data() { return { prepend: "<b>w</b>", append: "<b>Q</b>" }; } }; </script> <!-- prepend-html and append-html .name --> <!-- date-picker.vue --> ``` 还可以使用 `prepend` 和 `append` 插槽插入其他嵌套元素 ```html <template> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" > <template v-slot:prepend> <nly-input-group-text> <nly-icon icon="nlyfont nly-icon-time" /> </nly-input-group-text> </template> <template v-slot:append> <nly-dropdown text="Dropdown" variant="success"> <nly-dropdown-item>Action A</nly-dropdown-item> <nly-dropdown-item>Action B</nly-dropdown-item> </nly-dropdown> </template> </nly-form-daterangepicker> </template> <!-- prepend-html and append-html .name --> <!-- date-picker.vue --> ``` ### 控制大小 `nly-form-daterangepicker` 提供一个 `size` prop 来控制默认渲染的输入框大小, 可选 `sm`, `md`, `lg`。 ```html <template> <div> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" size="sm" > </nly-form-daterangepicker> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" size="md" class="mt-2" > </nly-form-daterangepicker> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" size="lg" class="mt-2" > </nly-form-daterangepicker> </div> </template> <!-- prepend-html and append-html .name --> <!-- date-picker.vue --> ``` ### valid 验证提示 `nly-form-daterangepicker` 提供一个 `valid` 和 `invalid-feedback` , `valid-feedback`, `waring-feedback` 来显示验证信息 ```html <template> <div> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" prepend="@" append="!" invalid-feedback="invalid" valid-feedback="valid" warning-feedback="warning" :valid="valid" /> <nly-form-group label="valid 表单状态" label-cols-xs="auto" class="mt-2"> <nly-form-select v-model="valid" :options="validOptinos" /> </nly-form-group> </div> </template> <script> export default { data() { return { valid: "novalid", validOptinos: [ { value: null, text: "Please select an option", disabled: true }, { value: "novalid", text: "不显示 feedback" }, { value: "invalid", text: "显示invalid feedback" }, { value: "valid", text: "显示 valid feedback" }, { value: "warning", text: "显示 warning feedback" } ] }; } }; </script> <!-- valid .name --> <!-- date-picker.vue --> ``` ## 日历的一些设置 - 使用 `opens` prop 来设置日历的位置, 可选 `center`, `left`, `right`, `inline` - 使用 `single-date-picker` prop 来选择日期选择器的选择模式,分为单个日期选择和范围日期选择,设置 `single-date-picker` prop 为 `true` 为范围日期选择, `false` 为 单个日期选择 - 设置 `show-week-numbers` prop 为 `true` 来显示日历上的周数,设置为 `false` 不显示 - 设置 `time-picker` prop 为 `true` 来显示时间选择器 - 设置 `time-picker24-hour` prop 为 `true` 来显示 24 小时制时间显示器,必须设置 `time-picker` prop 为 `true` 才有效 - 设置 `show-dropdowns` prop 为 `true` 来显示月份选择下拉框和年份快速输入 - 设置 `auto-apply` prop 为 `true` 来设置自动提交选择的时间 - 设置 `ranges` prop 为 `true` 来显示左侧快速选择时间 - 设置 `always-show-calendars` prop 为 `true` 来显示日历 - 设置 `append-to-body` prop 为 `true` 来把日历渲染到 body 尾部,不然渲染在输入框下面, **注意 `append-to-body` 为 `false` 时可能会影响布局,如果影响布局, 请设置 `append-to-body` 为 `true`** - 设置 `close-on-esc` prop 为 `true` 来支持键盘按键 <kbd>ESC</kbd> 退出日历 - 设置 `linked-calendars` prop 为 `true` 来使得两个日历联动 ```html <template> <div> <nly-form-daterangepicker :opens="opens" :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" :single-date-picker="singleDatePicker" :time-picker="timePicker" :time-picker24-hour="timePicker24Hour" :show-week-numbers="showWeekNumbers" :show-dropdowns="showDropdowns" :auto-apply="autoApply" v-model="dateRange" :ranges="show_ranges ? undefined : false" :linked-calendars="linkedCalendars" :always-show--calendars="alwaysShowCalendars" :append-to-body="appendToBody" :close-on-esc="closeOnEsc" /> <div> 日历布局 <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="options" id="option1" value="left" v-model="opens" /> <label class="form-check-label">left 左侧</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="options" id="option2" value="center" v-model="opens" /> <label class="form-check-label">center 居中</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="options" id="option3" value="right" v-model="opens" /> <label class="form-check-label">right 右侧</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="options" id="option4" value="inline" v-model="opens" /> <label class="form-check-label">inline 垂直</label> </div> <small class="form-text text-muted" >日历布局,可选左侧,居中,右侧,垂直,当为垂直的时候,无法关闭 </small> </div> <div> <div class="form-check form-inline py-3"> <label class="form-check-label" for="singleDatePicker"> single-date-picker 日历选择模式 </label> <select v-model="singleDatePicker" id="singleDatePicker" class="form-control ml-3" > <option :value="true">single 单个日期</option> <option :value="false">range 范围日期</option> <option :value="false">默认</option> </select> <small class="form-text text-muted" >单个日期只能选择一个日期,范围日期必须选择两个日期</small > </div> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="showWeekNumbers" v-model="showWeekNumbers" /> <label class="form-check-label" for="showWeekNumbers"> show-week-numbers 显示周数 </label> <small class="form-text text-muted"> 日历左侧显示整个日期对应的周数 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="timePicker" v-model="timePicker" /> <label class="form-check-label" for="timePicker"> time-picker 显示时间选择器 </label> <small class="form-text text-muted"> 允许选择时间 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="timePicker24Hour" v-model="timePicker24Hour" /> <label class="form-check-label" for="timePicker24Hour"> time-picker24-hour 24小时制时间选择器 </label> <small class="form-text text-muted"> 时间显示器转为24小时制 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="showDropdowns" v-model="showDropdowns" /> <label class="form-check-label" for="showDropdowns"> show-dropdowns 显示选择月份和输入年份 </label> <small class="form-text text-muted"> 允许 显示选择月份和输入年份 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="autoApply" v-model="autoApply" /> <label class="form-check-label" for="autoApply"> auto-apply 自动提交 </label> <small class="form-text text-muted"> 选择完日期之后,会自动提交选择的时间,并隐藏停止,提交按钮 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="show_ranges" v-model="show_ranges" /> <label class="form-check-label" for="show_ranges"> ranges 显示左侧最近时间 </label> <small class="form-text text-muted"> 可以显示左侧最近时间,比如上个月 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="alwaysShowCalendars" v-model="alwaysShowCalendars" /> <label class="form-check-label" for="alwaysShowCalendars"> always-show-calendars 显示日历 </label> <small class="form-text text-muted"> 设置为false 不显示日历,如果设置了rangs显示左侧最近时间,这个选项无效 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="appendToBody" v-model="appendToBody" /> <label class="form-check-label" for="appendToBody"> append-to-body 把日期选择器渲染到 body </label> <small class="form-text text-muted"> </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="closeOnEsc" v-model="closeOnEsc" /> <label class="form-check-label" for="closeOnEsc"> close-on-esc 按esc键退出 </label> </div> </div> </template> <script> export default { data() { return { dateRange: { startDate: "2019-12-10", endDate: "2019-12-20" }, single_range_picker: false, show_ranges: true, singleDatePicker: false, timePicker: true, timePicker24Hour: true, showDropdowns: true, autoApply: false, showWeekNumbers: true, linkedCalendars: true, alwaysShowCalendars: true, appendToBody: false, closeOnEsc: true, opens: "center" }; } }; </script> <!-- calendars .name --> <!-- date-picker.vue --> ``` ## 禁用日期选择器 使用 `disabled` prop 可以禁用日历选择时间,这时候点击并不会显示日期选择器 ```html <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" disabled /> <!-- disabled.name --> <!-- date-picker.vue --> ``` 可以使用 `date-format` prop 接受有个函数来设置禁止选择日期。给 `date-format` 函数的第一个参数 classes 添加一个 disabled 属性 ```html <template> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" :date-format="dateFormat" /> </template> <script> export default { methods: { dateFormat(classes, date) { if (!classes.disabled) { classes.disabled = date.getTime() < new Date(); } return classes; } } }; </script> <!-- dateFormat disabled.name --> <!-- date-picker.vue --> ``` ## 使用插槽 ### input 插槽 我们可以使用 input 插槽来使默认渲染的 input 输入框变成其他想渲染的任何组件。 **注意** - 如果影响布局, 请设置 `append-to-body` 为 `true` - 需要给渲染的组件绑定 `click` 事件为 `clickPicker` ```html <template> <div> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :append-to-body="true" > <template #input="picker" style="min-width: 350px;"> <nly-form-input :value='picker.startDate + "-" + picker.endDate' @click="picker.clickPicker" /> </template> </nly-form-daterangepicker> <nly-input-group> <nly-input :value="inputDate" /> <template v-slot:append> <nly-input-group-text> <nly-form-daterangepicker v-model="dateRange" :append-to-body="true"> <template #input="picker"> <nly-icon icon="far fa-calendar-alt" @click="picker.clickPicker" /> </template> </nly-form-daterangepicker> </nly-input-group-text> </template> </nly-input-group> </div> </template> <script> export default { data() { return { dateRange: { startDate: "2019-12-10", endDate: "2019-12-20" } }; }, computed: { inputDate() { const locale = this.dateRange.startDate + " - " + this.dateRange.endDate; return locale; } } }; </script> <!-- input 插槽.name --> <!-- date-picker.vue --> ``` ### header 插槽 我们可以使用 header 插槽来给日期选择器添加 header ```html <template> <div> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :append-to-body="true" > <div slot="header" slot-scope="header" :style='{"background-color": "#aaa", padding: "0.5rem", color: "white",display: "flex", "align-items": "center","justify-content": "space-between"}' > <h3>Calendar header</h3> <span v-if="header.in_selection"> - in selection</span> </div> </nly-form-daterangepicker> </div> </template> <script> export default { data() { return { dateRange: { startDate: "2019-12-10", endDate: "2019-12-20" } }; }, computed: { inputDate() { const locale = this.dateRange.startDate + " - " + this.dateRange.endDate; return locale; } } }; </script> <!-- header 插槽.name --> <!-- date-picker.vue --> ``` ### ranges 插槽 我们可以使用 ranges 插槽来自定义 ranges 的内容 ```html <template> <div> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :append-to-body="true" > <template #ranges="ranges"> <div class="ranges"> <ul> <li v-for="(range, name) in ranges.ranges" :key="name" @click="ranges.clickRange(range)" > <b>{{name}}</b> <small class="text-muted" >{{range[0].toDateString()}} - {{range[1].toDateString()}}</small > </li> </ul> </div> </template> </nly-form-daterangepicker> </div> </template> <script> export default { data() { return { dateRange: { startDate: "2019-12-10", endDate: "2019-12-20" } }; }, computed: { inputDate() { const locale = this.dateRange.startDate + " - " + this.dateRange.endDate; return locale; } } }; </script> <!-- ranges 插槽.name --> <!-- date-picker.vue --> ``` ### footer 插槽 我们可以使用 footer 插槽来自定义 foorer 的内容 ```html <template> <div> <nly-form-daterangepicker :value='{ startDate: "2019-12-10", endDate: "2019-12-20" }' :append-to-body="true" > <div slot="footer" slot-scope="data" :style='{"background-color": "#aaa", padding: "0.5rem", color: "white",display: "flex", "align-items": "center","justify-content": "space-between"}' > <div><b class="text-black">Calendar footer</b> {{data.rangeText}}</div> <div style="margin-left: auto"> <a @click="data.clickApply" v-if="!data.in_selection" class="btn btn-primary btn-sm" >Choose current</a > </div> </div> </nly-form-daterangepicker> </div> </template> <script> export default { data() { return { dateRange: { startDate: "2019-12-10", endDate: "2019-12-20" } }; }, computed: { inputDate() { const locale = this.dateRange.startDate + " - " + this.dateRange.endDate; return locale; } } }; </script> <!-- footer 插槽.name --> <!-- date-picker.vue --> ``` ## 可以在其他任何地方打开日期选择器 使用 `this.$refs.pickerRefName.togglePicker(true/false)` 可以在其他元素上点击打开日期选择器 ## 完整 demo 这是一个完整的 demo ,差不多包括所有 prop 值的切换 ```html <template> <nly-container> <nly-row> <nly-col> <nly-form-group label="data picker" label-size="lg" label-class="font-weight-bold pt-0" class="mb-0" > <nly-form-daterangepicker ref="picker" :opens="opens" :locale-data="{ firstDay: 1, format: 'yyyy-mm-dd HH:MM:ss' }" :minDate="minDate" :maxDate="maxDate" :singleDatePicker="singleDatePicker" :timePicker="timePicker" :timePicker24Hour="timePicker24Hour" :showWeekNumbers="showWeekNumbers" :showDropdowns="showDropdowns" :autoApply="autoApply" v-model="dateRange" :ranges="show_ranges ? undefined : false" @update="updateValues" @toggle="checkOpen" :dateFormat="setDateFormat" :linkedCalendars="linkedCalendars" :alwaysShowCalendars="alwaysShowCalendars" :append-to-body="appendToBody" :closeOnEsc="closeOnEsc" :prepend="prepend" :append="append" :valid="valid" invalid-feedback="我是invalid" valid-feedback="我是valid" warning-feedback="我是warning" size="sm" /> </nly-form-group> </nly-col> </nly-row> <div class="form-row pt-3 bg-light"> <div class="col-md-6"> <div class="form-group row"> <label class="col-sm-4 col-form-label" for="startDate" >startDate 开始日期</label > <div class="col-sm-8"> <input type="text" class="form-control" id="startDate" v-model="dateRange.startDate" /> </div> </div> <div class="form-group row"> <label class="col-sm-4 col-form-label" for="endDate" >endDate 结束日期</label > <div class="col-sm-8"> <input type="text" class="form-control" id="endDate" v-model="dateRange.endDate" /> </div> </div> </div> <div class="col-md-6"> <div class="form-group row"> <label class="col-sm-4 col-form-label" for="minDate" >minDate 日历可选择最小日期</label > <div class="col-sm-8"> <input type="text" class="form-control" id="minDate" v-model="minDate" /> </div> </div> <div class="form-group row"> <label class="col-sm-4 col-form-label" for="maxDate" >maxDate 日历可选择最大日期</label > <div class="col-sm-8"> <input type="text" class="form-control" id="maxDate" v-model="maxDate" /> </div> </div> </div> </div> <div> 日历布局 <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="options" id="option1" value="left" v-model="opens" /> <label class="form-check-label">left 左侧</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="options" id="option2" value="center" v-model="opens" /> <label class="form-check-label">center 居中</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="options" id="option3" value="right" v-model="opens" /> <label class="form-check-label">right 右侧</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="options" id="option4" value="inline" v-model="opens" /> <label class="form-check-label">inline 垂直</label> </div> <small class="form-text text-muted" >日历布局,可选左侧,居中,右侧,垂直,当为垂直的时候,无法关闭 </small> </div> <div> <div class="form-check form-inline py-3"> <label class="form-check-label" for="singleDatePicker"> single-date-picker 日历选择模式 </label> <select v-model="singleDatePicker" id="singleDatePicker" class="form-control ml-3" > <option>single 单个日期</option> <option>range 范围日期</option> <option :value="false">默认</option> </select> <small class="form-text text-muted" >单个日期只能选择一个日期,范围日期必须选择两个日期</small > </div> <!-- prepend="@@" append="!" valid="invalid" invalid-feedback="我是invalid" valid-feedback="我是valid" warning-feedback="我是warning" size="sm" --> <nly-form-group label="prepend 输入框前面图标" label-cols-xs="auto"> <nly-form-input v-model="prepend" size="sm" /> </nly-form-group> <nly-form-group label="append 输入框前面图标" label-cols-xs="auto"> <nly-form-input v-model="append" size="sm" /> </nly-form-group> <nly-form-group label="valid 表单状态" label-cols-xs="auto"> <nly-form-select v-model="valid" :options="validOptinos" /> </nly-form-group> <div class="form-check"> <input class="form-check-input" type="checkbox" id="showWeekNumbers" v-model="showWeekNumbers" /> <label class="form-check-label" for="showWeekNumbers"> show-week-numbers 显示周数 </label> <small class="form-text text-muted"> 日历左侧显示整个日期对应的周数 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="timePicker" v-model="timePicker" /> <label class="form-check-label" for="timePicker"> time-picker 显示时间选择器 </label> <small class="form-text text-muted"> 允许选择时间 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="timePicker24Hour" v-model="timePicker24Hour" /> <label class="form-check-label" for="timePicker24Hour"> time-picker24-hour 24小时制时间选择器 </label> <small class="form-text text-muted"> 时间显示器转为24小时制 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="showDropdowns" v-model="showDropdowns" /> <label class="form-check-label" for="showDropdowns"> show-dropdowns 显示选择月份和输入年份 </label> <small class="form-text text-muted"> 允许 显示选择月份和输入年份 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="autoApply" v-model="autoApply" /> <label class="form-check-label" for="autoApply"> auto-apply 自动提交 </label> <small class="form-text text-muted"> 选择完日期之后,会自动提交选择的时间,并隐藏停止,提交按钮 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="show_ranges" v-model="show_ranges" /> <label class="form-check-label" for="show_ranges"> ranges 显示左侧最近时间 </label> <small class="form-text text-muted"> 可以显示左侧最近时间,比如上个月 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="alwaysShowCalendars" v-model="alwaysShowCalendars" /> <label class="form-check-label" for="alwaysShowCalendars"> always-show-calendars 显示日历 </label> <small class="form-text text-muted"> 设置为false 不显示日历,如果设置了rangs显示左侧最近时间,这个选项无效 </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="appendToBody" v-model="appendToBody" /> <label class="form-check-label" for="appendToBody"> append-to-body 把日期选择器渲染到 body </label> <small class="form-text text-muted"> </small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" id="closeOnEsc" v-model="closeOnEsc" /> <label class="form-check-label" for="closeOnEsc"> close-on-esc 按esc键退出 </label> </div> </div> </nly-container> </template> <script> export default { name: "", filters: { date(value) { if (!value) return ""; let options = { year: "numeric", month: "long", day: "numeric" }; return Intl.DateTimeFormat("en-US", options).format(value); } }, data() { // :locale-data="{ daysOfWeek: [ 'Нд', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб' ] }" return { sss: "", opens: "center", minDate: "2019-05-02 04:00:00", maxDate: "2020-12-26 14:00:00", // minDate: '', // maxDate: '', dateRange: { startDate: "2019-12-10", endDate: "2019-12-20" }, single_range_picker: false, show_ranges: true, singleDatePicker: false, timePicker: true, timePicker24Hour: true, showDropdowns: true, autoApply: false, showWeekNumbers: true, linkedCalendars: true, alwaysShowCalendars: true, appendToBody: false, closeOnEsc: true, dateUtil: undefined, dateFormat: undefined, prepend: "@", append: "!", valid: "novalid", validOptinos: [ { value: null, text: "Please select an option", disabled: true }, { value: "novalid", text: "不显示 feedback" }, { value: "invalid", text: "显示invalid feedback" }, { value: "valid", text: "显示 valid feedback" }, { value: "warning", text: "显示 warning feedback" } ] }; }, mounted() { this.dateFormat = (function() { var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZWN]|"[^"]*"|'[^']*'/g; var timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g; var timezoneClip = /[^-+\dA-Z]/g; // Regexes and supporting functions are cached through closure return function(date, mask, utc, gmt) { // You can't provide utc if you skip other args (use the 'UTC:' mask prefix) if ( arguments.length === 1 && this.kindOf(date) === "string" && !/\d/.test(date) ) { mask = date; date = undefined; } date = date || new Date(); if (!(date instanceof Date)) { date = new Date(date); } if (isNaN(date)) { throw TypeError("Invalid date"); } mask = String( this.dateFormat.masks[mask] || mask || this.dateFormat.masks["default"] ); // Allow setting the utc/gmt argument via the mask var maskSlice = mask.slice(0, 4); if (maskSlice === "UTC:" || maskSlice === "GMT:") { mask = mask.slice(4); utc = true; if (maskSlice === "GMT:") { gmt = true; } } var _ = utc ? "getUTC" : "get"; var d = date[_ + "Date"](); var D = date[_ + "Day"](); var m = date[_ + "Month"](); var y = date[_ + "FullYear"](); var H = date[_ + "Hours"](); var M = date[_ + "Minutes"](); var s = date[_ + "Seconds"](); var L = date[_ + "Milliseconds"](); var o = utc ? 0 : date.getTimezoneOffset(); var W = this.getWeek(date); var N = this.getDayOfWeek(date); var flags = { d: d, dd: this.pad(d), ddd: this.dateFormat.i18n.dayNames[D], dddd: this.dateFormat.i18n.dayNames[D + 7], m: m + 1, mm: this.pad(m + 1), mmm: this.dateFormat.i18n.monthNames[m], mmmm: this.dateFormat.i18n.monthNames[m + 12], yy: String(y).slice(2), yyyy: y, h: H % 12 || 12, hh: this.pad(H % 12 || 12), H: H, HH: this.pad(H), M: M, MM: this.pad(M), s: s, ss: this.pad(s), l: this.pad(L, 3), L: this.pad(Math.round(L / 10)), t: H < 12 ? this.dateFormat.i18n.timeNames[0] : this.dateFormat.i18n.timeNames[1], tt: H < 12 ? this.dateFormat.i18n.timeNames[2] : this.dateFormat.i18n.timeNames[3], T: H < 12 ? this.dateFormat.i18n.timeNames[4] : this.dateFormat.i18n.timeNames[5], TT: H < 12 ? this.dateFormat.i18n.timeNames[6] : this.dateFormat.i18n.timeNames[7], Z: gmt ? "GMT" : utc ? "UTC" : (String(date).match(timezone) || [""]) .pop() .replace(timezoneClip, ""), o: (o > 0 ? "-" : "+") + this.pad( Math.floor(Math.abs(o) / 60) * 100 + (Math.abs(o) % 60), 4 ), S: ["th", "st", "nd", "rd"][ d % 10 > 3 ? 0 : (((d % 100) - (d % 10) != 10) * d) % 10 ], W: W, N: N }; return mask.replace(token, function(match) { if (match in flags) { return flags[match]; } return match.slice(1, match.length - 1); }); }; })(); this.dateFormat.masks = { default: "ddd mmm dd yyyy HH:MM:ss", shortDate: "m/d/yy", mediumDate: "mmm d, yyyy", longDate: "mmmm d, yyyy", fullDate: "dddd, mmmm d, yyyy", shortTime: "h:MM TT", mediumTime: "h:MM:ss TT", longTime: "h:MM:ss TT Z", isoDate: "yyyy-mm-dd", isoTime: "HH:MM:ss", isoDateTime: "yyyy-mm-dd'T'HH:MM:sso", isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'", expiresHeaderFormat: "ddd, dd mmm yyyy HH:MM:ss Z" }; // Internationalization strings this.dateFormat.i18n = { dayNames: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], monthNames: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], timeNames: ["a", "p", "am", "pm", "A", "P", "AM", "PM"] }; this.dateUtil = { isSame: (date1, date2, granularity) => { let dt1 = new Date(date1); let dt2 = new Date(date2); if (granularity === "date") { dt1.setHours(0, 0, 0, 0); dt2.setHours(0, 0, 0, 0); } return dt1.getTime() === dt2.getTime(); }, daysInMonth: (year, month) => { return new Date(year, month, 0).getDate(); }, weekNumber: date => { return this.getWeek(date); }, format: (date, mask) => { return this.dateFormat(date, mask); }, nextMonth: date => { let nextMonthDate = new Date(date.getTime()); nextMonthDate.setDate(1); nextMonthDate.setMonth(nextMonthDate.getMonth() + 1); return nextMonthDate; }, prevMonth: date => { let prevMonthDate = new Date(date.getTime()); prevMonthDate.setDate(1); prevMonthDate.setMonth(prevMonthDate.getMonth() - 1); return prevMonthDate; }, validateDateRange: (newDate, min, max) => { let max_date = new Date(max); let min_date = new Date(min); if (max && newDate.getTime() > max_date.getTime()) { return max_date; } if (min && newDate.getTime() < min_date.getTime()) { return min_date; } return newDate; }, localeData: options => { let default_locale = { direction: "ltr", format: "mm/dd/yyyy", separator: " - ", applyLabel: "Apply", cancelLabel: "Cancel", weekLabel: "W", customRangeLabel: "Custom Range", daysOfWeek: this.dateFormat.i18n.dayNames .slice(0, 7) .map(d => d.substring(0, 2)), monthNames: this.dateFormat.i18n.monthNames.slice(0, 12), firstDay: 0 }; return { ...default_locale, ...options }; }, yearMonth: date => { let month = date.getMonth() + 1; return date.getFullYear() + (month < 10 ? "0" : "") + month; }, isValidDate: d => { return d instanceof Date && !isNaN(d); } }; }, methods: { pad(val, len) { val = String(val); len = len || 2; while (val.length < len) { val = "0" + val; } return val; }, getWeek(date) { var targetThursday = new Date( date.getFullYear(), date.getMonth(), date.getDate() ); targetThursday.setDate( targetThursday.getDate() - ((targetThursday.getDay() + 6) % 7) + 3 ); var firstThursday = new Date(targetThursday.getFullYear(), 0, 4); firstThursday.setDate( firstThursday.getDate() - ((firstThursday.getDay() + 6) % 7) + 3 ); var ds = targetThursday.getTimezoneOffset() - firstThursday.getTimezoneOffset(); targetThursday.setHours(targetThursday.getHours() - ds); var weekDiff = (targetThursday - firstThursday) / (86400000 * 7); return 1 + Math.floor(weekDiff); }, updateValues(values) { this.dateRange.startDate = this.dateUtil.format( values.startDate, "yyyy-mm-dd HH:MM:ss" ); this.dateRange.endDate = this.dateUtil.format( values.endDate, "yyyy-mm-dd HH:MM:ss" ); }, getDayOfWeek(date) { var dow = date.getDay(); if (dow === 0) { dow = 7; } return dow; }, kindOf(val) { if (val === null) { return "null"; } if (val === undefined) { return "undefined"; } if (typeof val !== "object") { return typeof val; } if (Array.isArray(val)) { return "array"; } return {}.toString .call(val) .slice(8, -1) .toLowerCase(); }, checkOpen(open) { console.log("event: open", open); }, setDateFormat(classes, date) { let yesterday = new Date(); let d1 = this.dateUtil.format(date, "isoDate"); let d2 = this.dateUtil.format( yesterday.setDate(yesterday.getDate() - 1), "isoDate" ); if (!classes.disabled) { classes.disabled = d1 === d2; } return classes; } } }; </script> <!-- demo.name --> <!-- date-picker.vue --> ```