欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Element-ui的table表格实现跨页多选及回显效果

程序员文章站 2022-06-22 15:03:59
效果图安装 Element-ui 和 egrid    基于 Element-UI Table 组件封装的高阶表格组件,可无缝支持 element 的 table 组件npm i element-ui -Snpm i egrid -S引入 Element-ui 和 Egrid    在 main.js 文件里引入并注册 ( 这里是 Vue3.0 的模板 )import Vue from 'vue'import App from './App.vue'import router from...

效果图

Element-ui的table表格实现跨页多选及回显效果

安装 Element-ui 和 egrid

    基于 Element-UI Table 组件封装的高阶表格组件,可无缝支持 element 的 table 组件

npm i element-ui -S
npm i egrid -S

引入 Element-ui 和 Egrid

    在 main.js 文件里引入并注册 ( 这里是 Vue3.0 的模板 )

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

import 'element-ui/lib/theme-chalk/index.css'
import '../public/css/iconfont.css' // 引入字体图标样式
import '../public/css/reset.css' // 引入初始化样式

import ElementUI from 'element-ui' // 引入element-ui
import Egrid from 'egrid' // 引入egrid

Vue.use(ElementUI)
Vue.use(Egrid)

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

在组件中使用form表单

<template>
  <div class='wrapper'>
    <div class='tab-wrap'>
      <el-form>
        <el-form-item>
          <el-button @click='handleRoleDialog'>选择英雄</el-button>
          <el-table :data='selectedList' max-height='618' style='margin-top: 20px;'>
            <el-table-column label='英雄名称' prop='name'></el-table-column>
            <el-table-column label='英雄定位' prop='location'></el-table-column>
            <el-table-column label='英雄特长' prop='specialty'></el-table-column>
            <el-table-column label='英雄技能' prop='skill'>
              <template slot-scope='scope'>
                <div class='item' v-for='item in scope.row.skill' :key='item.id'>{{item}}</div>
              </template>
            </el-table-column>
            <el-table-column label='英雄价格' prop='price'></el-table-column>
            <el-table-column label='操作' width='60'>
              <template slot-scope='scope'>
                <a href='javascript:;' @click='handleRoleDel(scope.row)'>删除</a>
              </template>
            </el-table-column>
          </el-table>
        </el-form-item>
      </el-form>
      <SetHero :visible.sync='show' :selectedList='selectedList' @on-choosed='choosed'></SetHero>
    </div>
  </div>
</template>

<script>
import SetHero from '../components/setHero'
export default {
  components: {
    SetHero
  },
  data () {
    return {
      show: false,
      selectedList: [
        {
          'id': 1,
          'name': '上官婉儿',
          'location': '法师 / 刺客',
          'specialty': '爆发 / 突进',
          'skill': ['笔阵', '篆法·疾势', '飞白·藏锋', '章草·横鳞'],
          'price': 13888
        }, {
          'id': 2,
          'name': '王昭君',
          'location': '法师',
          'specialty': '控制 / 冰冻',
          'skill': ['冰封之心', '凋零冰晶', '禁锢寒霜', '凛冬已至'],
          'price': 8888
        }, {
          'id': 3,
          'name': '老夫子',
          'location': '战士',
          'specialty': '突进',
          'skill': ['师道尊严', '圣人训诫', '举一反三', '圣人之威'],
          'price': 8888
        }
      ]
    }
  },
  methods: {
    handleRoleDialog () {
      this.show = true
    },
    // 删除英雄
    handleRoleDel (row) {
      if (row.id) {
        var newArr = this.selectedList.filter(function (item, index) {
          return item.id !== row.id
        })
        this.selectedList = newArr
      }
    },
    // 接收子组件传的值
    choosed (list) {
      this.selectedList = list
    }
  }
}
</script>

