按两个字段对计算对象和数组进行排序

我从 API 中提取信息,该 API 返回以下格式的数据:


[

 {

  "id": 173,

  "date": "2020-12-10T16:05:30",

  "date_gmt": "2020-12-10T16:05:30",

  "guid": {},

  "modified": "2020-12-10T16:05:31",

  "modified_gmt": "2020-12-10T16:05:31",

  "slug": "test",

  "status": "publish",

  "type": "place",

  "link": "http://localhost:81/test/",

  "title": {},

  "content": {},

  "featured_media": 0,

  "template": "",

  "acf": {

    "address": {

    "address": "123 Test Address",

    "street_number": "123",

    "street_name": "Test Address",

    "city": "Philipsburg",

    "state": "Sint Maarten",

    "country": "Sint Maarten",

    "country_short": "SX"

  },

  "header": {}

  },

  "_links": {}

 },

 etc

]

我将其存储在 Vuex 中,并通过以下方式组织信息:


computed: {

    resorts() {

      const resorts = {};

      if (this.$store.state.loading === false) {

        this.$store.state.posts.forEach((post) => {

          const c = post.acf.address.country;

          const s = post.acf.address.state;

          //const t = post.title;

          resorts[c] = resorts[c] || {};

          resorts[c][s] = resorts[c][s] || [];

          resorts[c][s].push(post);

        });

      }

      return resorts;

    },

}

v-for我在这样的循环中显示信息(Pug):


section.united-states(v-for="(country, index) in resorts" v-if="index==='United States'")

  h1(v-html="index")

  section.state(v-for="(state, subIndex) in country" :key="subIndex" :class="subIndex.toLowerCase()")

    h5(v-html="subIndex")

    ul

      li(v-for="post, resort) in state")

        listing(:id="post.id" :slug="post.slug" :image="post.acf.header" :title="post.title.rendered" :city="post.acf.address.city" :street="post.acf.address.street_name_short")

这样可以正确显示信息。但是,我需要它按Country、State、City名称的字母顺序排列。我尝试对其进行排序并尝试lodash.orderBy,但无法组织列表。从 Chrome 中的 Vue 检查器选项卡中,计算出的国家和州(不是城市)似乎是按字母顺序排列的。有什么建议么?


千万里不及你
浏览 93回答 1
1回答

慕容708150

一种解决方案是先对帖子进行排序,然后再按地址进行分组。使用Array.prototype.sort()和String.prototype.localeCompare(),创建一个实用程序(名为sortPosts())以在计算的 prop 中使用,该实用程序将按country, state, city, thenstreet_name字段对帖子进行排序:const sortPosts = posts =>  posts.slice().sort((a,b) => {    const countryA = a.acf.address.country    const countryB = b.acf.address.country    const stateA = a.acf.address.state    const stateB = b.acf.address.state    const cityA = a.acf.address.city || '' // can be undefined in Google Maps API    const cityB = b.acf.address.city || '' // can be undefined in Google Maps API    const streetA = a.acf.address.street_name    const streetB = b.acf.address.street_name    return countryA.localeCompare(countryB) || stateA.localeCompare(stateB) || cityA.localeCompare(cityB) || streetA.localeCompare(streetB)  })现在,我们将使用您已有的相同逻辑对这些帖子进行分组,但我们必须将局部resorts变量的数据类型从更改Object为Map,因为Object迭代并不总是遵循插入顺序,这会破坏排序sortPosts():export default {  computed: {    resorts() {      // BEFORE:      // const resorts = {};      const resorts = new Map();      if (this.$store.state.loading === false) {        sortPosts(this.$store.state.posts).forEach((post) => {          const c = post.acf.address.country;          const s = post.acf.address.state;          // BEFORE:          // resorts[c] = resorts[c] || {};          // resorts[c][s] = resorts[c][s] || [];          // resorts[c][s].push(post);          if (!resorts.has(c)) {            resorts.set(c, new Map());          }          const stateMap = resorts.get(c);          if (!stateMap.has(s)) {            stateMap.set(s, []);          }          stateMap.get(s).push(post);        });      }      return resorts    },  }}从 v2.6.12 开始,v-for不支持Maps,因此使用Array.from()使其可迭代v-for:<section v-for="[country, countryData] in Array.from(resorts)" :key="country">  <h1 v-html="country" />  <section class="state" v-for="[state, posts] in Array.from(countryData)" :key="state" :class="state.toLowerCase()">    <h5 v-html="state" />    <ul>      <li v-for="(post, resort) in posts" :key="post.id">        ...      </li>    </ul>  </section></section>演示
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript