1

I'm trying to separate my project now into components to make the code readable when adjusting into a responsive app. The problem is passing the v-model from base-select -> child -> parent. How do I store the data selected to the Parent.vue items: ''? Here is my code below.

Parent.vue

<template>
  <child></child>
</template>

<script>
import Child from './components/Child'

export default {
  components: { 
    Child,
  },
  data: ()=> ({
    item: ''
  })
}
</script>

Child.vue

<template>
  // Random HTML
  // Random HTML 2
  <base-select 
  :items="select"
  >
</template>

<script>
import BaseSelect from '@/components/BaseSelect'

export default {
  components: { 
    BaseSelect,
  },
  data: ()=> ({
    select: ['Select 1', 'Select 2']
  })
}
</script>

BaseSelect.vue

<template>
  <v-select
    v-bind="$attrs"
    v-on="$listeners"
    class="body-2"
    solo
    dense
    clearable
  />
</template>

2 Answers 2

1

To implement v-model you need to add a value property to each child component. Each component will also need to emit an input event so that the parent component can pick up the change (read more here). Note that if you are passing data down through too many components, you should probably look at using Vuex however in this case it would probably still be fine.

Your components would have to look something like this to pass v-model all the way to the base component:

Parent.vue

<template>
  <!-- Pass the data item below -->
  <child v-model="item"></child>
</template>

<script>
import Child from './components/Child'

export default {
  components: { 
    Child,
  },
  data: ()=> ({
    item: ''
  })
}
</script>

Child.vue

<template>
  // Random HTML
  // Random HTML 2
  <base-select 
    :items="select"
    value="value"
    @input="e => $emit('input', e)"
  >
</template>

<script>
import BaseSelect from '@/components/BaseSelect'

export default {
  components: { 
    BaseSelect,
  },
  // We add the value prop below to work with v-model
  props: {
    value: String
  },
  data: ()=> ({
    select: ['Select 1', 'Select 2']
  }),
}
</script>

BaseSelect.vue

<template>
  <v-select
    v-bind="$attrs"
    v-on="$listeners"
    value="value"
    @input="e => $emit('input', e)"
    class="body-2"
    solo
    dense
    clearable
  />
</template>

<script>
export default {
  props: {
    value: String
  }
}
</script>

You can find a similar working example that I did here.

Sign up to request clarification or add additional context in comments.

1 Comment

It looks more complicated passing from components to components. Yeah, like what @dreyhiflden have said, you're right vuex makes it more simple. Thank you very much for this!
1

You need to use $emit (documentation) to passing data back to parent components. Or you can start using Vuex (state manager for Vue.js).

You also can check the live demo here.

1 Comment

I totally forgot about vuex. I have this principle of using vuex the least possible and contain methods within components. I'll go read the documentation and if ever I fail to implement it, I'll go with vuex. Thanks man!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.