循环中的Vue 2组件访问循环 - 实例/范围问题

时间:2017-02-16 10:37:13

标签: javascript vuejs2 vue-component

我正在制作我的第一个Vue 2组件(在Laravel 5.3应用程序中),但遇到了我花了几个小时试图解决的实例/范围问题,但是无法让它工作!

我的组件生成订单列表,每个订单中都有一个用户列表(顾问)。我希望能够为订单选择用户,然后将用户分配给订单。

我的组件的最新版本看起来像这样;

Vue.component('unassigned-orders', {

    template: `           
        <table id="assignOrder" class="table table-hover">
            <thead>
                // table headers
            </thead>

            <tr v-for="(unassignedOrder, key) in unassignedOrders" 
                                                 :key="unassignedOrder.order_id">
                <td>{{ unassignedOrder.order_id }}</td>
                <td>{{ unassignedOrder.first_name }} {{ unassignedOrder.last_name }}</td>
                <td>{{ unassignedOrder.order_status }}</td>
                <td><select @change="assignAdvisor()">
                    <option  v-for="advisor in advisors" :value="advisor.id" >
                {{ advisor.first_name }} {{ advisor.last_name }}
                    </option>
                </select></td>
                <td><a class="btn btn-default">
                           Set Advisor {{ unassignedOrder.assignTo }}</a></td>
            </tr>
        </table>`,

    data: function() {
        return {
            unassignedOrders: [{'assignTo' : ''}], 
            advisors: ''
        }
    },

    methods: {
        assignAdvisor: function() {
            this.assignTo = event.target.value;
        }
    },


    mounted() {
        axios.get('url').then(response => this.advisors = response.data);
        axios.get('url').then(response => this.unassignedOrders = response.data);
    }
});

我没有收到任何错误,但功能不起作用(我只需要将var assignTo更新为相关订单,我相信我能够完成其余的工作。)

我确信我错过了一些非常简单的事情,任何人都有任何指示?

由于

2 个答案:

答案 0 :(得分:1)

在您的问题评论中进行了一些讨论后,我们能够将您的问题分解为:

  • 您正在呈现项目列表。此列表是一个对象数组。
  • 渲染项目中有一些功能允许您更改阵列中的相应对象。

但是如何更新数组中的相应对象?

以下是演示解决方案的摘要。

&#13;
&#13;
const items = {
  template: `
    <div>
      <ul>
        <li v-for="(item, index) in proxyItems">
          {{ item.name }} - {{ item.option }}
          <select @change="change(index, $event.target.value)">
            <option>No option</option>
            <option>Option 1</option>
            <option>Option 2</option>
          </select>
        </li>
      <ul>
    </div>
  `,
  
  props: {
    items: {
      type: Array,
    },
  },
  
  data() {
    return {
      proxyItems: this.items,
    };
  },
  
  methods: {
    change(index, value) {
      this.proxyItems.splice(index, 1, { ...{}, ...this.proxyItems[index], ...{ option: value } });
      console.log(this.proxyItems);
    },
  },
};

new Vue({
  render(createElement) {
    const props = {
      items: [
        { name: 'Item 1', option: 'No option' },
        { name: 'Item 2', option: 'No option' },
      ],
    };

    return createElement(items, { props });
  },
}).$mount('#app');
&#13;
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div id="app"></div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
</body>
</html>
&#13;
&#13;
&#13;

以下是解决方案的概要:

  • 要更新数组,我们需要找到您要更新的项目的索引,然后更新它。
this.proxyItems.splice(index, 1, { ...{}, ...this.proxyItems[index], ...{ option: value } });
  • 组件实际上是将项目作为值items中的值传递,但不建议您直接改变道具
  

此外,每次更新父组件时,子组件中的所有道具都将使用最新值进行刷新。这意味着您不应该尝试改变子组件内的prop。如果你这样做,Vue会在控制台中警告你。

- https://vuejs.org/v2/guide/components.html#One-Way-Data-Flow

因此,我们在组件的数据方法中创建项目的代理。

{
  props: {
    items: {
      type: Array,
    },
  },

  data() {
    return {
      proxyItems: this.items,
    };
  },
}

items中的所有数据突变都会发生在proxyItems

希望以上内容有助于解决您的问题。不过我会提出一个建议:

  

将列表项分解为自己的组件可能更好。这意味着每个项目都有自己的范围,您不必代理项目,并且您不必通过传播进行复杂的拼接和对象创建。

下面是一个例子。

&#13;
&#13;
const item = {
  template: `
    <li>
      {{ name }} - {{ selectedOption }}
      <select @change="change($event.target.value)">
        <option>No option</option>
        <option>Option 1</option>
        <option>Option 2</option>
      </select>
    </li>
  `,
  
  props: ['name'],
  
  data() {
    return {
      selectedOption: 'No option',
    };
  },
    
  methods: {
    change(value) {
      this.selectedOption = value;
      console.log(this.selectedOption);
    },
  },
};

const items = {
  components: {
    item,
  },

  template: `
    <div>
      <ul>
        <item v-for="item in items" :name="item.name"></item>
      <ul>
    </div>
  `,
  
  props: {
    items: {
      type: Array,
    },
  },
};

new Vue({
  render(createElement) {
    const props = {
      items: [
        { name: 'Item 1', option: 'No option' },
        { name: 'Item 2', option: 'No option' },
      ],
    };

    return createElement(items, { props });
  },
}).$mount('#app');
&#13;
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div id="app"></div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
</body>
</html>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

可能是未分配的订单和顾问是具有自己的getter和setter的复杂组件,因此您可以尝试使用计算属性或观察者。