使用 Vue js 完成地理信息——位置被删除

geocomplete with Vue js -- location being erased

我正在尝试使用 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 输入中的建议位置后,该字段似乎已填写 -- 但当我开始在另一个字段中输入时,位置输入字段恢复为仅字母我输入了位置搜索。单击 "post",然后单击 "news" 或 "offers",在此处尝试一下: https://jsfiddle.net/dvdgdnjsph/157w6tk8/

谁能告诉我怎么了?

不能肯定。但看起来 jQuery 插件只是改变了 input#get-article-location 值,而不是 Vue 模型。因此,当您触发模型更新(例如编辑标题)时,它会用您输入的任何内容覆盖完整位置。

我有类似这样的东西来捕捉 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) 它可能被另一个脚本使用并制造麻烦。

这是因为v-model,作为two-way绑定,在receiving-user-input方式上,监听input元素上的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接收parent,并在检测到组件中输入元素的变化时发出具有 user-input 值的 input 事件。然后我们可以使用 <my-component v-model='parentData'></my-component>,因为从 parent 的角度来看,child 的行为就像一个简单的输入元素。 example

您遇到的问题是 v-model 绑定到 input,因为 geolocation dropdown 是一个以编程方式更改值的插件,输入事件不会被触发,所以 v-model 未更新。例如,在选择位置后尝试输入 space,您会看到它会显示。

幸运的是,v-model 只不过是 v-on:input 的语法糖,所以您可以使用 v-on 来触发您的事件。考虑到您需要 unfocus 才能开箱即用,blur 事件可能是您的最佳选择,因此您可以简单地执行以下操作:

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

不幸的是,JSFiddle 不允许我保存或更新您的 Fiddle,但我确实使用上面的代码让它工作了。

为了完整起见,如果您想广泛使用此行为,并且由于 Vue 文档在这方面相当有限,您可以写一个 custom directive 来封装代码:

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/