Я пытаюсь использовать jQuery geocomplete вместе с Vue.js для заполнения формы геоданными.

Мой код содержит эту форму:

<form>
    <label for="get-offer-location">location: </label><input id="get-offer-location" v-model="newoffer.location" type="text"/>
    <div style="visibility:hidden">
        <input name="lat" type="text" value=""/>
        <input name="lng" type="text" value=""/>
    </div>
</form>

После того, как я нажимаю на предложенное местоположение из ввода get-offer-location, похоже, что поле заполнено - но когда я начинаю печатать в другом поле, поле ввода местоположения возвращается к буквам, которые я набрал для поиск местоположения. Попробуйте это, нажав «пост», затем «новости» или «предложения»: https://jsfiddle.net/dvdgdnjsph/157w6tk8/

Может кто-нибудь сказать мне, что не так?

2
David J. 6 Янв 2017 в 12:05

4 ответа

Лучший ответ

Проблема, с которой вы столкнулись, заключается в том, что v-model связывается с input, так как geolocation dropdown является плагином, который изменяет значение программно, входное событие не запускается, поэтому v-model не обновлено. Как вариант, попробуйте ввести пробел после выбора места, вы увидите, что оно придерживается.

К счастью, v-model является не чем иным, как синтаксическим сахаром для v-on:input, поэтому вы можете использовать v-on для запуска вашего события. Учитывая, что вам нужно unfocus, чтобы выйти из коробки, событие blur, вероятно, будет вашим лучшим вариантом, поэтому вы можете просто сделать:

v-on:blur="newarticle.location = $event.target.value"

К сожалению, JSFiddle не позволяет мне сохранять или обновлять вашу Fiddle, но я справился с приведенным выше кодом.

Для полноты, если вы хотите широко использовать это поведение и поскольку документы Vue довольно ограничены в этом отношении, вы можете написать пользовательская директива для инкапсуляции кода:

Vue.directive('model-blur', {
  bind: function(el, binding, vnode) {
    el.addEventListener('blur', function() {
      vnode.context[binding.expression] = el.value;
    });
  }
});

Тогда вы можете использовать так:

<input v-model-blur="myVar" />

Вот JSFiddle: https://jsfiddle.net/4vp6Lvmc/

2
craig_h 8 Янв 2017 в 12:09

Не могу сказать наверняка. Но похоже, что плагин jQuery просто меняет значение input # get-article-location, но не модель Vue. Поэтому, когда вы запускаете обновление модели (например, редактирование заголовка), оно перезаписывает полное местоположение тем, что вы ввели.

1
Yaroslav 6 Янв 2017 в 09:34

Это связано с тем, что v-model в качестве двусторонней привязки на пути приема-приема пользователем прослушивает событие input на элементе ввода, в то время как плагины js (например, jquery-geocomplete), очевидно, устанавливают ввод значения через js, что приводит к тому, что data модели представления не меняется, как мы обсуждали в других ответах.

Чтобы это исправить, просто прослушайте событие geocode:result плагина и вручную измените data с помощью кода (похоже, что-то не так с jsfiddle, поэтому я публикую его здесь):

var vueVM = this;

$("#get-offer-location").geocomplete({ details: ".details" });

$("#get-article-location")
.geocomplete({ details: ".details" })
/***** highlight start *****/
.bind("geocode:result", function(event, result){
    console.log(result);
    //tried result.something but couldn't find the the same thing as `this.value`
    vueVM.newarticle.location = this.value;
});
/***** highlight end *****/

дополнительные знания : механизм v-model, описанный выше, обычно используется при создании повторно используемых компонентов, получая value prop от родителя и испуская {{ X3}} событие со значением пользовательского ввода при обнаружении изменения элемента ввода в компоненте. И тогда мы можем использовать <my-component v-model='parentData'></my-component>, поскольку дочерний элемент ведет себя точно так же, как простой элемент ввода с точки зрения родителя. пример

1
PanJunjie潘俊杰 8 Янв 2017 в 10:40

У меня есть что-то вроде этого, чтобы поймать событие geocomplete и попытаться установить значение vueJS:

$("#get-article-location")
  .geocomplete({details: ".details"})
  .bind("geocode:result", function (event, result) {
    vm.newoffer.location = result.formatted_address;
    console.log('done');
  });

Но что-то все равно кажется неправильным, я думаю, вам действительно следует изменить имя вашего экземпляра vueJS (var vm), который может использоваться другим скриптом и создавать проблемы.

1
Nhan 6 Янв 2017 в 10:35