Search code examples
javascriptvue.jspropertiesvuexv-model

Problems with modifying props directly in vuejs vuex


I'm working in this web app, trying to build a searchbar filter which allows me to do my own query from writing whatever I want (if the API contains the data), but throws me always the same error:

Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "Search".

I was looking on some of your responses, trying to apply them to my case, but them gives me a massive error, turned to worst, here is part of my code, my original one:

  <v-container>
    <input class='input'
        @input='sendingSelfSearch'
      placeholder="write words for search"
      type="text"
      v-model="Search"
    />
  </v-container>
</template>
<script>
export default {
  name: "SearchBar",

  props: {
      SearchBar:Object,
      Search:String
  },

  methods:{
      sendingSelfSearch(){
          this.$emit('receivingSelfSearch',this.Search)
      }
  }
};
</script> 

And in this second part I'm receiving that component from 'Search' (component) to 'Home' (view):

<template>
  <div class="home">
              <img class='body' src='../assets/alli.jpg'/>
              <SearchBar @receivingSelfSearch='autoSearch' v-bind:Search='Search'></SearchBar>... 
</template>

<script>
import {mapGetters} from 'vuex'
import Filters from '../components/Filters.vue'
import SearchBar from '../components/SearchBar.vue'

export default {
  name: 'home',
  components: {
    Filters,
    SearchBar
  },
  data(){
    return {
       listCountries:'',
       listEvents:'',
       listModalities:'',
       Search:'',
    }
  },
  methods:{
    autoSearch(text){
       this.Search=text
    },
  },
  computed:{
       autoSearchFilter(){
          some code
  }

...the result of the query shows, but at same time I have this error in the devtool console, thus despite of being working is not 'correct' somehow. Any suggestions regarding this code where I should improve please?


Solution

  • Error is because you are modifying Search prop by using v-model on your input (SearchBar component)

    Do this instead:

    <v-container>
        <input class='input'
          placeholder="write words for search"
          type="text"
          v-model="searchPhrase"
        />
      </v-container>
    </template>
    <script>
    export default {
      name: "SearchBar",
    
      props: {
          Search: String
      },
      computed: {
        searchPhrase: {
          get() { return this.Search }
          set(val) { this.$emit('receivingSelfSearch', val) }
        }
      }
    };
    </script>
    

    How using computed property for v-model works:

    1. Child receives prop Search from the parent (parent owns the data - it has Search in data())
    2. When the Child is rendering and needs initial value for the input, it calls getter (get() method) which returns value of Search prop
    3. When user changes content of input, Vue will do something like searchPhrase = new value, which in turn calls setter
    4. Setter emits the event with new value as an event payload
    5. Parent listener gets a new value and assign it into the Search data variable (@receivingSelfSearch='autoSearch')
    6. Vue detects the Search is changed and update Child component, updating Search prop inside the Child to a new value