<style lang='stylus' scoped>
  .wrapper
    width: 100%;
    background: #fff;
    padding: 50px 0;
    box-sizing: border-box;
    .tab-wrap
      width: 600px;
      margin: 0 auto;
      .item
        cursor: pointer;
</style>

自定义组件 setHero

<template>
  <el-dialog title="选择英雄" append-to-body @open="open" @close="close" width="40%" :visible.sync="show">
    <el-button @click="resetAllChecked" style="margin-bottom: 20px;">取消全部选择</el-button>
    <egrid ref="multipleTable"
           :data="heroData"
           :columns="columns"
           :column-type="colType"
           :columns-schema="columnsSchema"
           @selection-change="selectionChange"></egrid>
    <el-pagination layout="prev, pager, next, jumper, sizes, total"
                   :total="totalCount"
                   v-if="totalCount"
                   :page-size="pageSize"
                   :page-sizes="[5, 10, 20, 30, 40, 50]"
                   :current-page="pageNo"
                   @size-change="sizeChange"
                   @current-change="pageChange"></el-pagination>
    <div slot="footer">
      <el-button @click="show = false">取 消</el-button>
      <el-button type="primary" @click=seve>确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
import Vue from 'vue'
import axios from 'axios'
import tableChecked from '@/mixins/table-checked.js'
const columns = [
  { prop: 'name', label: '英雄名称' },
  { prop: 'location', label: '英雄定位' },
  { prop: 'specialty', label: '英雄特长' },
  { prop: 'skill', label: '英雄技能' },
  { prop: 'price', label: '英雄价格' }
]
export default {
  mixins: [tableChecked],
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    selectedList: {
      type: Array,
      default () {
        return []
      }
    }
  },
  data () {
    return {
      heroData: [],
      totalCount: 0, // 数据总量
      pageSize: 5, // 每页数据量
      pageNo: 1, // 页数
      unionKey: ['id'], // 统一标识key集合
      // 相当于 Element Table-column 的 type 属性,用于支持功能特殊的功能列(多选、索引、折叠行),不设置则不显示功能列
      colType: 'selection',
      // 用于控制表格列渲染
      columns: columns,
      // Object 可以用来单独定义 columns 的某一列,这里的设置会覆盖 columnsProps 的配置属性 
      // 使用 Element Table-column 中 label 值进行匹配
      columnsSchema: {
        '英雄技能': {
          propsHandler ({ col, row }) {
            return { skill: row[col.prop] }
          },
          component: Vue.extend({
            props: ['skill'],
            render (h) {
              return h('div', this.skill.toString())
            }
          })
        }
      },
      selectedRows: [] // 当前列表页选择的数据项
    }
  },
  computed: {
    show: {
      get () {
        return this.visible
      },
      set (val) {
        this.$emit('update:visible', val)
      }
    }
  },
  methods: {
    getHeroList () {
      this.updateTableSelection(this.heroData, this.selectedRows, this.unionKey)
      // 正在加载时不再重复请求
      axios.get('/api/table.json').then(res => {
        this.totalCount = res.data.totalCount
        this.heroData = res.data.data.slice((this.pageNo - 1) * this.pageSize, this.pageNo * this.pageSize)
        this.buildTableSelection(this.heroData, 'multipleTable', this.unionKey)
      })
    },
    // 取消全部选择
    resetAllChecked () {
      this.selectedRows = [] // 清空当前列表页选择的数据项
      this.totalCheckedList = [] // 清空已选择的数据项
      this.$refs.multipleTable.clearSelection() // 清除全部的选中状态
    },
    // pageSize 改变时会触发 每页条数
    sizeChange (size) {
      this.pageSize = size
      this.pageNo = 1
      this.getHeroList()
    },
    // currentPage 改变时会触发	当前页
    pageChange (page) {
      this.pageNo = page
      this.getHeroList()
    },
    // Dialog 打开的回调
    open () {
      this.totalCheckedList = [] // 清空选择的数据项
      this.totalCheckedList.push(...this.selectedList) // 将selectedList放进去回显选中状态
      this.getHeroList()
    },
    // Dialog 关闭的回调
    close () {
      this.pageNo = 1
      this.heroData = []
    },
    // 当选择项发生变化时会触发该事件
    selectionChange (val) {
      this.selectedRows = val
    },
    // 确定
    seve () {
      this.updateTableSelection(this.heroData, this.selectedRows, this.unionKey)
      // 调用自定义事件,向父组件传值
      this.$emit('on-choosed', this.totalCheckedList)
      this.show = false
    }
  }
}
</script>

