Vue-3 排序 List A-Z of v-for in v-for

Vue-3 sort List A-Z of v-for in v-for

我正在尝试按字母顺序(即 A-Z)对以下 v-for 列表进行排序。我知道以下计算 属性 方法用于按字母顺序对 v-for 列表进行排序;

sortedList() {
            const res = []
            this.itemtwo.song.forEach(data => {
                data.albums.forEach(album => {
                    album.songsinalbum.forEach((song) => {
                        res.push(song)
                    })
                })
            })

            return res.sort((a, b) => {
                if (a.song > b.song) return 1
                else return -1
            })
        }

但是,我需要在 v-for 中的 v-for 上完成此操作,因为我需要第一个 v-for 的数据供 vue-router 使用。如果我使用上面的计算 属性,我无法从我的数据结构层次结构中的更高层访问相应的数据;

这是我的数据结构;

export const datatwo = [
{id: "1", artist: "Yaakov Shwekey", dateadded: "07/04/2022", artistroute: "/yaakovshwekey", 
albums: [{album:'Shomati', songsinalbum: [
        { song : 'MaMaMa', keys: [
            {key: "Am"},
            {key: "Em"}
        ]}, 
        { song : 'Al Naharos Bavel', keys: [
            {key: "Am"},
            {key: "Em"}
        ]},  
        { song : 'Levinyomin', keys: [
            {key: "Am"},
            {key: "Em"}
        ]}, ]},   

        {album : 'Simcha', songsinalbum: [
            { song : 'Kolot', keys: [
                {key: "Am"},
                {key: "Em"}
            ]}, 
            { song : 'Kalu Kol Hakotzim', keys: [
                {key: "Am"},
                {key: "Em"}
            ]},  
            { song : 'Vehi Sheamdah', keys: [
                {key: "Am"},
                {key: "Em"}
            ]}, ]},   ]
},]

这是我现在的 v-for;

        <div v-for="album in datanew" :key="album.id">
                <div class="" v-for="(item, i) in album.albums" :key="i">
                    <div class="" v-for="(itemtwo, i) in item.songsinalbum" :key="i">
                        <router-link v-if="albumname == item.album" class="routerlink" :key="item.songsinalbum" :to="'/albumselected/' + item.album + '/artist/' + album.artist">
                            <div class="routerlink button">{{itemtwo.song}}</div>
                        </router-link>
                    </div>
                </div>
            </div>

不确定这是否可行,非常感谢帮助。谢谢。

理论上可以使用

<div
        class=""
        v-for="(itemtwo, i) in item.songsinalbum.sort((a, b) =>
          a.song > b.song ? 1 : -1
        )"
        :key="i"
      >
        <router-link
          class="routerlink"
          :key="item.songsinalbum"
          :to="'/albumselected/' + item.album + '/artist/' + album.artist"
        >
          <div class="routerlink button">{{ itemtwo.song }}</div>
        </router-link>
      </div>

直接在模板中。或者将排序函数提取到这样的方法中:Template:

<div
        class=""
        v-for="(itemtwo, i) in sortFunction(item.songsinalbum)"
        :key="i"
      >

脚本(为了安全起见,我会在这里使用打字稿):

const sortFunction = (arr) => {
      return arr.sort((a, b) => {
        if (a.song > b.song) return 1;
        else return -1;
      });
    };

最后,可能最好的方法是在尝试时将您正在寻找的 v-for 模仿到计算方法中。计算缓存,因此它仅在输入更改时更改。我不确定使用常规方法解决方案会多久重新渲染一次。我使用计算函数想出了这个解决方案:

您需要创建几个包装器组件来向下钻取以获取所需的正确项目,即歌曲。我为每一步都创建了一个包装器组件。这可能不是最好的解决方案,但我想不出更好的解决方案在每种情况下,您都需要每个数组的上下文才能正确排序。我相信此解决方案可能是最 性能最好的 ,但并不优雅。我没有在 Whosebug 上显示每个包装器,而是提交了这个沙箱。 https://codesandbox.io/s/quirky-cartwright-wfo1ot 在每一个中,您都可以看到我深入了解了每个自己的上下文。您可以根据自己的喜好设置样式,但最后,每张专辑的专辑都会正确地按字母顺序对歌曲进行排序。然而,即使这个解决方案可能通过简单地在模板中排序而被击败,如果过程太长,我宁愿清理排序函数并在模板中使用它。