iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >vue如何实现简易的弹出框
  • 311
分享到

vue如何实现简易的弹出框

2024-04-02 19:04:59 311人浏览 独家记忆
摘要

目录Vue实现弹出框1.Template2.script => data 中定义3.script => methods 中定义关闭方法4.样式vue实现弹窗选择1.创建一

vue实现弹出框

说明:点击查询弹出模态,单击表格选中,点击模态外取消模态显示效果。

如图:

1.Template

 <!-- 模态 - 选择人员 -->
    <div class="model" v-show="isshowMultiple" @click="setMaskShow($event)">
      <div class="modelFixed" ref="child">
               此处为内容区
      </div>
    </div>

2.script => data 中定义

 
        isShowMultiple: false

3.script => methods 中定义关闭方法

 setMaskShow(e) {
        if (!this.$refs.child.contains(e.target)) {
          this.isShowMultiple = false;
        }
      },

4.样式

.model {
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
}
.modelFixed {
  position: absolute;
  top: 120px;
  left: 10px;
  padding: 5px;
  background: #ffffff;
  box-shadow: 3px 2px 5px #7777;
}

vue实现弹窗选择

1.创建一个ImproveResume.vue

<template>
  <div class="release-post">
    <div class="header">
      <img
        class="header_left"
        src="./images/left_header.png"
        alt=""
        @click="clickGoBack"
      />
      <p class="header_title">完善简历</p>
    </div>
    <div class="resume_main">
      <div class="resume_content">
        <van-fORM>
          <div class="table_list">
            <p class="name_title">期望薪资</p>
            <van-field
              class="calendar"
              v-model="onlineForm.salary"
              :value="onlineForm.salary"
              placeholder="请选择"
              @click="clickPicker(1)"
              :class="{ borderStyle: salaryChange }"
              :disabled="true"
            />
          </div>
          <div class="table_list">
            <p class="name_title">最高学历</p>
            <van-field
              :style="{ color: '#323233' }"
              class="calendar"
              v-model="onlineForm.education"
              :value="onlineForm.education"
              placeholder="请选择"
              @click="clickPicker(2)"
              :class="{ borderStyle: educationChange }"
              :disabled="true"
            />
          </div>
          <div class="table_list">
            <p class="name_title">工作年限</p>
            <van-field
              class="calendar"
              v-model="onlineForm.workYears"
              :value="onlineForm.workYears"
              placeholder="请选择"
              @click="clickPicker(3)"
              :class="{ borderStyle: workYearsChange }"
              :disabled="true"
            />
          </div>
        </van-form>
 
        <!-- 薪资范围 -->
        <van-popup v-model="showPickerPopup" position="bottom" round>
          <div>
            <div class="resume_picker">
              <div
                @click.stop="clickPicker(1)"
                :class="selectIndex == 1 ? 'select_title' : 'not_title'"
              >
                <p :class="selectIndex == 1 ? 'select_text' : 'not_text'">
                  期望薪资
                </p>
                <p :class="selectIndex == 1 ? 'select_data' : 'not_data'">
                  {{ onlineForm.salary ? onlineForm.salary : "请选择" }}
                </p>
              </div>
              <div
                @click.stop="clickPicker(2)"
                :class="selectIndex == 2 ? 'select_title' : 'not_title'"
              >
                <p :class="selectIndex == 2 ? 'select_text' : 'not_text'">
                  选择学历
                </p>
                <p :class="selectIndex == 2 ? 'select_data' : 'not_data'">
                  {{ onlineForm.education ? onlineForm.education : "请选择" }}
                </p>
              </div>
              <div
                @click.stop="clickPicker(3)"
                :class="selectIndex == 3 ? 'select_title' : 'not_title'"
              >
                <p :class="selectIndex == 3 ? 'select_text' : 'not_text'">
                  工作年限
                </p>
                <p :class="selectIndex == 3 ? 'select_data' : 'not_data'">
                  {{ onlineForm.workYears ? onlineForm.workYears : "请选择" }}
                </p>
              </div>
            </div>
            <PickerPopup
              @clickClose="clickClose"
              @clickConFirm="clickConFirm"
              :showPickerPopup="showPickerPopup"
              :pickerTitle="pickerTitle"
              :columnsData="columnsData"
              :selectIndex="selectIndex"
            ></PickerPopup>
          </div>
        </van-popup>
      </div>
    </div>
    <div>
      <div class="mask">
        <button
          class="btn"
          @click="submit"
          :class="{ btnBg: colorChange() }"
          v-preventReClick="1000"
        >
          下一步
        </button>
      </div>
    </div>
    <return-left-modal
      class="modal"
      :show="isShowModal"
      title="温馨提示"
      @hideModal="hideModal"
      @submit="submitModal"
      leftBtnText="取消"
      rightBtnText="继续完善"
    >
      <p class="tips_text">完善简历,24小时好工作主动联系您</p>
    </return-left-modal>
  </div>
