效果

需求

1、实现一个日历组件,如图:

2、显示某天的事项:

3、事项是模拟父组件请求接口返回的,数据格式如下:

[
{
id: '232',
date: '2019-06-01',
info: '我要去吃大餐'
},
{
id: '292',
date: '2019-06-06',
info: '我要去吃大餐'
},
{
id: '292',
date: '2019-06-07',
info: '我要去吃大餐'
},
{
id: '369',
date: '2019-06-30',
info: '我要去吃大餐'
}
]

4、把事项添加到日历组件中,数据格式如下:

代码解析

父组件页面:

<template>
<div class="test-container">
<h1>Test页面,测试组件</h1>
<!-- 日历 -->
<calendar v-if="calendarVisible" @getDateInfo="getDateInfo" :propsInfoList="propsInfoList" :propsTime="propsTime"></calendar>
</div>
</template> <script>
import calendar from '@/components/Calendar/Calendar.vue'
export default {
name: 'test',
components: {
"calendar": calendar
},
data() {
return {
calendarVisible: true,
propsTime: '',
propsInfoList: '',
middle: [
{
id: '232',
date: '2019-06-01',
info: '我要去吃大餐'
},
{
id: '292',
date: '2019-06-06',
info: '我要去吃大餐'
},
{
id: '292',
date: '2019-06-07',
info: '我要去吃大餐'
},
{
id: '369',
date: '2019-06-30',
info: '我要去吃大餐'
}
]
}
},
created() {
this.propsInfoList = JSON.stringify(this.middle)
this.propsTime = this.getToday()
},
mounted() {
window.alert('测试时间为19年 5、6、7月,完成是在6月')
},
methods: {
// 格式化当前日期 YYYY-MM-DD
getToday() {
let nowDate = new Date()
let yy = nowDate.getFullYear().toString()
let mm = (nowDate.getMonth() + 1 + '').padStart(2,'0')
let dd = (nowDate.getDate() + '').padStart(2,'0')
// let hh = nowDate.getHours().toString().padStart(2,'0')
// let mt = (nowDate.getMinutes() + '').padStart(2,'0')
// let ss = (nowDate.getSeconds() + '').padStart(2,'0')
return `${yy}-${mm}-${dd}` // -${hh}-${mt}-${ss}
},
// 组件传值
getDateInfo(year, month) {
let _this = this
_this.propsTime = `${year}-${month}`
_this.calendarVisible = false
setTimeout(() => {
_this.propsInfoList = []
let middle
if(month == '05') {
middle = [
{
id: '232',
date: '2019-05-10',
info: '我要去吃小餐'
}
]
} else if (month == '06') {
middle = _this.middle
} else if (month == '07') {
middle = [
{
id: '232',
date: '2019-07-10',
info: '我要去吃小餐'
}
]
} else {
middle = ''
}
_this.propsInfoList = JSON.stringify(middle)
_this.calendarVisible = true
}, 100)
}
}
}
</script>

日历子组件:

<template>
<div class="calendar-container">
<h1>calendar</h1>
<div class="show-date" @click="clickData">{{showDate}}</div>
<div class="now-time">今日:{{exactTime}}</div>
<div class="calendar">
<ul class="calendar-header">
<li>日</li>
<li>一</li>
<li>二</li>
<li>三</li>
<li>四</li>
<li>五</li>
<li>六</li>
</ul>
<ul class="calendar-body">
<li class="calendar-row" v-for="(item, index) in JSON.parse(calendarData)" :key="index">
<span v-for="(subItem, subIndex) in item" :class="[subIndex == 0 || subIndex == 6? 'weekend': 'weekday', subItem.type == '1'? 'exact-time': '', subItem.type == '0'? 'already-time': '', subItem.type == '2'? 'soon-time': '']" @click="showInfo(subItem)" :key="subIndex">
{{subItem.date}}
</span>
</li>
</ul>
</div>
<mt-popup v-model="popupVisible" position="bottom">
<mt-picker :slots="slots" :showToolbar="true" :visibleItemCount="5" :itemHeight="itemsHeight" ref="picker">
<img src="@/assets/images/picker_cancel.png" class="picker_cancel" v-on:click="cancelFunc()">
<img src ="@/assets/images/picker_sure.png" class="picker_sure" v-on:click="sureFunc()">
</mt-picker>
</mt-popup>
</div>
</template>

日历子组件逻辑:

