Javascript VUE 2+;访问子方法

Javascript VUE 2+;访问子方法,javascript,html,vue.js,Javascript,Html,Vue.js,在VUE中,我需要从子函数内部以及从父函数访问子函数。我有一个工作示例,但必须有更好的方法从父函数访问子函数 该示例有两个事件侦听器,当单击或按下时,这些侦听器应该展开。我想用全局EventListener从父级使用child.do\u something方法 有没有比这更好的方法来使用孩子 //子组件是需要访问其自己的click方法的组件 变量子项={ 道具:['item'], 数据:函数(){ 返回{ isActive:错误 } }, 模板:` {{item.kbd} `, 方法:{ 做某

在VUE中,我需要从子函数内部以及从父函数访问子函数。我有一个工作示例,但必须有更好的方法从父函数访问子函数

该示例有两个事件侦听器,当单击或按下时,这些侦听器应该展开。我想用全局
EventListener
从父级使用
child.do\u something
方法

有没有比这更好的方法来使用孩子

//子组件是需要访问其自己的click方法的组件
变量子项={
道具:['item'],
数据:函数(){
返回{
isActive:错误
}
},
模板:`
{{item.kbd}
`,
方法:{
做某事:功能(事件){
this.isActive=!this.isActive
//也做其他事情
},
},
}
//当按下某个键时,家长还需要访问“为正确的对象做些什么”
var parent=新的Vue({
el:'家长',
数据:{
密钥列表:[{
键码:“65”,
kbd:“A”
},
{
键码:“83”,
kbd:“S”
},
],
},
组成部分:{
“孩子”:孩子,
},
方法:{
击键:功能(键代码){
//找到孩子然后执行…这是最可怕的部分
const child=this.$children.find(child=>{
返回子项。$vnode.data.key==keyCode.toString()
});
孩子,做点什么
}
},
已创建:函数(){
window.addEventListener('keydown',(e)=>this.keystroke(e.keyCode));
}
})
.keys{
显示器:flex;
弹性:1;
最小高度:100vh;
对齐项目:居中;
证明内容:中心;
}
.钥匙{
保证金:1rem;
过渡:全部.07s缓解;
颜色:白色;
背景:rgba(0,0,0,0.77);
}
.玩{
转换:比例(1.1);
边框颜色:#ffc600;
盒影:0 0 1rem#ffc600;
}
kbd{
显示:块;
字号:4rem;
}

您可以使用ref,然后通过索引引用所需的特定子级。这将允许您避免使用内部值

<child v-for="(item,index) in keysList" :item="item" :key="item.keyCode" ref="children"></child>
这里修改了您的代码

//子组件是需要访问其自己的click方法的组件
变量子项={
道具:['item'],
数据:函数(){
返回{
isActive:错误
}
},
模板:`
{{item.kbd}
`,
方法:{
做某事:功能(事件){
this.isActive=!this.isActive
//也做其他事情
},
},
}
//当按下某个键时,家长还需要访问“为正确的对象做些什么”
var parent=新的Vue({
el:'家长',
数据:{
密钥列表:[{
键码:“65”,
kbd:“A”
},
{
键码:“83”,
kbd:“S”
},
],
},
组成部分:{
“孩子”:孩子,
},
方法:{
击键:功能(evt){
const index=this.keysList.findIndex(k=>k.keyCode==evt.keyCode)
this.$refs.children[index].do_something()
}
},
已创建:函数(){
window.addEventListener('keydown',this.keystroke);
}
})
.keys{
显示器:flex;
弹性:1;
最小高度:100vh;
对齐项目:居中;
证明内容:中心;
}
.钥匙{
保证金:1rem;
过渡:全部.07s缓解;
颜色:白色;
背景:rgba(0,0,0,0.77);
}
.玩{
转换:比例(1.1);
边框颜色:#ffc600;
盒影:0 0 1rem#ffc600;
}
kbd{
显示:块;
字号:4rem;
}

您可以通过向父数据按键列表中的项目添加一个以上的活动属性来实现这一点,并为匹配的按键更新活动属性。当您将物品作为道具传递给您的孩子时,您可以使用道具中的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 parent=新的Vue({
el:'家长',
数据:{
密钥列表:[{
键码:“65”,
kbd:“A”,
活动:错误
},
{
键码:“83”,
kbd:“S”,
活动:错误
}
],
},
组成部分:{
“孩子”:孩子,
},
方法:{
击键:功能(键代码){
this.keysList.forEach(key=>{key.active=key.keyCode===keyCode.toString()});
}
},
已创建:函数(){
window.addEventListener('keydown',(e)=>this.keystroke(e.keyCode));
}
})
儿童:

    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
    },
  },
}
var子项={
道具:['item'],
模板:`
{{item.kbd}
`,
方法:{
做某事:功能(事件){
//也做其他事情
},
},
}

通过这种方式,您只在一个地方管理状态,而不需要从您的家长访问您的孩子

我需要家长调用实际函数,因为另一个
//也要执行其他操作
需要调用。此外,
v-on:click='do_something'
不再切换该字段。我认为这可以通过查看活动属性并在其变为true时调用
do_something
来相当容易地实现。您可以使用
this.$emit('didsothing',event)从子处理程序发出
并使用
v-on:didsometing=“handleSometing($event)”
在家长中收听以切换活动状态。在您的子组件中添加活动道具的手表,并执行其他操作<代码>监视:{item(newValue){//基于newValue,item handle other stuff}}在这种情况下,您必须处理手表内的其他内容,并使用do_something发送给家长,我必须使用
监视:{“item.active”:函数(val){\\stuff}
为了让手表正确触发。为什么
refs
比直接访问孩子们更可取?@DavidFolkner在我看来,ref的主要优点是,ref是Vue获取组件或DOM元素句柄的指定方式。您问题中的代码是有效的,但是
$vnode
不是文档化API的一部分,因此可能会在不另行通知的情况下进行更改。真的
    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
    },
  },
}