使用computed属性setter和getter更新数据属性

时间:2016-11-29 16:58:52

标签: vue-component vue.js vuejs2

我有以下组件标记

<select id="create-user-roles" class="form-control" v-bind="role">
                                  <option v-for="role in roles" :value="role.id">{{ role.label }}</option>
                              </select>

并拥有以下组件

..........
data() {
      return {
        roles: [
        {name: 'something', id:0 },..,..,..,],
        form: {
            ......
            roles: null,
        }
      }
    },
    computed: {
      role: {
        get: function(){
          if(this.userData == undefined) return null;

          return this.userData.roles[0].id;
        },
        set: function(id) {
          console.log(id);
          var role = this.$data.roles.filter(function(o){
            return o.id === id
          }).name;
            console.log(role);
          this.$data.form.roles = [role];
            console.log(this.form.roles);
        }
      }
    },
...........

在我的组件方法函数中

this.form = Object.assign({}, this.userData)); // userData is a prop passed down from parent with {roles:[{id: 0, name: 'something' }]}

当我更改选择时,它不会使用form.roles setter更新role

事实上似乎没有任何事情被解雇!

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

主要问题是v-bind。如果您希望select元素的值与角色之间存在双向绑定,则需要使用v-model

setter中还有一个错误。这条线

var role = this.$data.roles.filter(function(o){ 
    return o.id === id 
}).name; 

赢了,因为filter会返回列表,而不是该列表中的项目。

进行这些更改后,您的代码应该可以正常运行。这是一个有变化的片段:

&#13;
&#13;
Vue.component('child', {
	template: '#child',
  props: ['userData'],
  data() {
    return {
      roles: [
        {name: 'something0', id:0 },
        {name: 'something1', id:1 },
        {name: 'something2', id:2 },
      ],
      form: { roles: null }
    }
  },
  computed: {
    role: {
      get: function(){
        if(this.userData == undefined) return null;
        return this.userData.roles[0].id;
      },
      set: function(id) {
        var role = this.roles.filter(role => role.id === id)[0];
        Vue.set(this.form.roles, 0, role);
      }
    }
  },
  created: function() {
  	this.form = Object.assign({}, this.userData);
  }
});

new Vue({
  el: '#app',
  data: {
  	userData: {
    	roles: [ {id: 0, name: 'something' } ]
    }
  }
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.3/vue.js"></script>

<div id="app">
  <child :user-data="userData"></child>
</div>

<template id="child">
  <div>
    <select v-model="role">
      <option v-for="role in roles" :value="role.id">{{ role.name }}</option>
    </select>
    <p>JSON.stringify(form):</p>
    <pre>{{JSON.stringify(form, null, 2)}}</pre>
  </div>
</template>
&#13;
&#13;
&#13;