首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Nuxt + Vue 3:使所有表列可排序并隔离排序单击操作,只需更改已排序列上的图标

Nuxt + Vue 3:使所有表列可排序并隔离排序单击操作,只需更改已排序列上的图标
EN

Stack Overflow用户
提问于 2020-10-30 15:30:51
回答 1查看 120关注 0票数 0

我有一个表,其中所有的列都是可排序的,排序函数工作得很好,但我很难弄清楚如何让我的图标仅针对我选择排序的列改变方向。使用我的方法,每次我点击一个图标,所有其他图标也会改变方向,我知道为什么会发生这种情况(我只是根据currentSortDir状态属性(asc或desc)计算以显示或不显示图标,我还知道我必须给每一列某种名称来计算我的状态属性currentSort (这将具有当前排序列的名称),但是我不知道如何使用v-if之类的东西来工作,也许我必须改变我的模板结构?我没有使用多类方法来更改排序图标,而是使用两个svg,它们将根据排序方法有条件地显示。

模板:

代码语言:javascript
复制
<template>
  <div>
    <h1 class="text-center font-semibold">Agents</h1>
    <div class="px-4 mt-6">
      <table class="text-left w-full">
        <thead>
          <tr>
            <th class="px-4 py-2" @click="sort('email')">
              <div
                class="bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center"
              >
                <span>
                  <IconBase
                    v-if="currentSortDir === 'asc'"
                    class="fill-current w-4 h-4 mr-2"
                    icon-color="rgba(0,0,0,0.80)"
                    icon-name="asc"
                    ><IconAsc
                  /></IconBase>
                  <IconBase
                    v-if="currentSortDir === 'desc'"
                    class="fill-current w-4 h-4 mr-2"
                    icon-color="rgba(0,0,0,0.80)"
                    icon-name="desc"
                    ><IconDesc
                  /></IconBase>
                </span>
                <span>Name</span>
              </div>
            </th>
            <th class="px-4 py-2" @click="sort('email')">
              <div
                class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center"
              >
                <span>
                  <IconBase
                    v-if="currentSortDir === 'asc'"
                    class="fill-current w-4 h-4 mr-2"
                    icon-color="rgba(0,0,0,0.80)"
                    icon-name="asc"
                    ><IconAsc
                  /></IconBase>
                  <IconBase
                    v-if="currentSortDir === 'desc'"
                    class="fill-current w-4 h-4 mr-2"
                    icon-color="rgba(0,0,0,0.80)"
                    icon-name="desc"
                    ><IconDesc
                  /></IconBase>
                </span>
                <span>Email</span>
              </div>
            </th>
            <th class="px-4 py-2" @click="sort('wsConnectionStatus')">
              <div
                class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center"
              >
                <span>
                  <IconBase
                    v-if="currentSortDir === 'asc'"
                    class="fill-current w-4 h-4 mr-2"
                    icon-color="rgba(0,0,0,0.80)"
                    icon-name="checkmark"
                    ><IconAsc
                  /></IconBase>
                  <IconBase
                    v-if="currentSortDir === 'desc'"
                    class="fill-current w-4 h-4 mr-2"
                    icon-color="rgba(0,0,0,0.80)"
                    icon-name="checkmark"
                    ><IconDesc
                  /></IconBase>
                </span>
                <span>WS</span>
              </div>
            </th>
            <th class="px-4 py-2" @click="sort('status')">
              <div
                class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center"
              >
                <IconBase
                  v-if="currentSortDir === 'asc'"
                  class="fill-current w-4 h-4 mr-2"
                  icon-color="rgba(0,0,0,0.80)"
                  icon-name="checkmark"
                  ><IconAsc
                /></IconBase>
                <IconBase
                  v-if="currentSortDir === 'desc'"
                  class="fill-current w-4 h-4 mr-2"
                  icon-color="rgba(0,0,0,0.80)"
                  icon-name="checkmark"
                  ><IconDesc
                /></IconBase>
                <span>Status</span>
              </div>
            </th>
            <th class="px-4 py-2" @click="sort('priorityRank')">
              <button
                class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center"
              >
                <IconBase
                  v-if="currentSortDir === 'asc'"
                  class="fill-current w-4 h-4 mr-2"
                  icon-color="rgba(0,0,0,0.80)"
                  icon-name="checkmark"
                  ><IconAsc
                /></IconBase>
                <IconBase
                  v-if="currentSortDir === 'desc'"
                  class="fill-current w-4 h-4 mr-2"
                  icon-color="rgba(0,0,0,0.80)"
                  icon-name="checkmark"
                  ><IconDesc
                /></IconBase>
                <span>Rank</span>
              </button>
            </th>
            <th class="px-4 py-2" @click="sort('numberChats')">
              <button
                class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center"
              >
                <IconBase
                  v-if="currentSortDir === 'asc'"
                  class="fill-current w-4 h-4 mr-2"
                  icon-color="rgba(0,0,0,0.80)"
                  icon-name="checkmark"
                  ><IconAsc
                /></IconBase>
                <IconBase
                  v-if="currentSortDir === 'desc'"
                  class="fill-current w-4 h-4 mr-2"
                  icon-color="rgba(0,0,0,0.80)"
                  icon-name="checkmark"
                  ><IconDesc
                /></IconBase>
                <span>Number Chats</span>
              </button>
            </th>
            <th class="px-4 py-2" @click="sort('currentMaxChats')">
              <button
                class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center"
              >
                <IconBase
                  v-if="currentSortDir === 'asc'"
                  class="fill-current w-4 h-4 mr-2"
                  icon-color="rgba(0,0,0,0.80)"
                  icon-name="checkmark"
                  ><IconAsc
                /></IconBase>
                <IconBase
                  v-if="currentSortDir === 'desc'"
                  class="fill-current w-4 h-4 mr-2"
                  icon-color="rgba(0,0,0,0.80)"
                  icon-name="checkmark"
                  ><IconDesc
                /></IconBase>
                <span>Max Current</span>
              </button>
            </th>
          </tr>
        </thead>
        <tbody>
          <Agent
            v-for="(agent, index) in sortedAgents"
            :key="index"
            :agent="agent"
            :data-index="index"
          ></Agent>
        </tbody>
      </table>
    </div>
  </div>
</template>

状态:

代码语言:javascript
复制
<script>
import { mapState } from 'vuex'
import IconBase from '@/components/Icons/IconBase.vue'
import IconAsc from '@/components/Icons/IconAsc.vue'
import IconDesc from '@/components/Icons/IconDesc.vue'
import Agent from '@/components/Agent.vue'
export default {
  components: {
    Agent,
    IconBase,
    IconAsc,
    IconDesc,
  },
  async fetch({ store, error }) {
    try {
      await store.dispatch('agents/fetchAgents')
    } catch (e) {
      error({
        statusCode: 503,
        message: 'Unable to fetch events at this time. Please try again later',
      })
    }
  },
  data() {
    return {
      currentSort: 'email',
      currentSortDir: 'asc',
    }
  },
  computed: {
    ...mapState({
      agents: (state) => state.agents.agents,
    }),
    sortedAgents() {
      return this.agents.slice().sort((a, b) => {
        let modifier = 1
        if (this.currentSortDir === 'desc') modifier = -1
        if (a[this.currentSort] < b[this.currentSort]) return -1 * modifier
        if (a[this.currentSort] > b[this.currentSort]) return 1 * modifier
        return 0
      })
    },
  },
  methods: {
    sort(columnToSort) {
      if (columnToSort === this.currentSort) {
        this.currentSortDir = this.currentSortDir === 'asc' ? 'desc' : 'asc'
      }
      this.currentSort = columnToSort
    },
  },
}
</script>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-30 17:43:32

假设一次只有一列可以升序,只需将currentSort添加到条件中即可。

代码语言:javascript
复制
<IconBase
  v-if="currentSortDir === 'asc' && currentSort === 'email'"
  class="fill-current w-4 h-4 mr-2"
  icon-color="rgba(0,0,0,0.80)"
  icon-name="checkmark"
  >
  <IconAsc/>
</IconBase>
<IconBase
  v-else
  class="fill-current w-4 h-4 mr-2"
  icon-color="rgba(0,0,0,0.80)"
  icon-name="checkmark"
  >
  <IconDesc/>
</IconBase>

请注意desc图标中的v-else

关于双击问题,请尝试以下内容:

代码语言:javascript
复制
if (columnToSort === this.currentSort) {
  this.currentSortDir = this.currentSortDir === 'asc' ? 'desc' : 'asc'
} else {
  this.currentSortDir = 'asc'
}
this.currentSort = columnToSort
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64604224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档