vue 渲染数组,拖拽排序,渲染同一个数组拖拽排序不影响其他选中行状态

这篇具有很好参考价值的文章主要介绍了vue 渲染数组,拖拽排序,渲染同一个数组拖拽排序不影响其他选中行状态。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

当我们能够设置单行状态改变的时候,那么肯定可以拿到选中的当前行的id或者下标index。
只要设定一个初始化值在拖拽开始的时候重新赋值,然后再处理选中状态的时候进行判断即可。
前期写的时候没有注意到这个问题,可以看这个文章。

在复测的时候发现了,当我改变任意一个排序的时候会影响到其他的状态。虽然其他行的顺序没有变化,但是设定的颜色却渲染了。
解决 ,在data 中初始设定一个新的变量 承接 选中的行的父元素下标 startIndex: ‘’, 在开始拖拽的时候获取并重新赋值, this.startIndex = i,在 isSelected 处理改变颜色的时候判断即可。
vue 渲染数组,拖拽排序,渲染同一个数组拖拽排序不影响其他选中行状态,vue.js,javascript,前端,拖拽

以前的问题

vue 渲染数组,拖拽排序,渲染同一个数组拖拽排序不影响其他选中行状态,vue.js,javascript,前端,拖拽
解决后不在影响
vue 渲染数组,拖拽排序,渲染同一个数组拖拽排序不影响其他选中行状态,vue.js,javascript,前端,拖拽
主要的代码也就在这里,天机了传值和接收赋值处理