<style scoped>
</style>

封装的table-checked.js(重点)

// 列表/表格item选中帮助类
// 提供全选、单独选择、切换分页时记录之前所有选中的item
// 引用方式:
// import tableChecked from '@/mixins/table-checked.js'
// mixins: [tableChecked]
// 1. table的selection形式
//   1.1 每次请求数据之前,调用该方法,原因是在当前页改变状态时不会触发 totalCheckedList,
//       因此请求数据之前需要主动触发一次计算全部选择的列表:
//       this.updateTotalListBySelection(this.heroData, this.multipleSelection, unionKey)
//   1.2 请求数据成功后,调用该方法:
//       this.buildMultipleTableSelection(this.heroData, 'multipleTable', unionKey)
//   1.3 执行操作时需要再次调用1.1中的方法,原因是当前页操作选中状态时,不会主动触发计算,因此在最终调用时触发一次即可
//   1.4 执行操作时,将 totalCheckedList 作为全部选择的参数即可
//   1.5 清除全部选择时,将totalCheckedList 和 selectedRows 的值置为空

export default {
  data () {
    return {
      totalCheckedList: [] // 被选中的列表数据
    }
  },
  methods: {
    // 根据 unionKey 构建 target 的 unionId
    // @param target 目标 item
    // @param unionKey 数组,唯一id标识,可能有多个 key
    buildUnionId (target, unionKey) {
      if (target && unionKey && unionKey.length) {
        let unionId = ''
        unionKey.forEach(key => {
          unionId += '-' + target[key] + '-'
        })
        return unionId
      } else {
        return '--'
      }
    },

    // 延迟构建 pageData 的选中状态,必须设置延迟状态,否则会多调用一次 selectionChange 的回调,导致选中状态不对
    // 因为 table 的 checkbox 选中状态是由 multipleTable 自己维护的,选中的item会存入 multipleSelection 中,
    // 因此需要重新构建 pageData 的选中状态
    // @param pageData 当前页 item 列表
    // @param tableRefs 多选 table ref name
    // @param unionKey 统一标识key集合
    // @param callback timeout 执行完毕后,回调函数
    buildTableSelection (pageData, tableRefs, unionKey, callback) {
      setTimeout(() => {
        if (pageData && this.totalCheckedList && this.$refs[tableRefs]) {
          this.$refs[tableRefs].clearSelection()
          pageData.forEach(pageItem => {
            const specItem = this.totalCheckedList.find(totalItem => {
              return this.buildUnionId(pageItem, unionKey) === this.buildUnionId(totalItem, unionKey)
            })
            if (specItem) {
              this.$refs[tableRefs].toggleRowSelection(pageItem, true)
            }
          })
        }
        if (callback && typeof callback === 'function') {
          callback()
        }
      }, 0)
    },

    // 根据 table 多选的状态来计算所有已选的 list
    // @param pageData 当前页 list
    // @param currentSelection 当前页选中的 list
    // @param unionKey 统一标识key集合
    updateTableSelection (pageData, currentSelection, unionKey) {
      // 如果总记忆中还没有选择的数据,那么就直接取当前页选中的数据,不需要后面一系列计算
      if (this.totalCheckedList.length <= 0) {
        this.totalCheckedList = currentSelection
        return
      }

      // 最新选中的列表,全部加入到totalCheckedList中去
      currentSelection.forEach(newSelectedItem => {
        const specPageItem = this.totalCheckedList.find(totalItem => {
          return this.buildUnionId(newSelectedItem, unionKey) === this.buildUnionId(totalItem, unionKey)
        })
        if (!specPageItem) {
          this.totalCheckedList.push(newSelectedItem)
        }
      })

      // 不在最新选中列表中的item,如果之前在totalCheckedList,则需要清除
      pageData.forEach(pageItem => {
        const specNewSelectedItem = currentSelection.find(newSelectedItem => {
          return this.buildUnionId(newSelectedItem, unionKey) === this.buildUnionId(pageItem, unionKey)
        })
        if (!specNewSelectedItem) {
          const removeIndex = this.totalCheckedList.findIndex(totalItem => {
            return this.buildUnionId(totalItem, unionKey) === this.buildUnionId(pageItem, unionKey)
          })
          if (removeIndex !== -1) {
            this.totalCheckedList.splice(removeIndex, 1)
          }
        }
      })
    }
  }
}

