使用vue3对vant的日历组件进行改造能选上一年下一年上一个月下一个月

效果如图:

代码如下子组件

<!-- eslint-disable vue/no-v-model-argument -->
<template>
  <section class="home-page">
    <van-calendar
      ref="calendar"
      v-bind="$attrs"
      :min-date="dateRange[0]"
      :max-date="dateRange[1]"
      v-on="$attrs"
    >
      <template #subtitle>
        <van-icon name="arrow-left" size="16" @click="scrollToDate(-1,'year')" />
        <span @click="scrollToDate(-1,'month')">前一个月</span>
        <span class="tit">{{ dateInfo.title }}</span>
        <span @click="scrollToDate(1,'month')">后一个月</span>
        <van-icon name="arrow" size="16" @click="scrollToDate(1,'year')" />
      </template>
    </van-calendar>
  </section>
</template>

<script setup>
/*
 * @Descripttion: 日历组件功能扩展
 * @Author: sunjinbo
 * @Date: 2023-10-20 15:06
 */
import moment from 'moment'
import { Toast } from 'vant'
import { ref, defineProps } from 'vue'
// props参数
const { date, dateRange } = defineProps({
  date: {
    type: Date,
    default: () => {
      return new Date()
    }
  },
  dateRange: {
    type: Array,
    default: () => {
      return [new Date(2010, 0, 1), new Date(2030, 12, 31)]
    }
  }
})
// data的数据
const dateInfo = ref({
  date: date,
  title: moment(date).format('YYYY年MM月')
})
// refs实例
const calendar = ref(null)
// 视图滚动到指定日期的视图
const scrollToDate = (type, dateType) => {
  // 生成新的时间
  const transDate = moment(dateInfo.value.date).add(type, dateType)
  // 做时间校验 校验成功则执行下面否则return
  if (!((transDate > dateRange[0]) && (transDate < dateRange[1]))) {
    return Toast.fail('已超出最大可选范围')
  }
  // 组合新的时间成对象类型
  const year = transDate.format('YYYY')
  const month = parseInt(transDate.format('MM'))
  const newDate = {
    date: new Date(transDate.format()),
    title: year + '年' + month + '月'
  }
  // 新的时间覆盖之前的时间
  dateInfo.value = newDate
  calendar.value.scrollToDate(new Date(dateInfo.value.date))
}
</script>

<style lang="less" scoped>
/deep/.van-calendar__header-subtitle {
	display: flex;
	align-items: center;
	justify-content: space-evenly;
	.tit {
		font-weight: 600;
		color: #1a73e8;
	}
}
</style>

父组件调用

<!-- eslint-disable vue/no-v-model-argument -->
<template>
  <section class="home-page">
    <van-cell title="选择多个日期" :value="text" @click="show = true" />
    <comp-calendar v-model:show="show" type="range" @confirm="onConfirm" /></section>
</template>

<script setup>
import CompCalendar from '@components/Calendar.vue'
import { ref } from 'vue'
const show = ref(false)
const text = ref(null)
const formatDate = (date) => `${date.getMonth() + 1}/${date.getDate()}`
const onConfirm = (values) => {
  const [start, end] = values
  show.value = false
  text.value = `${formatDate(start)} - ${formatDate(end)}`
}
</script>

<style lang="less" scoped>

</style>

参考vue2其他博客封装 vue2封装连接Vant组件库封装可翻页日历组件_vant日历-CSDN博客

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我会尽力回答你的问题,以下是我提供的参考答案: 首先,在使用Vue3和Vant组件之前,你需要搭建好Vue3的开发环境,并且安装好Vant组件库。具体可以参考官方文档:https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart 其次,对于二手交易app的商品发布和商品交易页面,我建议你分别创建两个组件,分别为"ProductPublish"和"ProductTrade"。在这两个组件中,你可以使用Vant组件库中的表单组件、按钮组件、图片上传组件等,来实现页面的布局和功能。 以下是一个简单的参考代码,仅供参考: ProductPublish.vue: ``` <template> <van-form @submit="onSubmit"> <van-field v-model="title" label="商品名称" required></van-field> <van-field v-model="description" label="商品描述" type="textarea"></van-field> <van-uploader v-model="images" label="商品图片" multiple></van-uploader> <van-field v-model="price" label="商品价格" type="number" required></van-field> <van-button type="primary" native-type="submit">发布商品</van-button> </van-form> </template> <script> import { ref } from 'vue'; import { Toast } from 'vant'; export default { setup() { const title = ref(''); const description = ref(''); const images = ref([]); const price = ref(''); const onSubmit = () => { // TODO: 提交表单数据到后台 Toast.success('发布成功'); }; return { title, description, images, price, onSubmit, }; }, }; </script> ``` ProductTrade.vue: ``` <template> <div> <van-list> <van-cell v-for="item in products" :key="item.id" :title="item.title" :label="`¥${item.price}`" :thumb="item.images[0]"> <template #right-icon> <van-button type="primary" size="small" @click="onBuy(item)">购买</van-button> </template> </van-cell> </van-list> </div> </template> <script> import { reactive } from 'vue'; import { Toast } from 'vant'; export default { setup() { const products = reactive([ { id: 1, title: '二手手机', description: '全新未使用,原装配件', images: ['https://img.yzcdn.cn/upload_files/2020/07/23/FnL2u8kHkD1Z8X2X4h4GK8xKJbJf.jpg!thumb500'], price: 800, }, { id: 2, title: '二手电脑', description: 'i5处理器,8G内存,256G固态硬盘', images: ['https://img.yzcdn.cn/upload_files/2020/07/23/FnL2u8kHkD1Z8X2X4h4GK8xKJbJf.jpg!thumb500'], price: 3000, }, ]); const onBuy = (product) => { // TODO: 购买商品,跳转到支付页面等操作 Toast.success('购买成功'); }; return { products, onBuy, }; }, }; </script> ``` 需要注意的是,以上代码仅作为参考,实际使用时需要根据自己的需求进行修改和完善。同时,还需要与后台进行数据交互,实现完整的功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值