isSelected(i, j) {
console.log(this.startIndex, ‘///this.startIndex’, i);
if(this.startIndex === i){
return j === this.selectedIndex; // 判断该图标是否被选中
}
},
dragStart (i, j, item2) {
console.log(i, j, item2, ‘----------------’);
this.startIndex = i // 开始选中的行下标。
this.dragStartIndex = j
this.dragStartData = item2
this.selectedIndex = j; // 更新选中的索引值
},
vue 渲染数组,拖拽排序,渲染同一个数组拖拽排序不影响其他选中行状态,vue.js,javascript,前端,拖拽文章来源地址https://www.toymoban.com/news/detail-795338.html

<template>
  <div class="atomizing-wrap">
    <div class="liquid-wrap">
      <div class="conduit1">
        <!-- <img src="../../../assets/images/emulsification/liquidtank/conduit1.png" alt="">
        <div class="lititle-wrap">
          <lititle title="井下原水"/>
        </div> -->
      </div>
      <div class="liquid-box">
        <liquid :dataInfo="dataInfos.emulsionSite" @liquidClik="liquidClik()"/>
      </div>
    </div>
    <div class="supercharge-box">
      <supercharge :dataInfo="dataInfos.superchargeSite" :typeInfo="dataInfos.emulsionSite"/>
    </div>
    <div class="pump-box">
      <pump :dataInfo="dataInfos" @pumpClik="pumpClik()"/>
    </div>
    <zmjdialog ref="zmjdialog" top="10vh" width="900px" @confirm="confirm" @cancel="cancel" >
      <el-form ref="ruleForm" :model="formData" label-width="150px">
        <div class="df">
          <!-- :rules="[{ required: true, message: '请输入测点', trigger: ['blur', 'change'] }]" -->
          <el-form-item
            prop="emulsionSite.site"
            label="清水箱测点"
          >
            <el-input v-model="formData.emulsionSite.site" placeholder="请输入清水箱测点">
            </el-input>
          </el-form-item>
          <el-form-item
          label-width="80px"
            prop="emulsionSite.unit"
            label="单位"
          >
            <el-input v-model="formData.emulsionSite.unit" :style="{width: '100px'}" placeholder="请输入单位">
            </el-input>
          </el-form-item>
          <el-form-item
          label-width="80px"
            prop="emulsionSite.maxValue"
            label="满量程"
          >
            <el-input v-model="formData.emulsionSite.maxValue" type="number" :style="{width: '100px'}" placeholder="满量程">
            </el-input>
          </el-form-item>
        </div>
        <div class="df">
          <el-form-item
            prop="systemSite.site"
            label="喷雾泵系统压力测点"
          >
            <el-input v-model="formData.systemSite.site" placeholder="请输入喷雾泵系统压力">
            </el-input>
          </el-form-item>
              <el-form-item
              label-width="80px"
            prop="systemSite.unit"
            label="单位"
          >
            <el-input v-model="formData.systemSite.unit" :style="{width: '100px'}" placeholder="请输入单位">
            </el-input>
          </el-form-item>
        </div>
        <div class="pressurize">
          <div class="addpressurize" @click="addpressurize">添加喷雾增压</div>
          <el-form-item
            v-for="(item, i) in formData.superchargeSite"
            :key="i"
            :label="`${i+1}#喷雾增压`"
          >
            <el-input v-model="item.site" placeholder="请输入喷雾增压测点">
            </el-input>
            <div v-if="i !== 0" class="el-icon-remove" @click="deletepressurize(i)"></div>
          </el-form-item>
              <!-- <el-form-item
              label-width="80px"
            prop="superchargeSite.number"
            label="数量"
            :rules="[{ required: true, message: '请输入数量', trigger: ['blur', 'change'] },{ validator: validatenum, trigger: 'blur'}]"
          >
            <el-input v-model="formData.superchargeSite.number" type="number" :style="{width: '100px'}" placeholder="请输入数量">
            </el-input>
          </el-form-item> -->
        </div>
        <div class="pump-list">
          <div class="title">
            <span>喷雾泵</span>
            <ul>
              <!-- <li @click="pumpcancel">取消</li> -->
              <li @click="addpump">添加</li>
            </ul>
          </div>
          <div class="ulmine">
            <el-collapse v-model="activeNames" @change="handleChange">
              <el-collapse-item v-for="(item, i) in formData.pumplist" :key="i" :name="i">
                <template slot="title">
                  {{ i+1 }}#{{ item.title }}
                  <div class="pumpdelete" @click.stop="pumpdelete(i)">删除</div>
                </template>
                <div class="ulmine-div">
                  <div class="addpumpsite" @click="addpumpsite(i)">添加测点</div>
                  <div class="df">
                    <el-form-item
                    label-width="100px"
                    label="喷雾泵测点"
                    >
                      <el-input v-model="item.site" placeholder="请输入测点">
                      </el-input>
                    </el-form-item>
                    <el-form-item
                    label-width="80px"
                    label="分站远控"
                    >
                      <el-switch
                        v-model="item.control"
                        >
                      </el-switch>
                    </el-form-item>
                    <el-form-item
                    label-width="80px"
                    label="解锁"
                    >
                      <el-switch
                        v-model="item.unlock"
                        >
                      </el-switch>
                    </el-form-item>
                  </div>
                  <div v-for="(item2, j) in item.list"
                    :key="j"
                    class="df"
                    draggable="true"
                    @dragstart="dragStart(i, j, item2)"
                    @dragover.prevent="dragOver(j)"
                    @dragend="dragEnd(i)"
                  >
                    <i class="el-icon-s-fold" :class="{'selected': isSelected(i, j)}"></i>
                    <el-form-item
                    label-width="100px"
                    label="测点名称"
                    >
                      <el-input v-model="item2.label" placeholder="请输入测点名称">
                      </el-input>
                    </el-form-item>
                    <el-form-item
                      label-width="50px"
                      label="测点"
                    >
                      <el-input v-model="item2.site" :style="{width: '100px'}" placeholder="请输入测点">
                      </el-input>
                    </el-form-item>
                    <el-form-item
                      label-width="50px"
                      label="单位"
                    >
                      <el-input v-model="item2.unit" :style="{width: '100px'}" placeholder="请输入单位">
                      </el-input>
                    </el-form-item>
                    <el-form-item
                      label-width="60px"
                      label="最大值"
                    >
                      <el-input v-model="item2.maxValue" type="number" :style="{width: '100px'}" placeholder="最大值">
                      </el-input>
                    </el-form-item>
                    <div class="el-icon-remove" @click="deletepumpsite(i,j)"></div>
                  </div>
                </div>
              </el-collapse-item>
            </el-collapse>
          </div>
        </div>
      </el-form>
    </zmjdialog>
    <zmjdialog ref="childInfoDialog" width="850px" top="30vh"  :title="`${label}历史数据`" @confirm="childInfoDialog">
      <zmj-echarts :ref="`historicalLineEcharts${EchartsId}`" :echarts-id="`historicalLineEcharts${EchartsId}`" :height="'200px'"></zmj-echarts>
    </zmjdialog>
  </div>
</template>

<script>
import ZmjEcharts from '@/components/zmjEcharts.vue'
import { shearerOptions } from '../../components/echarts/Historicalline.js'

export default {
  name: 'atomizing',
  components: {
    ZmjEcharts,
    liquid: () => import('./liquid.vue'),
    // lititle: () => import('./li-title.vue'),
    supercharge: () => import('./supercharge.vue'),
    pump: () => import('./pump.vue')
  },
  props: {
    dataInfo: {
      type: Object,
      default (){
        return {}
      }
    },
    dataTypeList: {
      type: Array,
      default (){
        return []
      }
    }
  },
  data () {
    return {
      activeNames: [0],
      formData: {},
      dataInfos: {},
      groupName: '', // 测点大类
      dataName: '', // 测名称
      deviceIdList: 1, // 设备号
      label: null,
      EchartsId: null,
      selectedIndex: -1,
      dragStartIndex: '',
      dragStartData: '',
      startIndex: ''
    }
  },
  watch: {
    dataInfo: {
      immediate: true,
      deep: true,
      handler (val) {
        this.formData = JSON.parse(JSON.stringify(val))
        this.dataInfos = JSON.parse(JSON.stringify(val))
      }
    }
  },
  computed: {},
  created () {},
  mounted () {
    this.bus.$on("waterCustomEvent", (v) => {
      this.dbChange(v, 'pumplistClikqs')
    });
    window.$eventBus.$on('wsMessage', message => {
      let dataType =  message.dataType
      message.data.forEach(val => {
        for(let i in this.dataInfos){
          if(Array.isArray(this.dataInfos[i])){
            this.dataInfos[i].forEach(v => {
              if(this.sifn(v.site) === dataType && this.sifn(v.site, 2) === val.deviceId){
                v.value = val.value
              }
              v.list && v.list.forEach(v2 => {
                if(this.sifn(v2.site) === dataType && this.sifn(v2.site, 2) === val.deviceId){
                  v2.value = val.value
                }
              })
            })
          }else if(this.sifn(this.dataInfos[i].site)  === dataType && this.sifn(this.dataInfos[i].site, 2) ===val.deviceId){
            this.dataInfos[i].value = val.value
          }
        }
      })
    })
  },
  beforeDestroy () {
    window.$eventBus.$off('wsMessage')
  },
  methods: {
    isSelected(i, j) {
      console.log(this.startIndex, '///this.startIndex', i);
      if(this.startIndex === i){
        return j === this.selectedIndex; // 判断该图标是否被选中
      }
    },
    dragStart (i, j, item2) {
      console.log(i, j, item2, '----------------');
      this.startIndex = i // 开始选中的行下标。
      this.dragStartIndex = j
      this.dragStartData = item2
      this.selectedIndex = j; // 更新选中的索引值
    },
    // 只要拖拽元素进入到放置区域就触发,这里实际是鼠标指针进入放置区域才触发
    dragOver (j) {
      this.dragOverIndex = j
    },
    dragEnd (i) {
      const copyTodolist = [...this.formData.pumplist[i].list]
      // 删除老的节点
      copyTodolist.splice(this.dragStartIndex, 1)
      // 在列表中目标位置增加新的节点
      copyTodolist.splice(this.dragOverIndex, 0, this.dragStartData)
      this.selectedIndex = this.dragOverIndex; // 更新选中的索引值
      this.formData.pumplist[i].list = [...copyTodolist]
      this.dragOverIndex = ''
    },
    pumpClik () {
      this.dbChange(this.dataInfos.systemSite, 'pumpClikqs')
    },
    liquidClik () {
      this.dbChange(this.dataInfos.emulsionSite, 'liquidClikqs')
    },
    dbChange(item, EchartsId) {
      this.EchartsId = EchartsId
      this.$refs.childInfoDialog.open()
      let newArr = item?.site?.split('/') || [];
      if(newArr.length === 3){
        this.groupName = `${newArr[0]}` // 测点大类
        this.deviceIdList =  `${newArr[1]}`*1 // 设备号
        this.dataName = `${newArr[2]}` // 测名称
      }
      this.label = item.label || item.title + (item.text ? item.text : '' )
      let params = {
        workFaceCode: window.$getStorage('workFaceInfo').workFaceCode,
        startTime: window.$dayjs().format('YYYY-MM-DD 00:00:00'),
        endTime: window.$dayjs().add(1, 'day').format('YYYY-MM-DD 00:00:00'),
        aggregateType : 'none', // 聚合类型 传none获取原始历史值
        groupName: this.groupName, // 测点大类
        dataName:  this.dataName, // 测名称
        deviceIdList: this.deviceIdList // 设备号
      }
      let thisDataList = null
      window.$axiosGet('deviceHistory', params).then((res) => {
        if(!res.length){
          this.$refs[`historicalLineEcharts${this.EchartsId}`] && this.$refs[`historicalLineEcharts${this.EchartsId}`].upDataEcharts(shearerOptions(res || [], params, this.dataInfos))
          return
        }
        thisDataList = res.map(item => {
          return item.data
        })
        this.$nextTick(() => {
          this.$refs[`historicalLineEcharts${this.EchartsId}`] && this.$refs[`historicalLineEcharts${this.EchartsId}`].getEchartsLiving();
          this.$refs[`historicalLineEcharts${this.EchartsId}`] && this.$refs[`historicalLineEcharts${this.EchartsId}`].upDataEcharts(shearerOptions(thisDataList || [], params, this.dataInfos))
        })
      }).catch(() => {
        this.$refs[`historicalLineEcharts${this.EchartsId}`] && this.$refs[`historicalLineEcharts${this.EchartsId}`].upDataEcharts(shearerOptions(thisDataList || [], params, this.dataInfos))
      })
    },
    childInfoDialog () {
      this.$refs.childInfoDialog.close()
    },
    sifn (v, i = 1) {
      if(v){
        let arr = v.split('/')
        if(arr.length === 3){
          if(i === 1){
            return `${arr[0]}_${arr[2]}`
          }else if(i === 2) {
            return Number(arr[1])
          }
        }else{
          return v
        }
      }else{
        return v
      }
    },
    handleChange (val) {
      console.log(val)
    },
    validatenum (rule, value, callback) {
      if (value === ''||value === null) {
        callback(new Error('数量不能为空'))
      } else if (Number(value) < 1 || Number(value) > 4) {
        callback(new Error('数量必须大于0且小于等于4'))
      } else {
        callback()
      }
    },
    // 乳化增压
    addpressurize () {
      if(this.formData.superchargeSite.length >= 4){
        this.$message.warning('喷雾增压最多添加4个')
        return
      }
      this.formData.superchargeSite.push({
        site: null,
        value: null
      })
    },
    // 乳化增压删除
    deletepressurize (i) {
      this.formData.superchargeSite.splice(i, 1)
    },
    addpump () {
      if(this.formData.pumplist.length >= 4){
        this.$message.warning('喷雾泵最多添加4个')
        return
      }
      this.formData.pumplist.push(
        {
          title: '喷雾泵',
          label: '喷雾泵测点',
          site: null,
          control: true,
          unlock: true,
          list: []
        }
      )
    },
    // 乳化泵取消修改
    pumpcancel () {

    },
    // 乳化泵删除
    pumpdelete (i) {
      if(this.formData.pumplist.length <= 1){
        this.$message.warning('喷雾泵最少有1个')
        return
      }
      this.formData.pumplist.splice(i, 1)
    },
    // 乳化泵测点添加
    addpumpsite (i) {
      this.formData.pumplist[i].list.push({
        label: null,
        site: null,
        unit: null,
        maxValue: null,
        value: null
      })
    },
    // 乳化泵测点删除
    deletepumpsite (i, j) {
      this.formData.pumplist[i].list.splice(j, 1)
    },
    edit () {
      this.formData = JSON.parse(JSON.stringify(this.dataInfo))
      this.$refs.zmjdialog.open()
    },
    confirm (){
      this.selectedIndex = -1;
      this.dragStartIndex = '';
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          this.$refs.zmjdialog.close()
          let arr = []
          for(let i in this.formData){
            if(Array.isArray(this.formData[i])){
              this.formData[i].forEach(v => {
                arr.push(v.site)
                v.list && v.list.forEach(v2 => {
                  arr.push(v2.site)
                })
              })
            }else{
              arr.push(this.formData[i].site)
            }
          }
          this.$emit('update:dataTypeList', arr)
          this.$emit('update:dataInfo', this.formData)
          this.$message.success('保存成功')
        } else {
          return false
        }
      })
    },
    cancel () {
      this.selectedIndex = -1;
      this.dragStartIndex = '';
      console.log('取消')
    }
  }
}
</script>
  <style lang="scss" scoped>
  .atomizing-wrap{
    position: relative;
      text-align: left;
  }
  .liquid-wrap{
      width:260px;
      margin-left: 20px;
      position: relative;
  }
  .conduit1{
      position: absolute;
      top: 20px;
      .lititle-wrap{
          position: absolute;
          top: 0;
          left: 20px;
      }
  }
  .liquid-box{
      position: absolute;
      left: 50px;
      top: 90px;
  }
  .supercharge-box{
      position: absolute;
      left: 246px;
      top: 45px;
  }
  .pump-box{
    position: absolute;
      left: 483px;
      top: 45px;
  }
  .pump-list{
  color: #fff;
  border:1px solid #999;
  border-radius: 5px;
  .title{
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 16px;
    width: 100%;
    height: 36px;
    background: rgba(238, 238, 238, 0.08);
    border-bottom: 1px solid #314150;
    box-sizing: border-box;
    ul{
      display: flex;
      li{
        margin-left: 8px;
        width: 64px;
        line-height: 24px;
        font-size: 14px;
        text-align: center;
        border-radius: 3px;
        user-select: none;
    cursor: pointer;
      }
      // >li:nth-child(1){
      //   border: 1px solid rgba(255, 255, 255, 0.24);
      // }
      >li:nth-child(1){
        border: 1px solid #0088FF;
      }
    }
  }
  .ulmine{
    padding: 10px 20px;
    height: 400px;
    overflow: hidden;
    overflow-y: scroll;
    .ulmine-div{
      position: relative;
      padding: 15px 0;
    }
    .el-icon-remove{
      cursor: pointer;
      height: 36px;
      line-height: 36px;
      font-size: 20px;
      padding-left: 15px;
      color: #999;
    }
    .pumpdelete{
        width: 64px;
        line-height: 24px;
        font-size: 14px;
        text-align: center;
        border-radius: 3px;
        cursor: pointer;
        border: 1px solid #B23B3B;
        margin-left: 620px;
    }
    .addpumpsite{
      position: absolute;
      line-height: 24px;
      font-size: 14px;
      text-align: center;
      border-radius: 3px;
      cursor: pointer;
      //right: 10px;
      top: 20px;
      width: 84px;
      right: 30px;
      border: 1px solid #0088FF;
    }
    .el-icon-s-fold{
      margin-top: 12px;
      color: #fff;
    }
    .selected {
      color: red; /* 设置选中时的颜色 */
    }
    ::v-deep{
      .el-collapse{
        border: none;
      }
      .el-collapse-item__header{
        padding-left: 20px;
        //background: transparent;
        color: #fff;
        border-bottom:none;
        background: rgba(238, 238, 238, 0.08);
      }
      .el-collapse-item__wrap{
        background: transparent;
        border-bottom: 1px dashed #7a7d80;
      }
      .el-collapse-item__content{
        color: #fff;
        padding-bottom: 0;
      }
    }
  }
  .ulmine::-webkit-scrollbar {
        display: none;
    }
}
.pressurize{
  position: relative;
  flex-wrap:wrap;
  .addpressurize{
    color: #fff;
    position: absolute;
      line-height: 24px;
      font-size: 14px;
      text-align: center;
      border-radius: 3px;
      cursor: pointer;
      left: 412px;
      top: 5px;
      width: 104px;
      border: 1px solid #0088FF;
      z-index: 99;
  }
  .el-icon-remove{
    cursor: pointer;
      height: 36px;
      line-height: 36px;
      font-size: 20px;
      padding-left: 10px;
      color: #999;
  }
}
  </style>

