vue.js упаковочные компоненты, которые имеют v-модели - PullRequest
0 голосов
/ 06 июня 2018

У меня есть сторонний компонент ввода ( vuetify v-text-field).

В целях проверки я предпочитаю оборачивать этот компонент в свой собственный.

my TextField.vue

<template>
    <v-text-field
            :label="label"
            v-model="text"
            @input="onInput"
            @blur="onBlur"
            :error-messages="this.getErrors(this.validation, this.errors)"
    ></v-text-field>
</template>

<script>
    import VTextField from "vuetify/es5/components/VTextField";
    import {vuelidateErrorsMixin} from '~/plugins/common.js';
    export default {
        name: "TextField",
        props: ['label', 'value', 'validation', 'errors'],
        mixins: [vuelidateErrorsMixin], //add vuelidate
        data: function() {
            return {
                'text': this.value
            }
        },
        components: {
            VTextField
        },
        methods : {
            onInput: function(value) {
                this.$emit('input', value);
                this.validation.$touch();
            },
            onBlur: function() {
                this.validation.$touch();
            }
        },
        watch: {
            value: {
                immediate: true,
                handler: function (newValue) {
                    this.text = newValue
                }
            }
        }
    }
</script>

, который используется в другом компоненте

<template> 
 ...   
  <TextField v-model="personal.email" label="Email" 
        :validation="$v.personal.email" :errors="[]"/> 
   ... 
</template> 
<script> 
      ...imports etc. 
      export default {   ...     
          data: function() {
              return {
                  personal: {
                      email: '',
                      name: ''
                  }
            }      
      },      
      components: [ TextField ] 
    } 
</script>

Это прекрасно работает, но мне интересно, если есть более чистый подход, чем повторять весь подход v-модели снова.Так как теперь мои данные дублируются в 2 местах + вся дополнительная (необязательная) обработка событий ...

Я просто хочу передать реактивные данные напрямую в v-текстовое поле из исходного шаблона.Моему TextField вообще не нужен доступ к этим данным - ТОЛЬКО уведомляется, что текст изменился (сделано через обработчики @input, @blur).Я не хочу использовать VUEX, поскольку у него есть свои проблемы с вводом / формами ...

Что-то более близкое к этому ...

<template>
    <v-text-field
            :label="label"
            v-model="value" //?? SAME AS 'Mine'
            @input="onNotify"
            @blur="onNotify"
            :error-messages="this.getErrors(this.validation, this.errors)"
    ></v-text-field>
</template>

<script>
    import VTextField from "vuetify/es5/components/VTextField";
    import {vuelidateErrorsMixin} from '~/plugins/common.js';
    export default {
        name: "TextField",
        props: ['label', 'validation', 'errors'], //NO VALUE HERE as cannot use props...
        mixins: [vuelidateErrorsMixin], //add vuelidate
        components: {
            VTextField
        },
        methods : {
            onNotify: function() {
                this.validation.$touch();
            }
        },
    }
</script>

Я не могу найти ничего, что могло бысделай это.

Я использую props + v-model wrapping.

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Вам необходимо переслать опору value вниз на обернутый компонент и переслать событие update назад (подробнее см. https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components):

<template>
  <wrapped-component
    :value='value'
    @input="update"
  />
</template>

<script>
  import wrappedComponent from 'wrapped-component'

  export default {
    components: { 'wrapped-component': wrappedComponent },
    props: ['value'],
    methods: {
      update(newValue) { this.$emit('input', newValue); }
    }
  }
</script>

Где-тоостальное:

<my-wrapping-component v-model='whatever'/>
0 голосов
/ 14 сентября 2018

Я создал миксин, чтобы упростить перенос компонента.

Здесь вы можете увидеть образец .

Миксин повторно использует тот же шаблон, что и вы«data» для передачи значения и «watch» для обновления значения во время внешнего изменения.

export default {
  data: function() {
    return {
      dataValue: this.value
    }
  },
  props: {
    value: String
  },
  watch: {
    value: {
      immediate: true,
      handler: function(newValue) {
        this.dataValue = newValue
      }
    }
  }
}

Но в компоненте переноса вы можете использовать «attrs» и «listeners» для прохождения всех атрибутов ислушатель вашего дочернего компонента и переопределите то, что вы хотите.

<template>
  <div>
    <v-text-field
        v-bind="$attrs"
        solo
        @blur="onBlur"
        v-model="dataValue"
        v-on="$listeners" />
  </div>
</template>

<script>
import mixin from '../mixins/ComponentWrapper.js'

export default {
  name: 'my-v-text-field',
  mixins: [mixin],
  methods: {
    onBlur() {
      console.log('onBlur')
    }
  }
}
</script>
...