组件外部元素的v模型

时间:2018-02-15 17:49:43

标签: javascript vue.js vuejs2

是否可以在DOM中位于Vue实例根元素之外的元素上使用v-model?

是的,你能否拥有以下内容:



$(function(){
  Vue.component('custom-element', {
    template: '#custom-template'
  })

  var vm = new Vue({
    el: "#app"
    data: {
      selected: ""
    }
  })
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js"></script>


<select id="SportSelector" v-model="selected">
  <option value="football"> Football </option>
  <option value="tennis"> Tennis </option>  
</select>

<div id="app">
  <custom-element> 

  </custom-element>
</div>

<script type="text/x-template" id="custom-template">
  <div>
    <p> {{selected}} </p>
  </div>
</script>
&#13;
&#13;
&#13;

其中select位于Vue的根元素(&#34; app&#34;)之外。这是我的问题的简化版本,但我相信我突出了我遇到的困难。

我看到这个答案谈论centralised state management在Vues之间共享数据但是看起来有点沉重,我必须把选择包装在一个完全不同的Vue中,我觉得我错过了一些重要的东西! (对Vue来说还是很新的)。 Vue与之交互的所有内容都必须位于Vue实例的根元素下吗?

3 个答案:

答案 0 :(得分:3)

不,您不能在Vue上下文之外的元素上使用v-model。原因是Vue编译为渲染函数,渲染它控制的元素的内容;它不会在该元素之外呈现任何内容,除非您涉及特定代码或vue-portal之类的库。

也就是说,当使用标准javascript设置Vue数据属性进行选择更改时,您可以更新Vue。我还清理了一些事情,比如将所选数据传递给组件(这是必要的;组件无法直接访问父项数据)。

&#13;
&#13;
$(function(){
  Vue.component('custom-element', {
    props: ["selected"],
    template: '#custom-template'
  })

  var vm = new Vue({
    el: "#app",
    data: {
      selected: ""
    }
  })
  
  //get a reference to the select
  const sports = document.querySelector("#SportSelector")
  //add a listener that updates the Vue data when the select changes
  sports.addEventListener("change", evt => vm.selected = evt.target.value)
  //initialize Vue with the current selected value
  vm.selected = sports.value
  
  
})
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js"></script>


<select id="SportSelector">
  <option value="football"> Football </option>
  <option value="tennis"> Tennis </option>  
</select>

<div id="app">
  <custom-element :selected="selected"> 

  </custom-element>
</div>

<script type="text/x-template" id="custom-template">
  <div>
    <p> {{selected}} </p>
  </div>
</script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

除非您在选择中进行一些时髦的交互,否则请将其添加到您的Vue实例中。 Vue实例应该封装表单的所有模板和逻辑。

如果您尝试在同一元素上混合使用jQuery和Vue,那么您可能不会玩得开心。

答案 2 :(得分:0)

您可以使用portal-vue完成此操作。它允许您将组件中的代码放置在DOM中的任何位置。

将其添加到您的视图实例:

import PortalVue from 'portal-vue';
Vue.use(PortalVue);

在组件中,定义要在组件外部呈现的内容:

<portal to="destination">
  <p>This slot content will be rendered wherever the <portal-target> with name 'destination'
    is  located.</p>
</portal>

然后您可以将其放置在DOM中的任何位置:

<portal-target name="destination">
  <!--
  This component can be located anywhere in your App.
  The slot content of the above portal component will be rendered here.
  -->
</portal-target>

来自https://github.com/LinusBorg/portal-vue

的示例代码