ant日历组件calendar转中文以及消息渲染

61 篇文章 1 订阅
52 篇文章 2 订阅

1.背景

目前使用的项目用的是ice+ant+react ,项目中使用了calendar组件,但是组件中的星期,年份,月份都是英文的,按照官网的配置了转中文没有起作用。

转换后的效果:
在这里插入图片描述

2、手动转换

由于官网的配置没有生效,所以使用了一个最直接的方案:直接替换英文的dom节点的内容为中文的。

注意!这里加入了完整的日历消息展示,消息从接口中获得,返回的是日历面板上每一天的消息信息,然后展示在日历中,如果只是需要转中文,则只需要看转中文的几个方法。最终的效果,可以直接在每天卡片上显示消息,也可以悬浮显示每天的消息。

import { useEffect, useState } from 'react'
import { useHistory } from 'react-router'
import { Calendar, Tooltip, Button } from 'antd'
import './style.less'

// 配置路由跳转数据
const pathArr = [
  '/Dongjiangao/person-manage/personal-manage',
  '/Dongjiangao/first-company/list',
  '/Dongjiangao/second-company/list',
]
function App(props) {
  const { api } = props
  const history: any = useHistory()
  const [dateArr, setDateArr]: any = useState([]) //存储每月的所有天数
  const [complateData, setComplateData]: any = useState(false) //标识数据渲染是否组装完成
  const [showTip, setShowTip] = useState(true) //是否悬浮显示消息

  useEffect(() => {
    // 初始化时转换显示的星期,月份,并且监听月份的滚动事件,滚动时替换英文为中文
    translateAllInit()
    // 初始化时转换已选中的月份
    translateMouthSelected()
  }, [])

  useEffect(() => {
    if (dateArr.length == 42) {
      setTimeout(() => {
       // dateArr在拼装数据的时候会重复添加,导致超出42个,所以需要裁剪
       let arrCurrent = dateArr.slice(dateArr.length - 42) //当月的日期数组
       api({
          startTime: arrCurrent[0],
          endTime: arrCurrent[41],
        })
          .then((res) => {
            setDateArr(res.data || [])
            // 数据获取完成
            setComplateData(true)
          })
          .catch((err) => {})
      }, 0)
    }
  }, [dateArr])

const translateAllInit = () => {
    // 1·设置【年月】日期按钮不显示
    document.getElementsByClassName('ant-radio-group')[0].style.display = 'none'
    
    // 2.转换星期的中英文
    document
      .getElementsByClassName('calendar-card-area')[0]
      .getElementsByTagName('thead')[0].innerHTML =
      `<tr><th>周日</th><th>周一</th><th>周二</th><th>周三</th><th>周四</th><th>周五</th><th>周六</th></tr>`
      
    // 3.转换月份的中英文
    //获取元素
    let mouthBtn: any = document.querySelector(
      `.ant-picker-calendar-month-select`
    )
   //监听月份下拉框展开事件
    mouthBtn.addEventListener('click', function () {
      // 3.1 转换展开时显示的月份
      getMouthListZh()
      // 3.2 转换滚动时显示的月份
      /**
      监听月份虚拟滚动:因为初始时下拉框不会展示全部月份的dom,
      也就无法依靠上面展开监听去替换所有的月份,
      只能滚动的时候实时拿到月份dom去转换中英文
      */
      let virtualbBtn = document.querySelector(`.rc-virtual-list-holder`)
      virtualbBtn &&
        virtualbBtn.addEventListener('scroll', function () {
          getMouthListZh()
        })
    })
  }

 // 转换月份下拉框的月份文字
  const getMouthListZh = () => {
    let arrNode: any = []
    arrNode = document
      .getElementsByClassName('calendar-card-area')[0]
      .getElementsByClassName('ant-select-item-option-content')
      
     for (let i = 0; i < arrNode.length; i++) {
      let oldText = arrNode[i].innerText
      arrNode[i].innerText = translateMouth(oldText)
    }
  }

 // 转换所有月份的文案
  const translateMouth = (oldText) => {
    let newText = ''
    // 如果是英文的才需要转
    if (!oldText.includes('月')) {
      switch (oldText) {
        case 'Jan':
          newText = '1月'
          break
        case 'Feb':
          newText = '2月'
          break
        case 'Mar':
          newText = '3月'
          break
        case 'Apr':
          newText = '4月'
          break
        case 'May':
          newText = '5月'
          break
        case 'Jun':
          newText = '6月'
          break
       case 'Jul':
          newText = '7月'
          break
        case 'Aug':
          newText = '8月'
          break
        case 'Sep':
          newText = '9月'
          break
        case 'Oct':
          newText = '10月'
          break
        case 'Nov':
          newText = '11月'
          break
        case 'Dec':
          newText = '12月'
          break
        default:
          break
      }
    } else {
      newText = oldText
    }
    return newText
  }

 // 转换已选中月份的中英文
  const translateMouthSelected = () => {
    let mouthText = document
      .getElementsByClassName('calendar-card-area')[0]
      .getElementsByClassName('ant-select-selection-item')[1].innerText

    if (mouthText) {
      document
        .getElementsByClassName('calendar-card-area')[0]
        .getElementsByClassName('ant-select-selection-item')[1].innerText =
       translateMouth(mouthText)
    }
  }

  // 路由跳转
  const goRouter = (path, routerKey: any, val: any) => {
    history.push({
      pathname: path,
      query: routerKey ? { [routerKey]: val, timeAll: 1 } : '',
    })
  }


  // 	自定义渲染日期单元格,返回内容会被追加到单元格
  function dateCellRender(value, s) {
    let formatVal = value.format('YYYY-MM-DD') //用来匹配获取的数据
    // 后触发
    dateArr.push(formatVal)
    setDateArr(dateArr)
    if (complateData) {
      let CopyDateArr = JSON.parse(JSON.stringify(dateArr))
      CopyDateArr = CopyDateArr.slice(0, 42) //渲染的对象
      let renderObj = CopyDateArr.filter((item) => item.datetime == formatVal)?.[0] || {}
      // 直接展示在日历卡片上的节点
      function openNode() {
        return (
          (renderObj.firstNumber ||
           renderObj.secondaryNumber ||
            renderObj.personnelNumber) && (
            <div className="calendar-tooltip">
              <div className="calendar-text-item">
               <div className="cicle-color-red"></div>
                <a
                  className="calendar-text-num"
                  onClick={() => {
                    goRouter(pathArr[1], '', '')
                    }}
                >
                  {renderObj.firstNumber}
                </a>
              </div>
              <div className="calendar-text-item">
                <div className="cicle-color-blue"></div>
                <a
                  className="calendar-text-num"
                  onClick={() => {
                    goRouter(pathArr[2], '', '')
                  }}
                >
                  {renderObj.secondaryNumber}
                </a>
              </div>
              <div className="calendar-text-item">
                <div className="cicle-color-green"></div>
                <a
                  className="calendar-text-num"
                   onClick={() => {
                    goRouter(pathArr[0], 'personAddTime', formatVal)
                  }}
                >
                {renderObj.personnelNumber}
                </a>
              </div>
            </div>
          )
        )
      }
      // 悬浮显示的节点
      function hoverNode() {
        return (
          <div className="calendar-tooltip">
            <div className="calendar-text-item calendar-text-item-hover">
               <div className="calendar-label">新增一级企业数量:</div>
               <a
                className="calendar-text-num"
                onClick={() => {
                  goRouter(pathArr[1], '', '')
                }}
              >
                {renderObj.firstNumber}
              </a>
            </div>
          </div>
        )
      }
       let tipsNode = (
        <Tooltip
          title={hoverNode()}
          color={'#ddd'}
          overlayStyle={{ width: '220px' }}
        >
                 <div style={{ opacity: 0 }}>悬浮显示消息详情</div>
        </Tooltip>
      )
      return showTip ? tipsNode : openNode()
    }
  }

 const onChange = async (value) => {
    // 4.转换已选中的月份中英文
    setTimeout(() => {
      translateMouthSelected()
    }, 0)
    // 先触发
    setDateArr([])
  }

return (
    <>
      <div className="calendar-content">
        <Button
          className="calendar-action-btn"
          onClick={() => {
            setShowTip(!showTip)
          }}
         >
          {showTip ? '展示' : '悬浮'}日历消息
        </Button>
      </div>
      <Calendar
        dateCellRender={dateCellRender}
        onChange={onChange}
        className="calendar-card-area"
      />
    </>
  )
}

export default App
    
      

    
         
   
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值