[英]Call .focus() on a sibling VueJS Component
我有一个选择组件。 我有一个输入组件。 当更改选择组件时,我需要.select()输入组件。 这是两个不相关的组件,即主 Vue 实例的兄弟。
这两个组件都是由模板组成的,因此根据文档https://v2.vuejs.org/v2/guide/components.html#Child-Component-Refs ,使用 ref 属性不是一个选项
我该怎么做呢? 我在 codepen 中编写了一个简单的示例 - https://codepen.io/anon/pen/MVmLVZ
HTML
<div id='my-app'>
<some-select></some-select>
<some-input></some-input>
</div>
<script type="text/x-template" id="vueTemplate-some-select">
<select @change="doStuff">
<option value='1'>Value 1</option>
<option value='2'>Value 2</option>
</select>
</script>
<script type="text/x-template" id="vueTemplate-some-input">
<input ref='text-some-input' type='text' value='Some Value'/>
</script>
Vue 代码
Vue.component('some-input', {
template: `#vueTemplate-some-input`
});
Vue.component('some-select', {
methods: {
doStuff: function() {
// Do some stuff
//TODO: Now focus on input text field
//this.$refs['text-some-input'].focus(); // Cant use refs, refs is empty
}
},
template: `#vueTemplate-some-select`
});
var app = new Vue({
el: '#my-app'
});
有几种方法可以做到这一点,正确的方法取决于实现此行为的原因。 听起来选择的值对应用程序很重要,而不仅仅是与选择组件相关,因此它应该来自父级。 父母也可以将该值传递给输入,它可以watch
它的变化并设置焦点。
该解决方案可能类似于以下代码段:
Vue.component("some-input", { template: `#vueTemplate-some-input`, props: ['watchValue'], watch: { watchValue() { this.$refs['text-some-input'].focus(); } } }); Vue.component("some-select", { props: ['value'], methods: { doStuff: function(event) { this.$emit('input', event.target.value); } }, template: `#vueTemplate-some-select` }); var app = new Vue({ el: "#my-app", data: { selectedValue: null } });
<script src="//unpkg.com/vue@latest/dist/vue.js"></script> <div id='my-app'> <some-select v-model="selectedValue"></some-select> <some-input :watch-value="selectedValue"></some-input> <div>Selected: {{selectedValue}}</div> </div> <script type="text/x-template" id="vueTemplate-some-select"> <select :value="value" @change="doStuff"> <option value='1'>Value 1</option> <option value='2'>Value 2</option> </select> </script> <script type="text/x-template" id="vueTemplate-some-input"> <input ref='text-some-input' type='text' value='Some Value' /> </script>
另一方面,如果您真的想知道select
发生了变化,而不仅仅是值发生了变化,您可以将事件总线传递给输入,以便父级可以将更改传递给其子级。 这可能看起来像这个片段:
Vue.component("some-input", { template: `#vueTemplate-some-input`, props: ['changeBus'], mounted() { this.changeBus.$on('change', () => this.$refs['text-some-input'].focus()); } }); Vue.component("some-select", { methods: { doStuff: function(event) { this.$emit('change', event.target.value); } }, template: `#vueTemplate-some-select` }); var app = new Vue({ el: "#my-app", data: { changeBus: new Vue() } });
<script src="//unpkg.com/vue@latest/dist/vue.js"></script> <div id='my-app'> <some-select @change="changeBus.$emit('change')"></some-select> <some-input :change-bus="changeBus"></some-input> </div> <script type="text/x-template" id="vueTemplate-some-select"> <select @change="doStuff"> <option value='1'>Value 1</option> <option value='2'>Value 2</option> </select> </script> <script type="text/x-template" id="vueTemplate-some-input"> <input ref='text-some-input' type='text' value='Some Value' /> </script>
这使事情保持封装:父母只知道一个孩子发生了变化,而另一个孩子处理了变化事件。 两个组件都不知道另一个组件。
您需要从选择组件向父组件发出自定义事件: VueJS 自定义事件
父组件:
<select-component @valueChanged="this.$refs.myInput.focus()"></select-component>
<input type="text" ref="myInput"/>
选择组件:
<select v-model="mySelectValue" @change="$emit('valueChanged', mySelectValue)"></select>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.