import { MessageBox } from 'mint-ui'
export default {
name: "calendar",
props: {
propsTime: String,
propsInfoList: String
},
data() {
return {
time: '',
infoList: '',
calendarData: [],
showDate: '',
exactTime: '',
itemsHeight: 95 * window.screen.height / 1334,
popupVisible: false,
slots: []
}
},
created() {
this.infoList = this.propsInfoList
this.time = this.propsTime.split('-')
const date = this.getToday()
this.exactTime = date.slice(0,3).join('-')
this.getCalendar(...(this.time))
this.getSlotsArray(...(date.slice(0,2)))
},
methods: {
// 日历组件
getCalendar(year, month) {
let _this = this
const rightNow = _this.exactTime
_this.showDate = `${year}-${month
const firstDate = new Date(year, month - 1, 1)
const firstDay = firstDate.getDay()
const isLeapYear = year % 100 == 0? year % 400 == 0? 1: 0: year % 4 == 0 ? 1: 0
const monthArray = [31, 28 + isLeapYear, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
const weeekLines =Math.ceil((monthArray[month - 1] + firstDay)/7)
let calendar = []
for(let i = 0; i < weeekLines; i++) {
let weeekLinesInfo = []
for(let j = 0; j < 7; j++) {
const cellNo = i * 7 + j
const datePerLine = cellNo - firstDay + 1
if(datePerLine <= 0 || datePerLine > monthArray[month - 1]) {
let outOfMonth = {
"type" : 'null',
"date" : ''
}
weeekLinesInfo[j] = outOfMonth
} else {
let day = (datePerLine + '').padStart(2,'0')
let inOfMonth = {
"type" : '',
"date" : day,
"isDone": '',
"infor": ''
}
const propsDate = `${year}-${month}-${day}`
if(propsDate == rightNow){
inOfMonth.type = "1"
}
const reservations = JSON.parse(_this.infoList)
for(let k = 0; k < reservations.length; k++) {
if(propsDate == reservations[k].date){
// inOfMonth.type = "1"
inOfMonth.infor = reservations[k].info
if(rightNow == reservations[k].date) {
inOfMonth.type = "1"
inOfMonth.isDone = "doing"
} else if (rightNow > reservations[k].date) {
inOfMonth.type = "0"
inOfMonth.isDone = "pass"
} else if (rightNow < reservations[k].date) {
inOfMonth.type = "2"
inOfMonth.isDone = "will"
}
}
}
weeekLinesInfo[j] = inOfMonth
}
}
calendar.push(weeekLinesInfo)
}
window.console.log(calendar)
_this.calendarData = JSON.stringify(calendar)
},
// 格式化当前日期 YYYY-MM-DD
getToday() {
let nowDate = new Date()
let yy = nowDate.getFullYear().toString()
let mm = (nowDate.getMonth() + 1 + '').padStart(2,'0')
let dd = (nowDate.getDate() + '').padStart(2,'0')
let hh = nowDate.getHours().toString().padStart(2,'0')
let mt = (nowDate.getMinutes() + '').padStart(2,'0')
let ss = (nowDate.getSeconds() + '').padStart(2,'0')
return [yy, mm, dd, hh, mt, ss]
// return `${yy}-${mm}-${dd}-${hh}-${mt}-${ss}`
},
// 组装 picker 数组
getSlotsArray(year, month){
let _this = this
let yearArray = []
for(let i = -10 ; i <= 10 ; i ++){
yearArray.push(year - 1 + i)
}
let monthArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
let slots = [
{
values:yearArray,
className:"slot1",
defaultIndex: 11
},
{
values:monthArray,
className:"slot2",
defaultIndex:month - 1
}
]
_this.slots = slots
},
// 显示日期弹窗
clickData(){
this.popupVisible = true
},
// 取消按钮
cancelFunc(){
this.popupVisible = false;
},
// 确认按钮
sureFunc() {
let _this = this
_this.popupVisible = false
const clickData = _this.$refs.picker.getValues()
const year = clickData[0] + ''
const month = (clickData[1] + '').padStart(2,'0')
const day = _this.time[2]
_this.getDateInfo(year, month)
_this.getCalendar(year, month)
},
// 调用父组件定义的方法
getDateInfo(year, month) {
this.$emit('getDateInfo', year, month)
},
// 点击展示某天的事项信息
showInfo(info) {
let _this = this
const infor = info
if(infor.infor) {
const [year, month] = _this.showDate.split('-')
console.log(year, month, info)
const titleDate = `${year}-${month}-${info.date}`
const preview = info.infor
MessageBox({
title: titleDate,
message: preview,
showCancelButton: false,
closeOnClickModal: true
})
}
}
}
}

其他:为了减少篇幅,省略样式

github地址

Vue.js(19)之 封装calendar组件的更多相关文章

  1. 每天记录一点:NetCore获得配置文件 appsettings.json vue-router页面传值及接收值 详解webpack + vue + node 打造单页面(入门篇) 30分钟手把手教你学webpack实战 vue.js+webpack模块管理及组件开发

    每天记录一点:NetCore获得配置文件 appsettings.json   用NetCore做项目如果用EF  ORM在网上有很多的配置连接字符串,读取以及使用方法 由于很多朋友用的其他ORM如S ...

  2. vue.js入门(3)——组件通信

    5.2 组件通信 尽管子组件可以用this.$parent访问它的父组件及其父链上任意的实例,不过子组件应当避免直接依赖父组件的数据,尽量显式地使用 props 传递数据.另外,在子组件中修改父组件的 ...

  3. Vue.js 3.x 中跨层级组件如何传递数据?

    provide/inject 基本用法 在 Vue.js 中,跨层级组件如果想要传递数据,我们可以直接使用 props 来将祖先组件的数据传递给子孙组件: 注:上图来自 Vue.js 官网:Prop ...

  4. Vue.js 2.x笔记:组件(5)

    1. 组件简介 组件(Component)是 Vue.js 最强大的功能之一,组件可以扩展 HTML 元素,封装可重用的代码. 组件:为了拆分Vue实例的代码量,以不同的组件来划分不同的功能模块,需要 ...

  5. vue.js基础知识篇(6):组件详解

    第11章:组件详解 组件是Vue.js最推崇也最强大的功能之一,核心目标是可重用性. 我们把组件代码按照template.style.script的拆分方式,放置到对应的.vue文件中. 1.注册 V ...

  6. vue.js 二维码生成组件

    安装 通过NPM安装 npm install vue-qart --save 插件应用 将vue-qart引入你的应用 import VueQArt from 'vue-qart' new Vue({ ...

  7. Vue.js 系列教程 2:组件,Props,Slots

    原文:intro-to-vue-2-components-props-slots 译者:nzbin 这是关于 JavaScript 框架 Vue.js 五个教程的第二部分.在这一部分,我们将学习组件, ...

  8. Vue.js 3 Step 创建一个组件

    Step1:Vue.extend()创建组件 Step2:Vue.component()注册组件,注册的标签一定要用小写 Step3:挂载点使用组件 <!doctype html> < ...

  9. Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

    基于vue.js开发的小巧PC端自定义滚动条组件VScroll. 前段时间有给大家分享一个vue桌面端弹框组件,今天再分享最近开发的一个vue pc端自定义滚动条组件. vscroll 一款基于vue ...

随机推荐

  1. 图的Prim,Kruskal,Dijkstra,Floyd算法

    代码部分有点问题,具体算法没问题, 最近期末考,要过段时间才会修改 //邻接矩阵,具体情况看上一篇的图的实现template<class T>class MGraph {public:   ...

  2. 三 进制、精度,Java的类型转换

    进制的表示: 0b010 :  二进制表示形式:前面+0n 0100  : 八进制表示形式: 前面+0 0x001 : 16进制表示形式:前面+0x 计算机以补码的方式进行运算 进制的转换: 10进制 ...

  3. ffmpeg 学习:002-代码架构

    前言 使用 ffmpeg 库时,最好先理解好ffmpeg的代码结构图. 下面这张图表明了FFmpeg在解码一个视频的时候的函数调用流程,为了保证结构清晰,其中仅列出了最关键的函数,剔除了其它不是特别重 ...

  4. XtraReport1添加参数

    解决了在report有个BeforePrint事件这里面直接 C# code   ? 1 string year = this.Parameters["year"].Value.T ...

  5. Console-terminal-tty-shell-kernel

    Console-terminal-tty-shell-kernel 1. 先看图表     1.1 简表     1.2 shell与内核的示意图     1.3 Console-terminal-t ...

  6. Windows使用Nexus搭建Maven私服

    简介 Maven私服是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构件,有了私服之后,当 Maven 需要下载构件时,直接请求私服,私服上存在则下载到本地仓库,否则,私服请求外部的 ...

  7. python反序列化漏洞

    原理在网页源码中如果出现将用户输入数据进行反序列化当成参数输出时,出现漏洞,可造成任意命令执行例如网页源码try:       become = self.get_argument('become') ...

  8. 【转】Spark Streaming 实时计算在甜橙金融监控系统中的应用及优化

    系统架构介绍 整个实时监控系统的架构是先由 Flume 收集服务器产生的日志 Log 和前端埋点数据, 然后实时把这些信息发送到 Kafka 分布式发布订阅消息系统,接着由 Spark Streami ...

  9. 吴裕雄--天生自然java开发常用类库学习笔记:集合工具类Collections

    import java.util.Collections ; import java.util.List ; import java.util.Set ; public class Collectio ...

  10. POJ 3468 区间更新(求任意区间和)A Simple Problem with Integers

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 163977 ...