</template>
<script>
import Vue from 'vue';
import { Circle, DatetimePicker, Form, Field, Toast, Calendar, Picker, Overlay, ActionSheet, Popup, Tab, Tabs } from 'vant';
import 'vant/lib/index.less';
Vue.use(Circle).use(DatetimePicker).use(Form).use(Field).use(Calendar).use(Picker).use(Overlay).use(ActionSheet).use(Popup);
import ReturnLeftModal from '../perfectResume/ReturnLeftModal'
import { objBlurFun } from '@/utils/resize';
import request from './api'
import PickerPopup from './PickerPopup'
 
import Vconsole from 'vconsole'
if (process.env.node_ENV === "development") {
  new Vconsole();
}
 
export default {
  name: "ImproveResume",
  components: {
    ReturnLeftModal,
    PickerPopup,
  },
  data () {
    return {
      showPickerPopup: false,//选择弹窗
      pickerTitle: '',//弹窗标题
      columnsData: [],//弹窗数据
      isShowModal: false,
      workingYears: ['应届毕业', '1-3年', '3-5年', '6-9年', '10年以上'],
      educationColumns: ['不限', '初中以下', '中专/中技', '高中', '大专', '本科', '硕士', '博士'],
      columnsSalary: ['面议', '1000元以下/月', '1000-2000元/月', '2000-3000元/月', '3000-5000元/月', '5000-8000元/月', '8000-12000元/月', '12000-20000元/月', '20000-25000元/月', '25000元以上/月'],
      perDiem: ['面议', '10-50元/日', '50-100元/日', '100-200元/日', '200-300元/日', '300-500元/日', '500元及以上/日'],
      onlineForm: {
        type: 0, //0全职1兼职
        salary: "",//薪资
        education: "",//学历
        workYears: '',
      },
 
      salaryChange: false,
      educationChange: false,
      workYearsChange: false,
 
      docmHeight: window.innerHeight,
      showHeight: window.innerHeight,
      selectIndex: 1,
 
    };
  },
  watch: {
    //监听屏幕高度变化(软键盘弹出)
    showHeight: function (newValue) {
      if (this.docmHeight > newValue) {
        this.hideshow = false
      } else {
        this.hideshow = true
      }
    }
  },
  mounted () {
    objBlurFun('input')
    objBlurFun('textarea')
    document.documentElement.style.background = '#fff';
    // 解决安卓软件盘弹出把底部fixed顶上去,window.onresize监听页面高度的变化
    window.onresize = () => {
      return (() => {
        this.showHeight = window.innerHeight;
      })()
    }
  },
  methods: {
    clickClose () {
      console.log('取消')
      this.showPickerPopup = false
    },
    clickConFirm (v, index) {
      console.log(v, index, '点击确认')
      this.columnsData = index == 1 ? this.columnsSalary : index == 2 ? this.educationColumns : index == 3 ? this.workingYears : []
      this.selectIndex = index
      if (index == 1) {
        this.onlineForm.salary = v
        this.clickPicker(index + 1)
      } else if (index == 2) {
        this.onlineForm.education = v
        this.clickPicker(index + 1)
      } else if (index == 3) {
        this.onlineForm.workYears = v
        this.showPickerPopup = false
      }
 
    },
    clickPicker (v) {
      console.log(v, '点击index')
      this.showPickerPopup = true
      this.pickerTitle = v == 1 ? '请选择期望薪资' : v == 2 ? "请选择最高学历" : v == 3 ? '请选择工作年限' : '请选择'
      this.columnsData = v == 1 ? this.columnsSalary : v == 2 ? this.educationColumns : v == 3 ? this.workingYears : []
      this.selectIndex = v
    },
 
    clickGoBack () {
      this.userPhoneChange = false
      this.isShowModal = true
    },
    hideModal () {
      this.$store.commit('noScroll', true);
      this.isShowModal = false
      this.$store.state.entry === this.$route.path ? this.$ZhiYue.closePage() : this.$router.back();
    },
    submitModal () {
      this.$store.commit('noScroll', false);
      this.isShowModal = false
    },
    //下一步按钮色值
    colorChange () {
      if (
        this.onlineForm.salary &&
        this.onlineForm.education &&
        this.workYears
      ) {
        return true
      }
    },
    // 验证
    validateOnlineForm (btn) {
      let valid = true;
      if (!this.onlineForm.salary || !this.onlineForm.salary.trim()) {
        valid = false;
        this.$shq.toast('请选择期望薪资')
        this.welfareChange = true
      } else if (!this.onlineForm.education || !this.onlineForm.education.trim()) {
        valid = false;
        this.$shq.toast('请选择最高学历')
        this.postAgeChange = true
      } else if (!this.onlineForm.workYears || !this.onlineForm.workYears.trim()) {
        valid = false;
        this.$shq.toast('请选择工作年限')
        this.educationnge = true
      }
      return valid;
    },
    //提交
    submit () {
      this.onlineForm.telephone = this.onlineForm.contact
      if (this.validateOnlineForm()) {
        request.saveNew(
          this.onlineForm
        ).then(resp => {
          if (resp && resp.code == 0) {
            Toast.success({
              message: '完善成功',
              onClose: () => {
                this.$store.state.entry === this.$route.path ? this.$ZhiYue.closePage() : this.$router.back();
              }
            })
          } else {
            resp.message && this.$shq.toast(resp.message);
          }
        }).catch(() => {
          this.btnDisable = false
          this.$shq.toast('操作失败,请再次尝试')
        })
      }
    },
  },
  destroyed () {
    this.$store.commit('noScroll', false);
  },
};
</script>

   

