Pass data from nested component up and down



  • Hello, I use components and pass a some props to it. To not repeat all the time I close it in component. Now I want to pass data from this component up. I achieve this using watch and model.
    On every cModel change (watch Fn) i emmit event and listen in parent. Is this proper solution in implementing or should i do it other way ?
    Example:

    <template>
      <div>
        <q-select
          use-input
          input-debounce="0"
          label="Multi with toggle"
          multiple
          rounded
          outlined
          :menu-offset="[0, 10]"
          :display-value="`${
            model.length ? 'Selected: ' + model.length : 'Select'
          }`"
          @filter="filterFn"
          v-model="cModel"
          :options="cOptions"
        >
          <template
            v-slot:option="{ itemProps, itemEvents, opt, selected, toggleOption }"
          >
            <q-item v-bind="itemProps" v-on="itemEvents">
              <q-item-section side>
                <q-checkbox :value="selected" @input="toggleOption(opt)" />
              </q-item-section>
              <q-item-section>
                <q-item-label v-html="opt.label"></q-item-label>
              </q-item-section>
            </q-item>
          </template>
        </q-select>
      </div>
    </template>
    
    <script>
    export default {
      name: "selectComponent",
      props: ["model", "stringOptions"],
      data() {
        return {
          cModel: this.model,
          cOptions: [],
          cStringOptions: this.stringOptions,
        };
      },
      watch: {
        cModel: function (newValue, oldValue) {
          this.$emit("modelChanged", newValue);
        },
      },
      methods: {
        filterFn(val, update) {
          if (val === "") {
            update(() => {
              this.cOptions = this.cStringOptions;
            });
            return;
          }
    
          update(() => {
            const needle = val.toLowerCase();
            this.cOptions = this.stringOptions.filter((v) => {
              return v.label.toLowerCase().includes(needle);
            });
          });
        },
      },
    };
    </script>
    


  • @felek props down, events up is a staple communication pattern in Vue.



  • So this is proper of implementation. Thx.



  • @felek it depends. If you don’t really care about event itself and only need to update same var you could use .sync modifier https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier
    But yeah you should still watch for value change inside component and then emit it.



  • Nice, i use watch and emit. Thx.


Log in to reply