到了这里,关于vue 渲染数组,拖拽排序,渲染同一个数组拖拽排序不影响其他选中行状态的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 同一个请求同一个参数,postman发送成功,jmeter失败

    当使用jmeter 请求时吗,注意请求参数中是否包含中文。 问题来由: 1.先用postman发送,成功。  2.一模一样,header一样,请求一样,但是就是一直查询不出来。 3.经过fiddler抓包,再次对比请求头,请求体,还是没有发现有什么差别。 4.猜想: 此接口其他参数传送,都没有问题

    2024年02月13日
    浏览(35)
  • 多个硬盘挂载到同一个目录

    同一目录无法重复挂载,后挂载的会覆盖之前挂载的磁盘。但是现在需要将4块磁盘并行挂载,该如何操作呢? 将2块磁盘合并到一个逻辑卷 进行挂载。 基本知识 基本概念PV(Physical Volume)- 物理卷物理卷在逻辑卷管理中处于最底层,它可以是实际物理硬盘上的分区,也可以是整

    2024年02月08日
    浏览(54)
  • CSS 沿着同一个方向旋转

    主要解决旋转360°后倒转的问题,沿着一个方向旋转,而不是倒回去重新开始。 效果  源码 在线示例 同方向旋转

    2024年02月15日
    浏览(30)
  • 【点击新增一个下拉框 与前一个内容一样 但不能选同一个值】

    主要是看下拉选择el-option的disabled,注意不要混淆 methods:

    2024年02月11日
    浏览(32)
  • 如何将微前端项目部署在同一台服务器同一个端口下

    作者:京东科技 高飞 本文旨在通过部署微前端项目的实践过程中沉淀出一套部署方案,现就一些重点步骤、碰到的问题做了一些总结。 因为线上部署主应用时需要用到子应用的线上可访问地址,因此部署顺序应该是先部署子应用,保证子应用能够线上可访问后,再将子应用

    2023年04月11日
    浏览(36)
  • 不同设备使用同一个Git账号

    想要在公司和家里的电脑上用同一个git账号来pull, push代码 第1种方法, 依次输入 第2种方法, 输入 用户名和邮箱与原设备保持一致 输入上面三句话之后会弹出提示是否在此电脑上创建.ssh文件夹,回车同意即可 接着会提示设置密码,不设置就连按两次回车 完成之后,在 “

    2024年04月10日
    浏览(32)
  • 不同版本.net引用同一个项目

    项目文件.csproj文件内容如下: 重点是:不能有其他的 netstandard2;net40;net45;net46;net6

    2024年02月10日
    浏览(32)
  • Unity批量给模型上同一个材质

    Unity批量给模型上同一个材质 第一步:先选择所有要上材质的模型:  第二步:将创建的材质拖到右侧属性栏:  

    2024年02月12日
    浏览(33)
  • axios同一个接口,同时接收 文件 或者 数据

    1、前端代码  主要是: if (response.data instanceof Blob)  判断是否是 Blob 对象, 否则使用: response.data = JSON.parse(await (response.data).text()) 将后台返回的内容转成 文本 返回 主要是: responseType: \\\'blob\\\' 2、后端代码 需要注意的是: response.setHeader(\\\"Access-Control-Expose-Headers\\\", \\\"filename\\\"); 否则

    2024年02月12日
    浏览(36)
  • 【注意】当同一个Class的多个对象出现在同一段代码内的时候,极易出错。

    下面的 paymentQuery 方法坐落于我们lijianjin系统的LiJianJinPaymentQueryBizService。 这两个bankOrderFlow、orderFlow,... 乱花渐欲迷人眼的赶脚,但其实,这是像“shǐ”一样的代码。         在我们的zhongtai-channel-provider, 上周出现并紧急fix了一个bug。竟然也是 此种情况 引发的bug。   先上

    2024年04月28日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包