<style scoped lang="less" >
* {
  margin: 0;
  padding: 0;
}
::v-deep .van-cell::after {
  border-bottom: none !important;
}
::v-deep .van-picker__cancel {
  opacity: 0;
}
 
.release-post {
  width: 100%;
  padding-bottom: 64px;
  padding-top: constant(safe-area-inset-top);
  padding-top: env(safe-area-inset-top);
}
 
::v-deep .van-field__control:disabled {
  font-size: 15px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 400;
  text-align: left;
  color: #333333;
  -WEBkit-text-fill-color: #333333;
}
.resume_main {
  width: 100%;
  margin-top: 64px;
  padding-bottom: 74px;
}
.resume_content {
  margin-left: 30px;
  margin-right: 30px;
}
.mask {
  width: 100%;
  background: #ffffff;
  box-shadow: 0px 0px 8px 0px rgba(204, 204, 204, 0.3);
  position: fixed;
  bottom: 0;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 10px 0;
  padding-bottom: calc(env(safe-area-inset-bottom)+15px);
  padding-bottom: calc(env(safe-area-inset-bottom) + 15px);
}
.btn {
  font-size: 16px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 500;
  text-align: left;
  color: #ffffff;
  margin: 0 auto;
  text-align: center;
  line-height: 1.6rem;
  width: 100%;
  margin: 0 16px;
  height: 48px;
  background: #d8d8d8;
}
.btnBg {
  font-size: 16px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 500;
  text-align: left;
  color: #ffffff;
  margin: 0 auto;
  text-align: center;
  line-height: 1.6rem;
  width: 100%;
  margin: 0 16px;
  height: 48px;
  background: #d8d8d8;
  border: none;
  outline: none;
  background: linear-gradient(90deg, #50a3ff, #1283ff);
  border-radius: 4px;
}
 
.name_title {
  font-size: 16px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: bold;
  color: #333333;
}
 
.calendar {
  width: 100%;
  height: 49px;
  background: #ffffff;
  border: 1px solid #e5e5e5;
  border-radius: 5px;
  margin-top: 10px;
  padding-left: 20px;
  background: url("./images/drop-down.png") no-repeat 96% center;
  background-size: 10px 7px;
  padding-right: 25px;
  ::v-deep .van-field__control {
    font-size: 15px;
    font-family: PingFangSC, PingFangSC-Regular;
    font-weight: 400;
    text-align: left;
    color: #333333;
    margin-top: 12px;
  }
}
::v-deep input::-webkit-input-placeholder {
  font-size: 15px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 400;
  text-align: left;
  color: #afadad;
  -webkit-text-fill-color: #afadad;
}
.table_list {
  margin-top: 16px;
}
 
.header {
  width: 100%;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  position: fixed;
  top: 0;
  height: 44px;
  background: #ffffff;
  padding-top: constant(safe-area-inset-top);
  padding-top: env(safe-area-inset-top);
  border-bottom: solid 0.5px #e5e5e5;
  z-index: 99;
}
.header_left {
  width: 20px;
  height: 20px;
  padding: 12px;
}
.header_title {
  width: 100%;
  margin: 0;
  margin-right: 44px;
  font-size: 18px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 500;
  text-align: center;
  color: #333333;
}
.borderStyle {
  border: solid 1px #ff1d28 !important;
  border-radius: 3px !important;
}
.tips_text {
  font-size: 12px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 400;
  text-align: center;
  color: #333333;
  padding-top: 8px;
  padding-bottom: 18px;
}
 
input::-webkit-input-placeholder {
  font-size: 15px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 400;
  text-align: left;
  color: #999999;
}
textarea::-webkit-input-placeholder {
  font-size: 15px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 400;
  text-align: left;
  color: #999999;
}
.van-field__control {
  color: #333333;
}
 
.resume_picker {
  display: flex;
  justify-content: space-around;
  align-items: center;
  flex: 1;
}
.select_title {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 16px 0;
  flex: 3;
  border-top: solid 3px #1283ff;
  background: linear-gradient(
    180deg,
    rgba(18, 131, 255, 0.08) 0%,
    rgba(255, 255, 255, 0) 100%
  );
}
.not_title {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 16px 0;
  flex: 3;
  border-top: solid 3px #ffffff;
}
.select_text {
  font-size: 12px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 400;
  color: #666666;
}
.not_text {
  font-size: 12px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 400;
  color: #666666;
}
.select_data {
  font-size: 16px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: bold;
  color: #1283ff;
  margin-top: 5px;
}
.not_data {
  font-size: 16px;
  font-family: PingFangSC-Medium, PingFang SC;
  font-weight: bold;
  color: #c2c2c2;
  margin-top: 5px;
}
</style>

2.创建PickerPopup.vue组件

<template>
  <div class="release-post" v-show="showPickerPopup">
    <!-- 薪资、学历、工作年限 -->
    <van-picker
      show-toolbar
      :title="pickerTitle"
      :columns="columnsData"
      :default-index="2"
      @cancel="clickClose"
      @confirm="clickConFirm"
      :style="(height = 0)"
      :cancel-button-text="null"
    />
  </div>
</template>
<script>
 
export default {
  name: "PickerPopup",
  props: {
    showPickerPopup: {
      type: Boolean,
      default: false
    },
    pickerTitle: {
      type: String,
      default: '默认'
    },
    columnsData: {
      type: Array,
      default: []
    },
    selectIndex: {
      type: Number,
      default: 1
    }
  },
  data () {
    return {
      oSelectIndex: 1
    };
  },
  watch: {
    selectIndex: {
      handler (newVal) {
        this.oSelectIndex = newVal
      },
      immediate: true,
    },
  },
 
  methods: {
    clickClose () {
      this.$emit('clickClose')
    },
    clickConFirm (value) {
      this.$emit('clickConFirm', value, this.oSelectIndex)
    },
  },
};
</script>
<style scoped lang="less" >
</style>

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: vue如何实现简易的弹出框

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

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

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • vue如何实现简易的弹出框
    目录vue实现弹出框1.Template2.script => data 中定义3.script => methods 中定义关闭方法4.样式vue实现弹窗选择1.创建一...
    99+
    2024-04-02
  • javascrip如何实现弹出框
    小编给大家分享一下javascrip如何实现弹出框,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在js中,可以使用confirm方法弹出是否弹出框,语法格式为“c...
    99+
    2023-06-15
  • vue中如何实现弹框dialog
    这篇文章主要为大家展示了“vue中如何实现弹框dialog”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vue中如何实现弹框dialog”这篇文章吧。效果如下,...
    99+
    2024-04-02
  • 如何用PHP实现简易的MVC框架
    这篇文章主要介绍了如何用PHP实现简易的MVC框架的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何用PHP实现简易的MVC框架文章都会有所收获,下面我们一起来看看吧。一、前言MVC的全名是Model View...
    99+
    2023-06-30
  • jQuery如何实现弹出框功能
    本篇内容介绍了“jQuery如何实现弹出框功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在我们构建网站或应用程序时,经常需要使用弹出框来...
    99+
    2023-07-06
  • react如何实现弹出模态框
    这篇文章主要介绍“react如何实现弹出模态框”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“react如何实现弹出模态框”文章能帮助大家解决问题。react实现弹出模态框的方法:1、用createP...
    99+
    2023-07-05
  • vue如何实现可拖拽的dialog弹框
    这篇文章主要介绍了vue如何实现可拖拽的dialog弹框,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体如下:element的dialog弹框在项目中挺常用的。但有时候嵌套...
    99+
    2023-06-15
  • js实现简易弹幕系统
    本文实例为大家分享了原生js实现弹幕效果的具体代码,供大家参考,具体内容如下 实现思路 1、先写好静态页面框架 <div id='father'> &...
    99+
    2024-04-02
  • Python如何利用Selenium实现弹出框
    这篇文章主要讲解了“Python如何利用Selenium实现弹出框”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python如何利用Selenium实现弹出框”吧!JavaScript三种弹...
    99+
    2023-07-02
  • 如何实现layui页面级弹出框
    这篇文章给大家分享的是有关如何实现layui页面级弹出框的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。home/Index.cshtml@{    ViewData[&qu...
    99+
    2023-06-29
  • 如何使用HTML和CSS实现一个简洁的弹出框布局
    概述:弹出框是网页中常用的一种交互元素,可以用于显示一些提示信息、确认对话框等。本文将介绍如何使用HTML和CSS实现一个简洁的弹出框布局,并提供具体的代码示例。HTML结构:首先,我们需要在HTML中创建一个外层容器,用来包裹弹出框的内容...
    99+
    2023-10-21
    CSS html 弹出框布局
  • C++实现简易的弹球小游戏
    本文实例为大家分享了C++实现弹球小游戏的具体代码,供大家参考,具体内容如下 操作说明:键盘A和D键控制左右移动,让球不要落下。 #include <graphics.h&...
    99+
    2024-04-02
  • Vue如何实现简易跑马灯效果
    本文小编为大家详细介绍“Vue如何实现简易跑马灯效果”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue如何实现简易跑马灯效果”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Vue跑马灯效果:1.分析a.点击&q...
    99+
    2023-06-30
  • vue如何实现简易选项卡功能
    这篇文章主要讲解了“vue如何实现简易选项卡功能”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue如何实现简易选项卡功能”吧!1. 效果: 实现发布评论功能 实现评论列表的展示 使用标签页...
    99+
    2023-07-02
  • HTML5中Canvas如何实现弹出框效果
    这篇文章将为大家详细讲解有关HTML5中Canvas如何实现弹出框效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。用户鼠标移入时,有弹出框出现,这样的需求很常见。这在处理HTML元素实现时简单,但是如果...
    99+
    2023-06-09
  • mini-vue渲染的简易实现
    目录前言目标第一步: 第二步:第三步:第四步:总结前言 目前的主流框架Vue、React 都是通过 Virtual Dom(虚拟Dom)来实现的,通过Virtua...
    99+
    2024-04-02
  • Angular如何实现多选复选框的弹出框指令
    这篇文章将为大家详细讲解有关Angular如何实现多选复选框的弹出框指令,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。要实现一个包含多个复选框的下拉框该如何做呢?先上个效...
    99+
    2024-04-02
  • 微信小程序如何实现简易封装弹窗
    今天就跟大家聊聊有关微信小程序如何实现简易封装弹窗,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。建立组件文件夹编写组件内容 <!--index.wxml-->&...
    99+
    2023-06-26
  • Popup如何实现弹出框添加数据
    这篇文章将为大家详细讲解有关Popup如何实现弹出框添加数据,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。逻辑窗口P1中显示一组数据,并提供一个添加按钮点击按钮,弹出新的...
    99+
    2024-04-02
  • vue组件如何实现弹出框点击显示隐藏效果
    小编给大家分享一下vue组件如何实现弹出框点击显示隐藏效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!效果如下图  ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作