根据数据中的参数值渲染组件

时间:2019-08-09 15:47:15

标签: javascript vue.js

我正在加载使用“待办事项列表”功能创建的数据,并且用户可以按自己想要的方式订购列表。返回的数据与用户保存的顺序不符。数据确实包含带有订单索引的数据参数。

const userGoals = {
  "Alen": {
    order: 2,
    goals: ["Learn JavaScript.", "Learn VueJS.", "Learn React."]
  },
  "Cole": {
    order: 1,
    goals: ["Learn JavaScript.", "Learn to paint.", "Learn Karate."]
  },
  "Lucas": {
    order: 0,
    goals: ["Learn to draw.", "Build a canoe.", "Learn to paint."]
  }
}

Vue.component('goal-list', {
  props: {
    users: Object
  },
  template: `
	<div>
		<ol v-for="(user, index) in users">
			<strong>{{ user.order }} {{ index }}</strong>
			<li v-for="goal in user.goals"> {{ goal }}</li>
		</ol>
	</div>
	`
});

var list = new Vue({
  el: '#userList',
  data: {
    users: userGoals
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<!doctype html>
<html lang="en">

<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <title>Goals</title>
</head>

<body>
  <h1>Goals</h1>

  <div id="userList">
    <goal-list :users="users"></goal-list>
  </div>
</body>

</html>

组件渲染顺序应为

  1. 卢卡斯
  2. 科尔
  3. 艾伦

基于每个用户对象中的order参数。

2 个答案:

答案 0 :(得分:1)

由于Ohgodwhy!

,我最终完成了此操作

我仍然使用计算属性,因为我不需要在渲染后再次对数据进行排序,并且据我了解,方法对于单击事件之类的方法更好。

由于我在对象内部有对象,因此我不得不稍微重组数据以使排序工作。

JSFiddle example

const userGoals = {
  "Alen": {
    order: 1,
    goals: ["Learn JavaScript.", "Learn VueJS.", "Learn React."]
  },
  "Lucas": {
    order: 2,
    goals: ["Learn to draw.", "Build a canoe.", "Paint a painting."]
  },
  "Cole": {
    order: 3,
    goals: ["Learn JavaScript.", "Learn to paint.", "Learn Karate."]
  },
  "Tahir": {
    order: 0,
    goals: ["Lift something heavy.", "Lift something even heavier!", "Relax."]
  }
}

Vue.component('goal-list', {
  props: {
    users: Object
  },
  template: `
	<div>
		<ol v-for="(user, index) in sortedUsers">
			<strong>{{ user.order }} {{ user.key }}</strong>
			<li v-for="goal in user.goals"> {{ goal }}</li>
		</ol>
	</div>
	`,
  computed: {
    sortedUsers() {
      return Object.keys(this.users)
        .map(i => {
          this.$set(this.users[i], 'key', i)
          return this.users[i]
        }).sort((a, b) => {
          return a.order > b.order ? 1 : (a.order < b.order ? -1 : 0)
        });
    }
  }
});

var list = new Vue({
  el: '#userList',
  data() {
    return {
      users: userGoals
    }
  }
});
<!doctype html>
<html lang="en">

<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <title>Goals</title>
</head>

<body>
  <h1>Goals</h1>

  <div id="userList">
    <goal-list :users="users"></goal-list>
  </div>

  <!-- Optional JavaScript -->
  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous">
  </script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous">
  </script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous">
  </script>
  <!-- Vue.js -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>

  <!-- Custom JavaScript -->
  <script src="/script.js"></script>"
</body>

</html>

答案 1 :(得分:0)

您可以在用户的​​sort属性上使用order,然后从计算出的吸气剂中返回该值:

computed: {
  sortedUsers: {
    get: function() {
      return this.users.sort((a, b) => {
        return a.order > b.order ? 1 : (a.order < b.order ? -1 : 0)
      })
    }
  }
}

然后更新您的组件以使用此getter而不是纯数据对象。