Vuejs Привязать значение к v-модели из реквизита или вычисленного значения - PullRequest
0 голосов
/ 30 ноября 2018

Мне нужна помощь, поскольку я потратил неделю, пытаясь найти решение, которое кажется очень простым делом в обычном режиме, но я просто изо всех сил.

У меня есть вход, которыйкомпонент и отображается в главном представлении следующим образом:

<slug v-model="slug" ></slug>

Затем у меня есть представление компонента, как показано ниже:

<template>
    <v-text-field box label="Slug*" v-model="slug" @change="strtoslug"  :rules="requiredRule"></v-text-field>
</template>

Я запускаю вычисленный метод для получения и установкиdata и может console.log без проблем.

В состоянии редактирования я не могу заполнить v-модель обновленным вычисленным состоянием, поскольку я не могу декальрировать как источник данных при рендеринге.

Вот весь мой блок кода.

<script>
//Set the params
export default {
  name:'slug',
  props: ['value'],
  //Set the data
  data() {
      const self = this;
      return {
          slugstr: '',
          requiredRule: [
              (v) => !!v || 'Field is required',
          ],
        }
    },
    watch: {
    },
    //Get the value onchange computer to return from component
    computed: {
        slug: {
          get() {
              return this.value;
          },
          set(val) {
            //set the slug
            this.slugstr = val;
            this.slug    = val;
            //send data back to parent
            this.$emit('input',val)
             return this.value;
          }
        }
    },
    mounted() {
      const self = this;
      //Set the templates get request
     },
      methods: {
        strtoslug: function(value){
            this.slug = this.sanitizeSlug(value);
        },

        sanitizeSlug: function(title) {
         var slug = "";
         // Change to lower case
         var titleLower = title.toLowerCase();
         // Letter "e"
         slug = titleLower.replace(/e|é|è|ẽ|ẻ|ẹ|ê|ế|ề|ễ|ể|ệ/gi, 'e');
         // Letter "a"
         slug = slug.replace(/a|á|à|ã|ả|ạ|ă|ắ|ằ|ẵ|ẳ|ặ|â|ấ|ầ|ẫ|ẩ|ậ/gi, 'a');
         // Letter "o"
         slug = slug.replace(/o|ó|ò|õ|ỏ|ọ|ô|ố|ồ|ỗ|ổ|ộ|ơ|ớ|ờ|ỡ|ở|ợ/gi, 'o');
         // Letter "u"
         slug = slug.replace(/u|ú|ù|ũ|ủ|ụ|ư|ứ|ừ|ữ|ử|ự/gi, 'u');
         // Letter "d"
         slug = slug.replace(/đ/gi, 'd');
         // Trim the last whitespace
         slug = slug.replace(/\s*$/g, '');
         // Remove Punctuation
         slug = slug.replace(/[.,\/#!$%\^&\*;:{}=\`~()]/g,"");
         // Change whitespace to "-"
         slug = slug.replace(/\s+/g, '-');
     //Return the formatted str
     return slug;
   }
 }

}
</script>

onchange происходит в console.log, но я просто не могу заставить его отрисовывать входные данные как значение, ПОЖАЛУЙСТА, что япоступаю неправильно.

С уважением

Пол

Ответы [ 2 ]

0 голосов
/ 09 декабря 2018

Ваше вычисляемое свойство имеет бесконечный цикл, потому что его установщик снова устанавливает себя:

computed: {
  slug: {
    set(val) {
      this.slug = val; // <-- sets itself again -- infinite loop
      this.$emit('input', val);
    }
  }
},

Этот бесконечный цикл не позволяет вашему компоненту передать значение родительскому элементу, и вы должны увидеть консольную ошибку, похожую на:Maximum call stack size exceeded.

Но похоже, что вы действительно хотите, чтобы переданное значение было санировано с помощью sanitizeSlug() заранее.В настоящее время он генерирует необработанное значение ввода для каждого ввода (например, при каждом нажатии клавиши), а затем отправляет очищенное значение с событием change, которое происходит после того, как <v-text-field> теряет фокус.Обработчик события change является избыточным, если у вас уже есть v-model="slug", поэтому его можно удалить.Кроме того, вероятно, лучше очистить все входные значения перед их выдачей.

Чтобы устранить проблему:

  1. В установщике slug удалите this.slug = valи санируйте значение input перед его отправкой:

    computed: {
      slug: {
        set(val) {
          // this.slug = val; // <-- delete this
          this.$emit('input', this.sanitizeSlug(val)); // <-- sanitized input value
        }
      }
    },
    
  2. Удалите привязку обработчика события change:

    <v-text-field box label="Slug*" v-model="slug"
                  <!-- @change="strtoslug" DELETE THIS BINDING -->
                  :rules="requiredRule"></v-text-field>
    
  3. Также удалите связанный с обработчиком событий метод:

    methods: {
      /* strtoslug: function(value){
          this.slug = this.sanitizeSlug(value);
      },*/ // DELETE THIS METHOD
    }
    

demo

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

Я не совсем уверен, что хорошо понял, чего вы пытаетесь достичь, но вот некоторые элементы, которые помогут решить вашу проблему.

Полагаю, вы хотите, чтобы ваш родительский компонент реагировал на свойство дочернего компонента идочернее свойство, которое будет обновлено родителем.Скажите, если я ошибаюсь.

Эта проблема может быть связана с вашим значением return в функции установки.Вот некоторый код с v-model, используемый с пользовательским компонентом.

App.vue

<template>
  <slug v-model="input_data"></slug>
</template>
<script>
import slug from "./components/slug";

export default {
  name: "App",
  data() {
    return {
      input_data: "hello"
    };
  },
  components: {
    slug
  },
  watch: {
    input_data() {
      console.log("Parent: " + this.input_data);
    }
  }
};
</script>

slug.vue

<template>
  <div>
    <input v-model="msg" />
    <p>{{ value }}</p>
  </div>
</template>

<script>
export default {
  name: "slug",
  props: ["value"],
  computed: {
    msg: {
      get: function() {
        return this.value;
      },
      set: function(val) {
        this.$emit("input", val);
      }
    }
  }
};
</script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...