初始化CSS(reset.css)

@charset "utf-8";
html,body {
  width: 100%;
  height: 100%;
}
html {
  background-color: #fff;
  color: #000;
  font-size: 12px;
}

body, ul, ol, dl, dd, h1, h2, h3, h4, h5, h6, figure, form, fieldset, legend, input, textarea, button, p,
blockquote, th, td, pre, xmp {
  margin: 0;
  padding: 0;
}

body, input, textarea, button, select, pre, xmp, tt, code, kbd, samp {
  line-height: 1.5;
  font-family: tahoma, arial, "Hiragino Sans GB", simsun, sans-serif;
}

h1, h2, h3, h4, h5, h6, small, big, input, textarea, button, select {
  font-size: 100%;
}

h1, h2, h3, h4, h5, h6 {
  font-family: tahoma, arial, "Hiragino Sans GB", "微软雅黑", simsun, sans-serif;
}

h1, h2, h3, h4, h5, h6, b, strong {
  font-weight: normal;
}

address, cite, dfn, em, i, optgroup, var {
  font-style: normal;
}

caption {
  text-align: inherit;
}

ul, ol, menu {
  list-style: none;
}

fieldset, img {
  border: 0;
}

img, object, input, textarea, button, select {
  vertical-align: middle;
}

article, aside, footer, header, section, nav, figure, figcaption, hgroup, details, menu {
  display: block;
}

audio, canvas, video {
  display: inline-block;
  *display: inline;
  *zoom: 1;
}

blockquote:before, blockquote:after, q:before, q:after {
  content: "\0020";
}

textarea {
  overflow: auto;
  resize: vertical;
}

input, textarea, button, select, a {
  outline: 0 none;
  border: none;
}

button::-moz-focus-inner, input::-moz-focus-inner {
  padding: 0;
  border: 0;
}

mark {
  background-color: transparent;
}

a, ins, s, u, del {
  text-decoration: none;
}

sup, sub {
  vertical-align: baseline;
}

html {
  overflow-x: hidden;
  height: 100%;
  font-size: 50px;
  -webkit-tap-highlight-color: transparent;
}

body {
  font-family: Arial, "Microsoft Yahei", "Helvetica Neue", Helvetica, sans-serif;
  color: #333;
  font-size: .28em;
  line-height: 1;
  -webkit-text-size-adjust: none;
}

hr {
  height: .02rem;
  margin: .1rem 0;
  border: medium none;
  border-top: .02rem solid #cacaca;
}

a {
  color: #25a4bb;
  text-decoration: none;
}

.el-button {
  height: 30px;
  line-height: 30px;
  padding: 0 14px;
  min-width: 86px;
  font-size: 14px;
  font-family: PingFangSC-Regular;
  font-weight: 400;
  border: 1px solid #256EFF;
  color: #256EFF;
  box-sizing: border-box;
  border-radius: 3px;
}

.el-button:hover {
  background: #D0DFFF;
  color: #256EFF;
}

.el-dialog .el-dialog__footer .el-button {
  border-radius: 1px;
}

.el-button--primary {
  color: #fff;
  background: #256EFF;
  border: 1px solid #256EFF;
}

.el-button--primary:hover {
  background: #1A63F5;
  color: #fff;
}

.el-dialog .el-dialog__footer .el-button {
  border-radius: 1px;
}

.el-button.el-button--text, .el-button.el-button--text:hover {
  border-radius: 1px;
  min-width: 0;
  border: none;
  background: none;
}

.el-button.el-button--text:hover {
  color: rgba(37, 110, 255, 0.8);
}

.el-dialog .el-dialog__header {
  text-align: center;
}

.el-form-item__content {
  line-height: 0;
}

.el-table {
  overflow: inherit;
}

.el-table a:hover {
  color: rgba(37, 110, 255, 0.8);
}

.el-table a {
  color: #256EFF;
  text-decoration: none;
  font-size: 12px;
}

.el-table td {
  padding: 0;
}

.el-table .cell {
  padding: 12px 15px 12px;
  color: #333333;
  font-weight: 400;
  box-sizing: border-box;
}

.el-table th.is-leaf {
  border-bottom: none;
}

.el-table .el-table__header-wrapper {
  border-top: 1px solid #DCDEE0;
  border-bottom: 1px solid #DCDEE0;
}

.el-table .el-table__header th {
  padding: 0;
  background-color: #F2F4F7;
}

.el-table .el-table__header tr th:first-child {
  border-left: 1px solid #DCDEE0;
}

.el-table .el-table__header tr th:last-child {
  border-right: 1px solid #DCDEE0;
}

.el-table .el-table__header .cell {
  padding: 4px 15px;
  font-size: 14px;
}

.el-table .el-table__body-wrapper {
  border-left: 1px solid #DCDEE0;
  border-right: 1px solid #DCDEE0;
}

.el-table thead th, .el-table thead.is-group th {
  background: #fafafa;
  color: #666;
}

.el-table .el-table__body-wrapper {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  box-sizing: border-box;
}

.el-table .el-table__body .cell {
  font-size: 12px;
}

.el-pagination {
  color: #333333;
  font-weight: 400;
  padding: 0;
  text-align: right;
  margin-top: 20px;
}

.el-pagination .el-pager li {
  height: 30px;
  line-height: 30px;
}

.el-pagination .el-pager li.active {
  color: white;
  background: #256EFF;
  min-width: 20px;
  height: 20px;
  line-height: 21px;
  margin: 3px 7.75px 0 7.75px;
  border-radius: 10px;
}

