首页 文章

在兄弟VueJS组件上调用.focus()

提问于
浏览
2

我有一个选择组件 . 我有一个输入组件 . 当选择组件改变时,我需要.select()输入组件 . 这是两个不相关的组件,即主Vue实例的兄弟 .

这两个组件都是由模板组成的,因此根据文档https://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 Code

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'
    });

2 回答

  • 1

    有几种方法可以做到这一点,而正确的方法取决于实现此行为的原因 . 听起来选择的值对应用程序来说很重要,而不仅仅是与选择组件相关,因此它应该来自父级 . 父级也可以将该值传递给输入,输入可以 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>
    

    这可以保持封装的内容:父级只知道一个子级发生更改,另一个子级处理更改事件 . 两个组件都不知道另一个 .

  • 1

    您需要从select-component向父级发出自定义事件:VueJS Custom Events

    父组件:

    <select-component @valueChanged="this.$refs.myInput.focus()"></select-component>
    <input type="text" ref="myInput"/>
    

    选择组件:

    <select v-model="mySelectValue" @change="$emit('valueChanged', mySelectValue)"></select>
    

相关问题