是否可以在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;
其中select位于Vue的根元素(&#34; app&#34;)之外。这是我的问题的简化版本,但我相信我突出了我遇到的困难。
我看到这个答案谈论centralised state management在Vues之间共享数据但是看起来有点沉重,我必须把选择包装在一个完全不同的Vue中,我觉得我错过了一些重要的东西! (对Vue来说还是很新的)。 Vue与之交互的所有内容都必须位于Vue实例的根元素下吗?
答案 0 :(得分:3)
不,您不能在Vue上下文之外的元素上使用v-model
。原因是Vue编译为渲染函数,渲染它控制的元素的内容;它不会在该元素之外呈现任何内容,除非您涉及特定代码或vue-portal
之类的库。
也就是说,当使用标准javascript设置Vue数据属性进行选择更改时,您可以更新Vue。我还清理了一些事情,比如将所选数据传递给组件(这是必要的;组件无法直接访问父项数据)。
$(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;
答案 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>
的示例代码