.el-dialog__footer {
  padding: 0 20px 20px;
  text-align: right;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

.el-checkbox:last-child {
  margin-right: 0;
}

.el-checkbox {
  color: #333333;
  font-weight: 400;
  margin-right: 20px;
}

.el-checkbox__input.is-checked .el-checkbox__inner, .el-checkbox__input.is-indeterminate .el-checkbox__inner {
  background-color: #256EFF;
  border-color: #256EFF;
}

.el-checkbox__inner {
  border: 1px solid #999999;
  border-radius: 1px;
  width: 16px;
  height: 16px;
  background-color: #ffffff;
}

.el-checkbox__inner:after {
  border: 1px solid #ffffff;
  border-left: none;
  border-top: none;
  height: 8px;
  left: 4px;
  position: absolute;
  top: 1px;
  width: 4px;
}

.el-radio {
  color: #333333;
  text-align: left;
  font-weight: 400;
  margin-right: 20px;
  cursor: pointer;
}

.el-radio__inner {
  border: 1px solid #999999;
  width: 18px;
  height: 18px;
  background-color: #ffffff;
}

.el-radio__inner:after {
  width: 10px;
  height: 10px;
  background-color: #256EFF;
}

.el-radio__input:hover {
  color: #256EFF;
}

.el-radio__label {
  font-size: 14px;
  line-height: 20px;
  padding-left: 4px;
}

.el-radio__input.is-checked .el-radio__inner {
  border-color: #256EFF;
  background: #ffffff;
}

::-webkit-scrollbar {
  width: 0;
  height: 0;
  background-color: rgba(0, 0, 0, 0);
}

/*定义滚动条轨道 内阴影+圆角*/
::-webkit-scrollbar-track {
  -webkit-box-shadow: inset 0 0 1px rgba(0, 0, 0, 0);
  border-radius: 10px;
  background-color: rgba(0, 0, 0, 0);
}

::-webkit-scrollbar-track:hover {
  -webkit-box-shadow: inset 0 0 1px rgba(239, 239, 239, 239);
  border-radius: 10px;
  background-color: rgba(239, 239, 239, 239);
}

/*定义滑块 内阴影+圆角*/
::-webkit-scrollbar-thumb {
  border-radius: 10px;
  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
  background-color: #114D71;
}

Hero.json数据

{
  "status": true,
  "totalCount": 42,
  "data": [
    {
      "id": 1,
      "name": "上官婉儿",
      "location": "法师 / 刺客",
      "specialty": "爆发 / 突进",
      "skill": ["笔阵", "篆法·疾势", "飞白·藏锋", "章草·横鳞"],
      "price": 13888
    }, {
      "id": 2,
      "name": "王昭君",
      "location": "法师",
      "specialty": "控制 / 冰冻",
      "skill": ["冰封之心", "凋零冰晶", "禁锢寒霜", "凛冬已至"],
      "price": 8888
    }, {
      "id": 3,
      "name": "老夫子",
      "location": "战士",
      "specialty": "突进",
      "skill": ["师道尊严", "圣人训诫", "举一反三", "圣人之威"],
      "price": 8888
    }, {
      "id": 4,
      "name": "狄仁杰",
      "location": "射手",
      "specialty": "",
      "skill": ["迅捷", "六令追凶", "逃脱", "王朝密令"],
      "price": 8888
    }, {
      "id": 5,
      "name": "墨子",
      "location": "法师 / 战士",
      "specialty": "控制 / 护盾",
      "skill": ["兼爱非攻", "和平漫步", "机关重炮", "墨守成规"],
      "price": 8888
    }, {
      "id": 6,
      "name": "盘古",
      "location": "战士",
      "specialty": "突进 / 收割",
      "skill": ["盘古斧", "狂怒突袭", "压制之握", "开天辟地", "聚合为一"],
      "price": 13888
    }, {
      "id": 7,
      "name": "猪八戒",
      "location": "坦克",
      "specialty": "团控 / 回复",
      "skill": ["毫发无伤", "肉弹蹦床", "倒打一耙", "圈养时刻"],
      "price": 13888
    },
    {
      "id": 8,
      "name": "伽罗",
      "location": "射手",
      "specialty": "远程消耗 / 团队",
      "skill": ["破魔之箭", "渡灵之箭", "静默之箭", "纯净之域"],
      "price": 13888
    }, {
      "id": 9,
      "name": "李信",
      "location": "战士",
      "specialty": "突进 / 团控",
      "skill": ["灰暗利刃", "急速突进", "强力斩击", "力量觉醒·光", "力量觉醒·暗"],
      "price": 13888
    }, {
      "id": 10,
      "name": "云中君",
      "location": "刺客 / 战士",
      "specialty": "突进 / 收割",
      "skill": ["云间游", "天隙鸣", "若英·华彩", "风雷引"],
      "price": 13888
    }, {
      "id": 11,
      "name": "瑶",
      "location": "辅助",
      "specialty": "团队增益",
      "skill": ["山鬼·白鹿", "若有人兮", "风飒木萧", "独立兮山之上"],
      "price": 13888
    }, {
      "id": 12,
      "name": "米莱狄",
      "location": "法师",
      "specialty": "持续输出 / 推进",
      "skill": ["机械仆从", "空中力量", "强制入侵", "浩劫磁场"],
      "price": 13888
    }, {
      "id": 13,
      "name": "狂铁",
      "location": "战士",
      "specialty": "突进 / 团控",
      "skill": ["无畏战车", "碎裂之刃", "强袭风暴", "力场压制"],
      "price": 13888
    }, {
      "id": 14,
      "name": "斐擒虎",
      "location": "刺客 / 战士",
      "specialty": "远程消耗 / 收割",
      "skill": ["寸劲", "冲拳式", "气守式", "虎啸风生"],
      "price": 13888
    },
    {
      "id": 15,
      "name": "明世隐",
      "location": "辅助",
      "specialty": "团队增益",
      "skill": ["大吉大利", "临卦·无忧", "师卦·飞翼", "泰卦·长生"],
      "price": 13888
    }, {
      "id": 16,
      "name": "沈梦溪",
      "location": "法师",
      "specialty": "消耗 / 加速",
      "skill": ["暴躁节奏", "猫咪炸弹", "正常操作", "综合爆款"],
      "price": 13888
    }, {
      "id": 17,
      "name": "梦奇",
      "location": "战士 / 坦克",
      "specialty": "远程消耗 / 团控",
      "skill": ["食梦", "梦境萦绕", "梦境挥洒", "梦境漩涡"],
      "price": 13888
    }, {
      "id": 18,
      "name": "奕星",
      "location": "法师",
      "specialty": "消耗 / 团控",
      "skill": ["气合", "定式·镇神", "定式·倚盖", "天元"],
      "price": 13888
    }, {
      "id": 19,
      "name": "百里守约",
      "location": "刺客 / 射手",
      "specialty": "远程消耗",
      "skill": ["瞄准", "静谧之眼", "狂风之息", "逃脱"],
      "price": 13888
    }, {
      "id": 20,
      "name": "百里玄策",
      "location": "刺客",
      "specialty": "突进 / 收割",
      "skill": ["*序章", "神乎钩镰", "梦魇钩锁", "瞬镰闪"],
      "price": 13888
    }, {
      "id": 21,
      "name": "鲁班大师",
      "location": "辅助",
      "specialty": "",
      "skill": ["稷下科技", "立即清扫", "助手驰援", "强力收纳"],
      "price": 13888
    },
    {
      "id": 22,
      "name": "大乔",
      "location": "辅助",
      "specialty": "团队增益",
      "skill": ["川流不息", "鲤跃之潮", "宿命之海", "绝断之桥", "漩涡之门"],
      "price": 13888
    }, {
      "id": 23,
      "name": "曜",
      "location": "战士",
      "specialty": "",
      "skill": ["星辰之赐", "裂空斩", "逐星", "归尘"],
      "price": 13888
    }, {
      "id": 24,
      "name": "西施",
      "location": "法师",
      "specialty": "控制 / 距离增伤",
      "skill": ["少女的把戏", "纱缚之印", "幻纱之灵", "心无旁骛"],
      "price": 13888
    }, {
      "id": 25,
      "name": "蒙犽",
      "location": "射手",
      "specialty": "远程消耗",
      "skill": ["炽热浑天", "狂轰火线", "爆裂重炮", "飞弹援袭"],
      "price": 13888
    }, {
      "id": 26,
      "name": "东皇太一",
      "location": "辅助 / 坦克",
      "specialty": "回复 / 持续控制",
      "skill": ["暗冕之噬", "日蚀祭典", "曜龙烛兆", "堕神契约"],
      "price": 13888
    }, {
      "id": 27,
      "name": "太乙真人",
      "location": "辅助 / 坦克",
      "specialty": "复活 / 团队增益",
      "skill": ["黄金闪闪", "意外事故", "第三只手", "大变活人"],
      "price": 13888
    }, {
      "id": 28,
      "name": "蔡文姬",
      "location": "辅助",
      "specialty": "团队增益 / 回复",
      "skill": ["长歌行", "思无邪", "胡笳乐", "忘忧曲"],
      "price": 13888
    }, {
      "id": 29,
      "name": "干将莫邪",
      "location": "法师",
      "specialty": "爆发 / 超远视距",
      "skill": ["比翼同心", "护主邪冢", "雌雄双剑·近", "雌雄双剑·远", "剑来"],
      "price": 13888
    }, {
      "id": 30,
      "name": "杨玉环",
      "location": "法师 / 辅助",
      "specialty": "持续输出 / 治疗",
      "skill": ["惊鸿调", "霓裳曲", "胡旋乐", "长恨歌", "惊鸿·清平"],
      "price": 13888
    }, {
      "id": 31,
      "name": "嫦娥",
      "location": "法师 / 坦克",
      "specialty": "持续输出 / 法力",
      "skill": ["月盈", "月辰", "月璇", "月芒"],
      "price": 13888
    }, {
      "id": 32,
      "name": "刘备",
      "location": "战士",
      "specialty": "突进 / 收割",
      "skill": ["强化霰弹", "双重射击", "身先士卒", "以德服人"],
      "price": 13888
    }, {
      "id": 33,
      "name": "兰陵王",
      "location": "刺客",
      "specialty": "突进 / 收割",
      "skill": ["秘技·极意", "秘技·分身", "秘技·影蚀", "秘技·暗袭", "秘技·隐匿"],
      "price": 13888
    }, {
      "id": 34,
      "name": "露娜",
      "location": "战士 / 法师",
      "specialty": "突进 / 收割",
      "skill": ["月光之舞", "弦月斩", "炙热剑芒", "新月突击"],
      "price": 13888
    }, {
      "id": 35,
      "name": "貂蝉",
      "location": "法师 / 刺客",
      "specialty": "持续输出 / 真伤",
      "skill": ["语·花印", "落·红雨", "缘·心结", "绽·风华"],
      "price": 13888
    }, {
      "id": 36,
      "name": "达摩",
      "location": "战士 / 坦克",
      "specialty": "突进 / 团控",
      "skill": ["真言·心经", "真言·无相", "真言·明王", "真言·普渡"],
      "price": 13888
    }, {
      "id": 37,
      "name": "马可波罗",
      "location": "射手",
      "specialty": "远程消耗",
      "skill": ["连锁反应", "华丽左轮", "漫游之枪", "*弹幕"],
      "price": 13888
    }, {
      "id": 38,
      "name": "赵云",
      "location": "战士 / 刺客",
      "specialty": "突进",
      "skill": ["龙鸣", "惊雷之龙", "破云之龙", "天翔之龙"],
      "price": 0
    }, {
      "id": 39,
      "name": "镜",
      "location": "刺客",
      "specialty": "突进 / 收割",
      "skill": ["铸镜", "开锋", "裂空", "见影"],
      "price": 18888
    }, {
      "id": 40,
      "name": "马超",
      "location": "战士 / 刺客",
      "specialty": "突进 / 远程消耗",
      "skill": ["魔影突袭", "萧索之刃", "日落孤枪", "万刃归鞘"],
      "price": 13888
    }, {
      "id": 41,
      "name": "诸葛亮",
      "location": "法师",
      "specialty": "爆发 / 收割",
      "skill": ["策谋之刻", "东风破袭", "时空穿梭", "元气弹"],
      "price": 18888
    }, {
      "id": 42,
      "name": "雅典娜",
      "location": "战士",
      "specialty": "突进",
      "skill": ["真身觉醒", "神圣进军", "贯穿之枪", "敬畏圣盾"],
      "price": 18888
    }
  ]
}

本文地址:https://blog.csdn.net/fu983531588/article/details/107465009