Vue.js multiple choice and computed property

I am using Vue.js 2.0 and the Element library.

I want to use multiple choice to attribute some of the roles for my users.

A list of all available roles is accepted and assigned availableRoles

. Since it is an array of an object and v-model

only accepts an array with a value, I need to extract id

from the roles via a computed property computedRoles

.

My user's current roles are accepted and assigned userRoles: [{'id':1, 'name':'Admin'}, {'id':3, 'name':'User'}]

.

computedRoles

then equals [1,3]

Selection selection is ok, but I can't change anything (add or remove option from selection)

What's wrong and how to fix it?

http://jsfiddle.net/3ra1jscx/3/

<div id="app">
    <template>
      <el-select v-model="computedRoles" multiple placeholder="Select">
        <el-option v-for="item in availableRoles" :label="item.name" :value="item.id">
        </el-option>
      </el-select>
    </template>
</div>

var Main = {
    data() {
      return {
        availableRoles: [{
          id: 1,
          name: 'Admin'
        }, {
          id: 2,
          name: 'Power User'
        }, {
          id: 3,
          name: 'User'
        }],
        userRoles: [{'id':1, 'name':'Admin'}, {'id':3, 'name':'User'}]
      }
    },

    computed : {

        computedRoles () {
            return this.userRoles.map(role => role.id)
        }
    }
  }

      

+1


source to share


2 answers


I agree mostly with @ wostex answer, but it doesn't return the property for you userRoles

. Essentially you have to change computedRoles

and userRoles

. userRoles

becomes a computed property and computedRoles

is a data property. In my update, I changed the name computedRoles

to selectedRoles

.

var Main = {
    data() {
      return {
        availableRoles: [{
          id: 1,
          name: 'Admin'
        }, {
          id: 2,
          name: 'Power User'
        }, {
          id: 3,
          name: 'User'
        }],
        selectedRoles:[1,2]
      }
    },
    computed : {
      userRoles(){
         return this.availableRoles.reduce((selected, role) => {
             if (this.selectedRoles.includes(role.id))
                    selected.push(role);
             return selected;
         }, [])
      }
    }
  }
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')

      



And here's the fiddle .

+1


source


Check the solution: jsfiddle

The caveat here is that computed properties are basically getters. You can define a setter for the computed property, but my approach is more like my opinion.

In short, instead of v-model

for a computed set v-model

for a data property.



Complete code:

<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/element-ui/lib/index.js"></script>
<div id="app">
<template>
  <el-select v-model="ids" multiple placeholder="Select" @change="logit()">
    <el-option v-for="item in availableRoles" :label="item.name" :value="item.id">
    </el-option>
  </el-select>
</template>
</div>

var Main = {
    data() {
      return {
        availableRoles: [{
          id: 1,
          name: 'Admin'
        }, {
          id: 2,
          name: 'Power User'
        }, {
          id: 3,
          name: 'User'
        }],
        userRoles: [{'id':1, 'name':'Admin'}, {'id':3, 'name':'User'}],
        ids: []
      }
    },
    mounted() {
        this.ids = this.userRoles.map(role => role.id);
    },
    methods: {
        logit: function() {
        console.log(this.ids);
      }
    }
  }
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')

      

+1


source







All Articles