简体   繁体   English

组件外部元素上的 v-model

[英]v-model on an element outside the component

Is it possible to use v-model on an element in the DOM that is outside the root element of the Vue instance?是否可以在 DOM 中位于 Vue 实例的根元素之外的元素上使用 v-model?

Ie, Could you have the following:即,您能否拥有以下内容:

 $(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>

Where the select is outside the root element ("app") of the Vue.选择在 Vue 的根元素(“app”)之外的地方。 This is a simplified version of my problem, but I believe highlights the difficulties I'm having.这是我的问题的简化版本,但我相信突出了我遇到的困难。

I saw this answer talking about centralised state management for sharing data between Vues but that seems a bit heavy to have to wrap the select in an entirely different Vue, I feel like i'm missing something major!我看到这个答案讨论了在 Vues 之间共享数据的集中状态管理,但是不得不将选择包装在一个完全不同的 Vue 中似乎有点沉重,我觉得我错过了一些重要的东西! (still very new to Vue). (对 Vue 来说还是很新的)。 Does everything the Vue interacts with have to be under the root element of the instance of the Vue? Vue 与之交互的所有内容都必须在 Vue 实例的根元素下吗?

No, you cannot use v-model on elements outside the context of the Vue.不,您不能在 Vue 上下文之外的元素上使用v-model The reason is Vue compiles down to a render function that renders the contents of the element it controls;原因是 Vue 编译成一个渲染函数,渲染它控制的元素的内容; it doesn't render anything outside that element, unless you involve specific code or a library like vue-portal .它不会渲染该元素之外的任何内容,除非您涉及特定代码或像vue-portal这样的库。

That said, you can update Vue when the select changes using standard javascript set the Vue data property.也就是说,您可以在选择更改时使用标准 javascript 设置 Vue 数据属性来更新 Vue。 I also cleaned up a few things like passing the selected data to your component (which is necessary; components cannot access their parents data directly).我还清理了一些东西,比如将选定的数据传递给你的组件(这是必要的;组件不能直接访问它们的父数据)。

 $(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 })
 <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>

Unless you have some funky interaction going on with the select, add it to your Vue instance.除非您对选择进行了一些时髦的交互,否则将其添加到您的 Vue 实例中。 The Vue instance should encapsulate all your templates and logic for the form. Vue 实例应该封装表单的所有模板和逻辑。

If you're trying to mix jQuery and Vue on the same element you're probably not going to have a good time.如果你试图在同一个元素上混合使用 jQuery 和 Vue,你可能不会玩得很开心。

You can use portal-vue to accomplish this.您可以使用portal-vue来完成此操作。 It allows you to place the code from your component anywhere in the DOM.它允许您将组件中的代码放置在 DOM 中的任何位置。

Add it your view instance:将其添加到您的视图实例中:

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

In your component you define the content you want to render outside the component:在您的组件中,您定义要在组件外呈现的内容:

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

You can then place this anywhere in the DOM:然后你可以把它放在 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>

Example code from https://github.com/LinusBorg/portal-vue来自https://github.com/LinusBorg/portal-vue 的示例代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM