2017-02-16 117 views
0

我正在製作我的第一個Vue 2組件(在Laravel 5.3應用程序中),但遇到了我花費數小時試圖解決的實例/範圍問題,但僅僅不能讓它工作!Vue 2組件循環訪問循環 - 實例/範圍問題

我的組件生成訂單列表,每個訂單中都有一個用戶列表(顧問)。我希望能夠爲某個訂單選擇一個用戶,然後將該用戶分配給該訂單。

我的組件的最新版本看起來像這樣;

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到相關的訂單,我相信我能推測休息了)。

我相信我錯過了一些非常簡單的東西,任何人都有任何指針?

感謝

+0

簡單瀏覽了一下您的示例代碼,如果你添加屬性'assignTo'由組件的數據方法返回的對象會發生什麼?您可以將該值設置爲null或空字符串。 – wing

+0

我以前曾嘗試過,即在數據函數內自己的行上有'assignTo:'',而不是嵌套在unassignedOrders中,但它具有相同的結果,即沒有任何內容。 – Ash

+0

Ahh okai。我試圖更好地理解你想達到的目標。這是我的解釋 - 如果我錯了,請糾正我。您的組件呈現名爲'unassignedOrders'的項目列表。當未分配順序的'select'發出'change'事件時,它應該設置該順序的'assignTo'屬性。這聽起來是對的嗎? – wing

回答

1

在你的問題的意見經過一番討論後,我們能夠針對您的問題分解到這一點:

  • 您呈現的項目列表。該列表是一個對象數組。
  • 渲染項目中有一些功能允許您更改數組中的相應對象。

但是怎樣才能更新數組中的相應對象呢?

下面是一個演示解決方案的代碼片段。

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');
<!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>

這裏是解決方案的概要:

  • 要更新,我們需要找到您要更新,然後更新該項目的索引的數組。
this.proxyItems.splice(index, 1, { ...{}, ...this.proxyItems[index], ...{ option: value } }); 
  • 組件實際上是通過物品作爲道具items的值,但並不建議您變異道具直接

此外,每次父組件更新後,子組件中的所有道具都將刷新爲最新值。這意味着你不應該試圖改變子組件內的道具。如果你這樣做,Vue會在控制檯中發出警告。

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

因此,我們在創建組件的數據方法的項目的代理。

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

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

items所有數據的突變會發生在proxyItems

希望以上內容有助於解決您的問題。然而,我會提出一個建議:

將您的列表項分解爲它們自己的組件可能會更好。這意味着每個項目都有自己的範圍,您不必代理這些項目,也不需要使用傳播進行復雜的拼接和對象創建。

下面是一個例子。

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');
<!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>

+0

嗨,非常感謝,非常棒的答案!在過去的幾個小時裏,我一直在玩你的第二個建議,並讓它工作。我花了一段時間才弄明白不改變道具的想法(仍然不確定是否擁有它),但它的作用不亞於此。非常感謝 – Ash

0

可能unassignedOrder和顧問是複雜的部件用自己的getter和setter,所以你可以嘗試使用計算機性能或觀察他們。

+0

我不確定你將如何應用觀察者,因爲我不相信你可以有多個相同模型的實例,所以你不能應用模型到選擇(顧問)輸入。或者我誤解了? – Ash