簡體   English   中英

VUE 2+訪問子方法

[英]VUE 2+ accessing child methods

我遇到一種情況,在VUE中,我需要從子級以及父級中訪問子級功能。 我有一個有效的示例,但是必須有一種更好的方法來從父級訪問子級功能。

該示例包含幾個事件偵聽器,在單擊或按鍵時應將其展開。 我想將父級的child.do_something方法與全局EventListener

有沒有比這更好的方法來使用孩子了?

 // CHILD is a component that needs access to its own click method var child = { props: ['item'], data: function() { return { isActive: false } }, template: ` <div class="key" :class="{playing: isActive}" v-on:click='do_something'> <kbd class="noselect">{{ item.kbd }}</kbd> </div> `, methods: { do_something: function(event) { this.isActive = !this.isActive // DO OTHER STUFF too }, }, } //PARENT also need to access do_something for the right object when a key is pressed var parent = new Vue({ el: '#parent', data: { keysList: [{ keyCode: "65", kbd: "A" }, { keyCode: "83", kbd: "S" }, ], }, components: { 'child': child, }, methods: { keystroke: function(keyCode) { //FIND THE CHILD AND EXECUTE...THIS IS THE TERRIBLE PART const child = this.$children.find(child => { return child.$vnode.data.key === keyCode.toString() }); child.do_something() } }, created: function() { window.addEventListener('keydown', (e) => this.keystroke(e.keyCode)); } }) 
 .keys { display: flex; flex: 1; min-height: 100vh; align-items: center; justify-content: center; } .key { margin: 1rem; transition: all .07s ease; color: white; background: rgba(0, 0, 0, 0.77); } .playing { transform: scale(1.1); border-color: #ffc600; box-shadow: 0 0 1rem #ffc600; } kbd { display: block; font-size: 4rem; } 
 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <div class="keys" id='parent'> <child v-for="(item,index) in keysList" :item="item" :key="item.keyCode"></child> </div> 

您可以使用ref,然后通過索引引用所需的特定孩子。 這樣可以避免使用內部值。

<child v-for="(item,index) in keysList" :item="item" :key="item.keyCode" ref="children"></child>

keystroke

const index = this.keysList.findIndex(k => k.keyCode == evt.keyCode)
this.$refs.children[index].do_something()

在這里,您的代碼已修改。

 // CHILD is a component that needs access to its own click method var child = { props: ['item'], data: function() { return { isActive: false } }, template: ` <div class="key" :class="{playing: isActive}" v-on:click='do_something'> <kbd class="noselect">{{ item.kbd }}</kbd> </div> `, methods: { do_something: function(event) { this.isActive = !this.isActive // DO OTHER STUFF too }, }, } //PARENT also need to access do_something for the right object when a key is pressed var parent = new Vue({ el: '#parent', data: { keysList: [{ keyCode: "65", kbd: "A" }, { keyCode: "83", kbd: "S" }, ], }, components: { 'child': child, }, methods: { keystroke: function(evt) { const index = this.keysList.findIndex(k => k.keyCode == evt.keyCode) this.$refs.children[index].do_something() } }, created: function() { window.addEventListener('keydown', this.keystroke); } }) 
 .keys { display: flex; flex: 1; min-height: 100vh; align-items: center; justify-content: center; } .key { margin: 1rem; transition: all .07s ease; color: white; background: rgba(0, 0, 0, 0.77); } .playing { transform: scale(1.1); border-color: #ffc600; box-shadow: 0 0 1rem #ffc600; } kbd { display: block; font-size: 4rem; } 
 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <div class="keys" id='parent'> <child v-for="(item,index) in keysList" :item="item" :key="item.keyCode" ref="children"></child> </div> 

或者,為每個孩子使用不同的引用的更直接的方法。

<child v-for="(item,index) in keysList" :item="item" :key="item.keyCode" :ref="item.keyCode"></child>

keystroke

this.$refs[evt.keyCode][0].do_something()

這里不幸的是,因為ref被設置為循環的一部分,所以每個ref都是一個元素的數組。 如果我想辦法解決該問題,請對其進行編輯。

這就是工作。

 // CHILD is a component that needs access to its own click method var child = { props: ['item'], data: function() { return { isActive: false } }, template: ` <div class="key" :class="{playing: isActive}" v-on:click='do_something'> <kbd class="noselect">{{ item.kbd }}</kbd> </div> `, methods: { do_something: function(event) { this.isActive = !this.isActive // DO OTHER STUFF too }, }, } //PARENT also need to access do_something for the right object when a key is pressed var parent = new Vue({ el: '#parent', data: { keysList: [{ keyCode: "65", kbd: "A" }, { keyCode: "83", kbd: "S" }, ], }, components: { 'child': child, }, methods: { keystroke: function(evt) { this.$refs[evt.keyCode][0].do_something() } }, created: function() { window.addEventListener('keydown', this.keystroke); }, }) 
 .keys { display: flex; flex: 1; min-height: 100vh; align-items: center; justify-content: center; } .key { margin: 1rem; transition: all .07s ease; color: white; background: rgba(0, 0, 0, 0.77); } .playing { transform: scale(1.1); border-color: #ffc600; box-shadow: 0 0 1rem #ffc600; } kbd { display: block; font-size: 4rem; } 
 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <div class="keys" id='parent'> <child v-for="(item,index) in keysList" :item="item" :key="item.keyCode" :ref="item.keyCode"></child> </div> 

您可以通過向父數據keys中的項添加另一個active屬性來實現此目的,並為匹配的擊鍵更新active屬性。 將物品作為道具傳遞給孩子時,可以使用道具中的item.active。 您不需要孩子中的isActive數據。

家長:

    var parent = new Vue({
  el: '#parent',
  data: {
    keysList: [{
        keyCode: "65",
        kbd: "A",
        active: false
      },
      {
        keyCode: "83",
        kbd: "S",
        active: false
      }
    ],
  },
  components: {
    'child': child,
  },
  methods: {
    keystroke: function(keyCode) {
      this.keysList.forEach(key => {key.active = key.keyCode === keyCode.toString()});
    }
  },
  created: function() {
    window.addEventListener('keydown', (e) => this.keystroke(e.keyCode));
  }
})

<div class="keys" id='parent'>
  <child v-for="(item,index) in keysList" :item="item" :key="item.keyCode" :isActive="item.active"></child>
</div>

兒童:

    var child = {
  props: ['item'],

  template: `
    <div class="key" :class="{playing: item.active}" v-on:click='do_something'>
      <kbd class="noselect">{{ item.kbd }}</kbd>
    </div>
  `,

  methods: {
    do_something: function(event) {
       // DO OTHER STUFF too
    },
  },
}

這樣,您就可以在一個地方管理狀態,而無需從父母那里訪問孩子

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM