v-用于在单独的 div 中呈现每个对象的子项 - 防止 .sort

v-for rendering children of each object in separate div - preventing .sort

我在 vue-3;

中遇到了以下 "bug"

在我解释之前,这是我的数据structure/hierarchy;

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"}
            ]}, ]},   ]
},
{id: "2", artist: "Baruch Levine", dateadded: "07/04/2022", artistroute: "/baruchlevine", 
albums: [
    {album : 'Vezkani', songsinalbum: [
        { song : 'Vezakani', keys: [
            {key: "Am"},
            {key: "Em"}
        ]}, 
        { song : 'Bitchu', keys: [
            {key: "Am"},
            {key: "Em"}
        ]},  
        { song : 'Vhu', keys: [
            {key: "Am"},
            {key: "Em"}
        ]}, ]},   

        {album : 'Touched by a Niggun', songsinalbum: [
            { song : 'Faultche Phony Rebbe', keys: [
                {key: "Am"},
                {key: "Em"}
            ]}, 
            { song : 'Tour of Yerushalayim', keys: [
                {key: "Am"},
                {key: "Em"}
            ]},  
            { song : 'Someones Child', keys: [
                {key: "Am"},
                {key: "Em"}
            ]}, ]},   ]
},
{id: "3", artist: "Simcha Leiner", dateadded: "10/04/2022", artistroute: "/simchaleiner", 
albums: [
    {album : 'Simcha Leiner One', songsinalbum: [
        { song : 'Mi Mi Mi', keys: [
            {key: "Am"},
            {key: "Em"}
        ]}, 
        { song : 'Veal Hakol', keys: [
            {key: "Am"},
            {key: "Em"}
        ]},  
        { song : 'Shalom', keys: [
            {key: "Am"},
            {key: "Em"}
        ]}, ]},   

        {album : 'Simcha Leiner Two', songsinalbum: [
            { song : 'Mi Adir', keys: [
                {key: "Am"},
                {key: "Em"}
            ]}, 
            { song : 'Boi Kallah', keys: [
                {key: "Am"},
                {key: "Em"}
            ]},  
            ]},   ]
}
]

现在,我想做的是在不使用 computed property 的情况下在字母列表中显示所有 album 名称,而只是通过在中创建 v-for一个v-for。这样做的原因是因为我需要访问 routerartist 名称。 所以这是我创建的 v-for 循环(排序函数附加到第二个循环(尽管我知道它不是性能最好的!));

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

但是,排序无法正常工作,因为 vue 呈现子对象的方式是通过为每个父对象创建单独的 div,自然 .sort 函数不起作用。 这就是 Vue 呈现上述 v-for;

的方式
        <div class=""><a href="/albumselected/Shomati/artist/Yaakov Shwekey" class="routerlink">
                <div class="routerlink button">Shomati</div>
            </a></div>
        <div class=""><a href="/albumselected/Simcha/artist/Yaakov Shwekey" class="routerlink">
                <div class="routerlink button">Simcha</div>
            </a></div>
    </div>
    <div>
        <div class=""><a href="/albumselected/Touched by a Niggun/artist/Baruch Levine" class="routerlink">
                <div class="routerlink button">Touched by a Niggun</div>
            </a></div>
        <div class=""><a href="/albumselected/Vezkani/artist/Baruch Levine" class="routerlink">
                <div class="routerlink button">Vezkani</div>
            </a></div>
    </div>
    <div>
        <div class=""><a href="/albumselected/Simcha Leiner One/artist/Simcha Leiner" class="routerlink">
                <div class="routerlink button">Simcha Leiner One</div>
            </a></div>
        <div class=""><a href="/albumselected/Simcha Leiner Two/artist/Simcha Leiner" class="routerlink">
                <div class="routerlink button">Simcha Leiner Two</div>
            </a></div>
    </div>

我一直在使用的计算属性是;

sortedSongs() {
        const res = []
        this.datanew.forEach(data => {
            data.albums.forEach(album => {
                res.push(album)
            })
        })


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

开源社区中有没有人对此有解决方案?非常感谢帮助或验证!

在模板中调用 sort 是错误的,因为它会改变数组,更不用说在每次渲染时都会调用它了。

它可以与计算中的原始 datatwo 结构相同,但具有排序数据:

sortedData() {
  return datatwo.map(item => ({
    ...item,
    albums: [...item.albums].sort((a, b) => { /* ... */ })
  }))
}

或将 albums 排序并用作单个列表:

sortedData() {
  return this.datanew.flatMap(item => item.albums.map(album => ({
    ...item,
    ...album
  })))
  .sort((a, b) => {
    if (a.album > b.album) return 1;
    else if (a.album < b.album) return -1;
    else return 0;
  });
}

和使用相同的方式,但模板中没有 sort

sort 应在数组复制时调用以避免突变。