返回顶部
首页 > 资讯 > 精选 >vue怎么实现左右滑动选择日期组件
  • 858
分享到

vue怎么实现左右滑动选择日期组件

2023-06-29 21:06:48 858人浏览 薄情痞子
摘要

今天小编给大家分享一下Vue怎么实现左右滑动选择日期组件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。效果图:1、安装day

今天小编给大家分享一下Vue怎么实现左右滑动选择日期组件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

效果图:

vue怎么实现左右滑动选择日期组件

1、安装dayjs日期文件

npm install dayjs --save

2、封装的组件:

<template>  <div class="m-calendar" ref="calendar">    <div class="m-toolbar">      <div class="m-year-selector">        <!-- <a class="m-prev-btn" @click="changeYear('prev')"></a> -->        <span>{{showDate.year}}{{yearName}}</span>        <!-- <a class="m-next-btn" @click="changeYear('next')"></a> -->      </div>      <div class="m-month-selector">        <!-- <a class="m-prev-btn" @click="changeMonth('prev')"></a> -->        <span>{{monthNames[showDate.month-1]}}</span>        <!-- <a class="m-next-btn" @click="changeMonth('next')"></a> -->      </div>    </div>    <div class="m-week-header">      <div        class="m-week-day"        v-for="item in weekNames"        :key="item"      >        {{item}}      </div>    </div>    <div      class="m-months-container"      @touchstart="touchstart"      @touchmove="touchmove"      @touchend="touchend"    >      <div        class="m-months-wrapper"        :      >        <div          class="m-months"          v-for="(month,monthIndex) in fullDate"          :key="monthIndex"          :style="{            transfORM: `translate3D(${(monthIndex-1+translateX + (isTouching ? touch.x : 0))*100}%, 0, 0)`,            transitionDuration: isTouching ? '0s' : '.3s',          }"        >          <div            class="m-row"            v-for="(week,weekIndex) in month"            :key="weekIndex"          >            <div              class="m-day"              v-for="(day,dayIndex) in week"              :key="dayIndex"              @click="onDayClick(day)"            >              <span                :class="{                  'm-day-num':true,                  'm-grey': day.isGrey,                  'm-today': day.isToday,                  'm-disable': day.isDisable,                  'm-select': day.isSelect,                }"              >                  <!-- 'm-during': day.isDuring -->                {{day.value}}              </span>              <slot name="day" :date="day" />            </div>          </div>        </div>      </div>    </div>  </div></template><script>import dayjs from 'dayjs';let touchStartPosition;let touchEndPosition;let timeStamp;export default {  name: 'inlineCalendar',  props: {    defaultDate: {      type: [Date, Number, Array, String, dayjs],    },    disabledDate: {      type: Array,      default() {        return [];      },    },    minDate: {      type: [Date, Number, Array, String, dayjs],    },    maxDate: {      type: [Date, Number, Array, String, dayjs],    },    mode: {      type: String,      default: 'single',    },    dayClick: {      type: Function,      default() {        return function() {          return true;        };      },    },    enableTouch: {      type: Boolean,      default: true,    },    monthNames: {      type: Array,      default() {        return ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'];      },    },    weekNames: {      type: Array,      default() {        return ['一', '二', '三', '四', '五', '六', '日'];      },    },    yearName: {      type: String,      default: '年',    },    restrictCurrentMonth: {      type: Boolean,      default: false,    },  },  watch: {    mode() {      this.init();    },  },  data() {    return {      fullDate: [[], [], []],      translateX: 0,      showDate: {        year: undefined,        month: undefined,      },      dateNow: {        year: dayjs().year(),        month: dayjs().month() + 1,        date: dayjs().date(),      },      selectDate: [],      touch: {        x: 0,        y: 0,      },      isTouching: false,    };  },  created() {    this.init();  },  methods: {    init(date) {      this.selectDate = [];      let { defaultDate, mode } = this;      if (date) {        defaultDate = date;      }      let dateToShow = dayjs().startOf('month');      if (mode === 'single' && defaultDate) {        this.selectDate = dayjs(defaultDate).startOf('day');        dateToShow = this.selectDate.startOf('month');      }      if (mode === 'multiple' && Array.isArray(defaultDate)) {        if (defaultDate.length > 0) {          this.selectDate = defaultDate.map((item) => dayjs(item).startOf('day'));        }      }      if (mode === 'during' && Array.isArray(defaultDate)) {        if (defaultDate.length === 2) {          const startDate = dayjs(defaultDate[0]).startOf('day');          const endDate = dayjs(defaultDate[1]).startOf('day');          if (startDate.isBefore(endDate) || startDate.isSame(endDate)) {            this.selectDate = [startDate, endDate];          }        }      }      this.showDate = {        year: dateToShow.year(),        month: dateToShow.month() + 1,      };      this.getFullDate(this.showDate);    },    touchstart(event) {      if (this.enableTouch) {        touchStartPosition = event.touches[0].clientX;        touchEndPosition = event.touches[0].clientY;        timeStamp = event.timeStamp;        this.touch = {          x: 0,          y: 0,        };        this.isTouching = true;      }    },    touchmove(event) {      if (this.enableTouch) {        this.touch = {          x: (event.touches[0].clientX - touchStartPosition) / this.$refs.calendar.offsetWidth,          y: (event.touches[0].clientY - touchEndPosition) / this.$refs.calendar.offsetHeight,        };      }    },    touchend(event) {      if (this.enableTouch) {        this.isTouching = false;        const during = dayjs(event.timeStamp).diff(timeStamp);        if (Math.abs(this.touch.x) > Math.abs(this.touch.y) && Math.abs(this.touch.x * this.$refs.calendar.offsetWidth) > 20) {          if (this.touch.x > 0) {            this.changeMonth('prev');          } else if (this.touch.x < 0) {            this.changeMonth('next');          }        } else {          this.touch = {            x: 0,            y: 0,          };        }      }    },    // 触发change事件    emitChange() {      this.$emit('change', this.selectDate);    },    // 触发切换年月事件    emitSwitch(showDate) {      if (this.restrictCurrentMonth) {        this.selectDate = [];      }      this.$emit('switch', showDate);    },    // 日期点击事件    onDayClick(day) {      if (!this.dayClick(day.dateTime)) {        return;      }      switch (this.$props.mode) {      case 'single':        if (!day.isSelect && !day.isDisable) {          this.selectDate = day.dateTime;          this.getFullDate(this.showDate);          this.emitChange();        }        break;      case 'multiple':        if (!day.isSelect && !day.isDisable) {          this.selectDate.push(day.dateTime);          this.getFullDate(this.showDate);          this.emitChange();        } else {          if (this.selectDate.length > 1) {            this.selectDate = this.selectDate.filter((item) => !item.isSame(day.dateTime));            this.getFullDate(this.showDate);            this.emitChange();          }        }        break;      case 'during':        if (day.isDisable) return;        if (this.restrictCurrentMonth && day.isGrey) return;        if (this.selectDate.length === 0) {          this.selectDate = [day.dateTime];        } else if (this.selectDate.length === 1) {          this.selectDate.push(day.dateTime);          if (this.selectDate[1].isBefore(this.selectDate[0])) {            this.selectDate.reverse();          }        } else if (this.selectDate.length === 2) {          this.selectDate = [day.dateTime];        }        this.getFullDate(this.showDate);        this.emitChange();        break;      }    },    // 切换年份    changeYear(action) {      const date = dayjs(`${this.showDate.year}-${this.showDate.month}`);      let computedDate;      switch (action) {      case 'prev':        this.translateX += 1;        computedDate = date.subtract(1, 'year');        break;      case 'next':        this.translateX -= 1;        computedDate = date.add(1, 'year');        break;      }      this.showDate = {        year: computedDate.year(),        month: computedDate.month() + 1,      };      this.emitSwitch(this.showDate);      this.getFullDate(this.showDate);    },    // 切换月份    changeMonth(action) {      const date = dayjs(`${this.showDate.year}-${this.showDate.month}`);      let computedDate;      switch (action) {      case 'prev':        this.translateX += 1;        computedDate = date.subtract(1, 'month');        break;      case 'next':        this.translateX -= 1;        computedDate = date.add(1, 'month');        break;      }      this.showDate = {        year: computedDate.year(),        month: computedDate.month() + 1,      };      this.emitSwitch(this.showDate);      this.getFullDate(this.showDate);    },    // 暴露出去的方法:切换已选的时间    changeDate(date) {      if (dayjs(date).isValid() || Array.isArray(date)) {        this.init(date);      } else {        console.error('Type of parameter is invalid!');      }    },    // 暴露出去的方法:切换当前显示的时间    changeDateView(date = dayjs()) {      const changeDate = dayjs(date);      this.showDate = {        year: changeDate.year(),        month: changeDate.month() + 1,      };      this.getFullDate(this.showDate);    },    getFullDate() {      const date = dayjs(`${this.showDate.year}-${this.showDate.month}`);      const thisDate = this.getDate(date);      const prevDate = this.getDate(date.subtract(1, 'month'));      const nextDate = this.getDate(date.add(1, 'month'));      this.fullDate = [        prevDate.fullDate,        thisDate.fullDate,        nextDate.fullDate,      ];    },    // 当前日期是否被选中    isSelect(date) {        // console.log(date)      let select = false;      switch (this.$props.mode) {      case 'single':        if (this.selectDate && date.isSame(this.selectDate)) {          select = true;        }        break;      case 'multiple':        if (this.selectDate.length > 0 && this.selectDate.some((item) => date.isSame(item))) {          select = true;        }        break;      }      return select;    },    // 当前时间是否在selectDate之间    isBetting(date) {      if (this.mode === 'during') {        const startDate = this.selectDate[0];        const endDate = this.selectDate[1];        if (this.selectDate.length === 1) {          return date.isSame(startDate);        } else if (this.selectDate.length === 2) {          return (date.isAfter(startDate) && date.isBefore(endDate)) || date.isSame(startDate) || date.isSame(endDate);        }      }      return false;    },    getIsDisable(dateTime) {      let isDisable = false;      const disabledDate = this.disabledDate.map((item) => dayjs(item).startOf('day'));      if (this.minDate || this.maxDate) {        if (this.minDate) {          const minDate = dayjs(this.minDate).startOf('day');          isDisable = dateTime.isBefore(minDate);        }        if (!isDisable && this.maxDate) {          const maxDate = dayjs(this.maxDate).endOf('day');          isDisable = dateTime.isAfter(maxDate);        }      } else if (disabledDate.length > 0) {        if (this.mode !== 'during') {          isDisable = disabledDate.some((item) => item.isSame(dateTime));        }      }      return isDisable;    },    getDate(thisDate) {      let date = [];      const prevDate = thisDate.subtract(1, 'month');      const nextDate = thisDate.add(1, 'month');      const firstDayOfWeek = thisDate.day() || 7;      const dayCountOfThisMonth = thisDate.daysInMonth();      const dayCountOfPrevMonth = prevDate.daysInMonth();      const prevIndexOfThisMonth = firstDayOfWeek - 1;      const NextIndexOfThisMonth = firstDayOfWeek + dayCountOfThisMonth - 2;      const disabledDate = this.disabledDate.map((item) => dayjs(item).startOf('day'));      for (let i = 0; i < 7 * 6; i++) {        // 上月        if (i < prevIndexOfThisMonth) {          const value = dayCountOfPrevMonth - (firstDayOfWeek - i - 2);          const dateTime = prevDate.date(value);          date[i] = {            value,            dateTime,            isGrey: true,            isToday: dateTime.isSame(dayjs().startOf('day')),            isSelect: this.isSelect(dateTime),            isDisable: this.getIsDisable(dateTime),            isDuring: this.isBetting(dateTime),          };        }        // 当月        if (          i >= prevIndexOfThisMonth &&          i <= NextIndexOfThisMonth        ) {          const value = i - firstDayOfWeek + 2;          const dateTime = thisDate.date(value);          date[i] = {            value,            dateTime,            isGrey: false,            isToday: dateTime.isSame(dayjs().startOf('day')),            isSelect: this.isSelect(dateTime),            isDisable: this.getIsDisable(dateTime),            isDuring: this.isBetting(dateTime),          };        }        // 下月        if (i > NextIndexOfThisMonth) {          const value = i - firstDayOfWeek - dayCountOfThisMonth + 2;          const dateTime = nextDate.date(value);          date[i] = {            value,            dateTime,            isGrey: true,            isToday: dateTime.isSame(dayjs().startOf('day')),            isSelect: this.isSelect(dateTime),            isDisable: this.getIsDisable(dateTime),            isDuring: this.isBetting(dateTime),          };        }      }      const fullDate = [];      for (let i = 0; i < 6; i++) {        fullDate.push(date.slice(i * 7, (i + 1) * 7));      }      return {        fullDate,      };    },  },};</script><style lang="less" scoped>@import './style.CSS';</style>

相关的style.css文件

.m-calendar {  background: #fff;  box-shadow: 0px 2px 6px 0px rgba(183, 183, 183, 0.2);}.m-calendar .m-toolbar {  padding-bottom: 0.36266667rem;}.m-calendar .m-toolbar {  display: flex;  height: 2.56rem;}.m-calendar .m-toolbar .m-month-selector,.m-calendar .m-toolbar .m-year-selector {  display: flex;  align-items: center;  justify-content: space-between;  padding-top: 0.74666667rem;}.m-calendar .m-toolbar .m-month-selector,.m-calendar .m-toolbar .m-year-selector {  line-height: 1.06666667rem;}.m-calendar .m-toolbar .m-month-selector,.m-calendar .m-toolbar .m-year-selector {  font-size: 0.768rem;  font-family: PingFangSC-Medium, PingFangSC;  font-weight: 500;  color: #29262a;}.m-calendar .m-toolbar .m-year-selector {  padding-left: 0.91733333rem;}.m-calendar .m-week-header {  padding: 0 0.91733333rem;}.m-calendar .m-week-header {  padding-bottom: 0.512rem;}.m-calendar .m-week-header {  position: relative;  display: flex;  box-sizing: border-box;  justify-content: space-between;  font-size: 0.59733333rem;}.m-calendar .m-week-header .m-week-day {  text-align: left;  line-height: 0.85333333rem;  font-family: PingFangSC-Regular, PingFangSC;  font-weight: 400;  color: #222222;}.m-calendar .m-months-container {  position: relative;  box-sizing: border-box;  height: 12.37333333rem;  overflow: hidden;}.m-calendar .m-months-container .m-months-wrapper {  position: absolute;  top: 0;  left: 0;  right: 0;  bottom: 0;}.m-calendar .m-months-container .m-months-wrapper .m-months {  position: absolute;  top: 0;  left: 0;  right: 0;  bottom: 0;  will-change: transform;  width: 16rem;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row {  padding-top: 0.512rem;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row {  width: 16rem;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row {  position: relative;  display: flex;  height: 1.408rem;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row .m-day {  margin-right: 0.87466667rem;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row .m-day:nth-child(1) {  margin-left: 0.66133333rem;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row .m-day {  font-size: 0.59733333rem;  font-family: PingFangSC-Medium, PingFangSC;  font-weight: 500;  color: #222222;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row .m-day {  position: relative;  height: 1.408rem;  width: 1.408rem;  line-height: 1.408rem;  text-align: center;  cursor: pointer;  -WEBkit-tap-highlight-color: transparent;  border-radius: 50%;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row .m-day .m-day-num {  width: 1.408rem;  display: inline-block;  border-radius: 100%;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row .m-day .m-day-num {  height: 1.408rem;  line-height: 1.408rem;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row .m-day .m-grey {  color: #b8b8b8;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row .m-day .m-today {  background: #5DABF3;  color: #fff;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row .m-day .m-disable {  color: #b8b8b8;  text-decoration: line-through;}.m-calendar .m-months-container .m-months-wrapper .m-months .m-row .m-day .m-select {  background: #007aff;  color: #fff;}

3、使用到的页面

<div class="data">      <inlineCalendar :dayClick="dayClick" /></div>
<script>import inlineCalendar from '../components/inlineCalendar';export default {  name: "home",  data() {    return { };  },  components: {    inlineCalendar  },  methods: {    dayClick(date) {      console.log('date---->', date);      console.log(date.format('YYYY-MM-DD'));      let dates = date.format('YYYY-MM-DD');    },  }};</script><style lang="less" scoped>    .data {      position: fixed;      top: 1.87733333rem;      width: 100%;      height: 100%;    }</style>

以上就是“vue怎么实现左右滑动选择日期组件”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

--结束END--

本文标题: vue怎么实现左右滑动选择日期组件

本文链接: https://lsjlt.com/news/326404.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • vue怎么实现左右滑动选择日期组件
    今天小编给大家分享一下vue怎么实现左右滑动选择日期组件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。效果图:1、安装day...
    99+
    2023-06-29
  • vue左右滑动选择日期组件封装的方法
    现在做的项目中遇到了左右滑动选择日期的一个功能,然后我封装了一下这个组件,现在分享给大家看一下: 效果图: 1、安装dayjs日期文件 npm install dayjs --sa...
    99+
    2024-04-02
  • Vue无限滑动周选择日期的组件怎么实现
    今天小编给大家分享一下Vue无限滑动周选择日期的组件怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。思路根据用户传入日...
    99+
    2023-07-04
  • Vue可左右滑动按钮组组件怎么用
    这篇文章将为大家详细讲解有关Vue可左右滑动按钮组组件怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体内容如下左右两箭头控制按钮组左右移动,双击到最左或最右边,功能比较简单。如下所示<tem...
    99+
    2023-06-29
  • vue怎么实现日期选择组件功能
    这篇文章主要讲解了“vue怎么实现日期选择组件功能”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue怎么实现日期选择组件功能”吧!目录结构demo 用vue-cli 的webpack-si...
    99+
    2023-07-04
  • 使用vue怎么实现左右滑动效果
    使用vue怎么实现左右滑动效果?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。HTML代码<template>    &l...
    99+
    2023-06-15
  • vue如何实现左右滑动tab(vue-touch)
    目录下载(vue-touch)main.js中引入开始使用vue-touch 的相关事件开始做tab切换下载(vue-touch) npm install vue-touch@nex...
    99+
    2024-04-02
  • 原生JS如何实现左右箭头选择日期
    小编给大家分享一下原生JS如何实现左右箭头选择日期,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!先上个效果图,就是用左右尖括号可...
    99+
    2024-04-02
  • vue实现顶部左右滑动导航
    日常开发中经常用到导航这些东西,写篇文章记录下。该导航实现为点击末尾/起首位置,导航自动滑动出下一项的效果。 思路:判断当前点击项,相对与屏幕的位置,若点击的位置,满足可移动的限制,...
    99+
    2024-04-02
  • 怎么用vue实现顶部左右滑动导航
    这篇“怎么用vue实现顶部左右滑动导航”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么用vue实现顶部左右滑动导航”文章吧...
    99+
    2023-07-04
  • jquery怎么实现移动端按钮组左右滑动
    本文小编为大家详细介绍“jquery怎么实现移动端按钮组左右滑动”,内容详细,步骤清晰,细节处理妥当,希望这篇“jquery怎么实现移动端按钮组左右滑动”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。学习移动端触摸...
    99+
    2023-06-29
  • Vue可左右滑动按钮组组件使用详解
    本文实例为大家分享了基于Vue可左右滑动按钮组组件,供大家参考,具体内容如下 左右两箭头控制按钮组左右移动,双击到最左或最右边,功能比较简单。如下所示 <template&g...
    99+
    2024-04-02
  • jquery实现移动端按钮组左右滑动
    本文实例为大家分享了jquery实现移动端按钮组左右滑动的具体代码,供大家参考,具体内容如下 学习移动端触摸相关功能时写了一个例子,共享一下,其中最不好理解的是screen、page...
    99+
    2024-04-02
  • Android怎么实现菜单左右滑动
    在Android中,实现菜单左右滑动可以通过使用ViewPager和Fragment来实现。下面是实现的步骤:1. 在布局文件中,添...
    99+
    2023-09-28
    Android
  • vue实现左右滑动效果实例代码
    前言 个人实际开发中用到的效果问题总结出来便于自己以后开发查看调用,如果也适用其他人请随意拿走勿喷就行! vue.js是现在流行的js框架之一,vue 是一套用于构建用户界面的渐进式...
    99+
    2024-04-02
  • 日期选择组件(DatePicker)的实现
    日期选择组件(DatePicker)的实现可以使用以下步骤:1. 创建一个输入框(input)用于显示选中的日期。2. 创建一个弹出...
    99+
    2023-09-15
    实现
  • Android自定义View实现左右滑动选择出生年份
    自定义view的第三篇,模仿的是微博运动界面的个人出生日期设置view,先看看我的效果图: 支持设置初始年份,左右滑动选择出生年份,对应的TextView的值也会改变。这...
    99+
    2022-06-06
    view 选择 Android
  • Android组件banner实现左右滑屏效果
    什么是banner组件?在许多Android应用上,比如爱奇艺客户端、百度美拍、应用宝等上面,都有一个可以手动滑动的小广告条,这就是banner,实际应用中的banner,其信...
    99+
    2022-06-06
    Android
  • 如何实现Vue组件化的日期联动选择器功能
    这篇文章主要介绍了如何实现Vue组件化的日期联动选择器功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。将时间戳转换成日期格式// ...
    99+
    2024-04-02
  • vue实现顶部左右滑动导航的方法
    这篇文章主要讲解了“vue实现顶部左右滑动导航的方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue实现顶部左右滑动导航的方法”吧!日常开发中经常用到导航这些东西,写篇文章记录下。该导航...
    99+
    2023-06-20
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作