关于组件外部元素上的javascript:v-model

 2021-04-27 

v-model on an element outside the component

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

即,您能否提供以下信息:

1
2
3
4
5
6
7
8
9
10
11
12
$(function(){
  Vue.component('custom-element', {
    template: '#custom-template'
  })

  var vm = new Vue({
    el:"#app"
    data: {
      selected:""
    }
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js">


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


  <custom-element>

  </custom-element>


<script type="text/x-template" id="custom-template">
 
    <p> {{selected}} </p>

选择位于Vue的根元素(" app")之外的位置。这是我的问题的简化版本,但我认为可以突出显示我遇到的困难。

我看到这个答案是关于在Vue之间共享数据的集中状态管理的,但是似乎不得不将选择package到完全不同的Vue中有点沉重,我感觉我缺少一些重要的东西! (对于Vue还是很新的)。 Vue与之交互的所有内容都必须在Vue实例的根元素下吗?


否,您不能在Vue上下文之外的元素上使用v-model。原因是Vue向下编译为一个渲染函数,以渲染其控制的元素的内容。除非您涉及特定的代码或诸如vue-portal

之类的库,否则它不会在该元素之外呈现任何内容。

这就是说,你可以更新Vue公司在使用标准的JavaScript选择改变设置Vue的数据属性。我还清理了一些事情,例如将选定的数据传递到您的组件(这是必需的;组件无法直接访问其父级数据)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$(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
 
 
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js">


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


  <custom-element :selected="selected">

  </custom-element>


<script type="text/x-template" id="custom-template">
 
    <p> {{selected}} </p>


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

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

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

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

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

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

1
2
3
4
5
6
<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

的示例代码


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

如果您试图在同一元素上混合使用jQuery和Vue,您可能会度过美好时光。