关于javascript:Vue3-emit指南包含选项API组合API以及-setup-语法糖

35次阅读

共计 4298 个字符,预计需要花费 11 分钟才能阅读完成。

有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

许多 Vue 模式波及应用 props 将数据从父组件传递到子组件。但如果咱们须要一个子组件将数据传给它的父组件呢?

应用 emit,咱们能够触发事件并将数据传递到组件的层次结构中。这对上面几种状况很有用,如:

  • 从 input 中收回数据
  • 从 modal 自身外部敞开 modal
  • 父组件响应子组件

Vue Emit 是如何工作的?

当咱们 emit 一个事件时,咱们用一个或多个参数调用一个办法:

  • eventName: string – 事件的名称
  • values: any – 通过事件传递的参数

上面是一个内联 emit 的例子,<button @click="$emit('add', Math.random())">。emit 一个名为 add 的事件,并将 Math.random() 的值作为参数传递进来。

而后,在父组件应用 v-on@指令能够监听咱们的自定义增加事件并接管该参数值。

Child.vue

<template>
  <button @click="$emit('add', Math.random())">
    Add Math.random()
  </button>
</template>

Parent.vue 中监听:

<script setup>
import {ref} from 'vue'
const count = ref(0)
// 也能够从咱们的模板中调用一个函数 `<ChildComponent @add="add" />
// const add = (i) => count.value += i
</script>
<template>
  <ChildComponent @add="(i) => count += i" /> 
  <p>Count: {{count}}</p>
</template>

每次咱们点击按钮,Child.vue 都会 emit 一个 add 事件,并带有一个 0 到 1 之间的随机值。而后,Parent.vue 捕捉到这个事件,并将这个值增加到计数中。

能够传递任意多的参数,监听器也会收到所有的参数:

  • Child – $emit('add', Math.random(), 44, 50)
  • Parent – @add="(i, j, k) => count += i + j + k"

当初,咱们晓得如何在咱们的模板中 emit 内联事件,但在更简单的例子中,如果咱们从 SFC 的script 中 emit 一个事件会更好。特地是当咱们想在 emit 事件之前执行一些逻辑时,这很有用。

在 Vue 3 中,咱们有 2 种不同的办法来做到这一点:

  • 选项 API – this.$emit
  • 带有 setup() 的组合 API – context.emit
  • 带有 <script setup> 的组合 API – defineEmits()

咱们一个一个来看。

选项 API – this.$emit

在 Vue3 中,我人能够抉择应用选项 API 或组合 API。

在选项 API 中,咱们能够调用 this.$emit 来 emit 一个自定义事件。

看上面这个例子在 MyTextInput.vue 中,它蕴含一个 labelinput。每当 input 扭转时,咱们会 emit 一个事件,并将输出的值转成大写作为参数传递进来。

咱们能够不从模板中调用 $emit,而是调用一个组件办法。在该办法中调用this.$emit 并把咱们的值传给它。

MyTextInput.vue

<script>
  export default {
      methods: {handleChange (event) {this.$emit("customChange", event.target.value.toUpperCase())
          }
      }
  }
</script>

<template>
  <div>
    <label>My Custom Input</label>
    <input type="text" placeholder="Custom input!" @input="handleChange" />
  </div>
</template>

Parent.vue 中接管:

<script>
  export default {
      methods: {handleChange (event) {this.$emit("customChange", event.target.value.toUpperCase())
          }
      }
  }
</script>

<template>
  <div>
    <label>My Custom Input</label>
    <input type="text" placeholder="Custom input!" @input="handleChange" />
  </div>
</template>

带有 setup() 的组合 API – context.emit

在 组合 API 中,如果应用 setup 函数,就不能在用 this, 也就是不能调用 this.$emit() 办法了。

相同,能够应用 setup 办法中的第二个参数 context 来拜访 emit 办法。咱们能够用之前应用的事件名称和值调用context.emit

MyTextInput.vue

<script>
  export default {
    // can use the entire context object
    setup (props, context) {const handleChange = (event) => {context.emit("customChange", event.target.value)
        }
        return {handleChange}
    },
    // or we can destructure it and get `emit`
    setup (props, { emit}) {const handleChange = (event) => {emit("customChange", event.target.value)
        }
        return {handleChange}
    }
  }
</script>

<template>
  <div>
    <label>My Custom Input</label>
    <input type="text" placeholder="Custom input!" @input="handleChange" />
  </div>
</template>

<script setup> 中的用法

当咱们应用 <script setup> 时,咱们无法访问组件实例或 context 上下文参数。那咱们怎么取得 emit ?

在这种状况下,咱们能够应用 defineEmits:

  • 指定组件要 emit 事件
  • 为每个事件增加验证信息
  • 能够拜访与 context.emit 雷同的值

在最简略的状况下,defineEmits是一个字符串数组,每个字符串是一个事件的名称。

MyTextInput.vue

<script setup>
const emit = defineEmits(['customChange'])

const handleChange = (event) => {emit('customChange', event.target.value.toUpperCase())
}
</script>

然而,如果咱们传递一个对象,咱们能够为每个事件增加一个验证器函数,咱们能够在外面查看值是否是咱们所须要的格局。

像事件监听器一样,验证器承受咱们传入所有参数。

这与 prop validation 相似,如果咱们的验证器返回 false,会在控制台失去一个正告,这为咱们提供了一些有用的信息。

MyTextInput.vue

<script setup>
const emit = defineEmits({
  unvalidatedEvent: null, // if we want an event without validation
  customChange: (s) => {if (s && typeof s === 'string') {return true} else {console.warn(`Invalid submit event payload!`)
      return false
    }
  },
})

const handleChange = (event) => {
  // no console warning
  emit('customChange', event.target.value.toUpperCase())
}

onMounted(() => {emit('customChange', 1) // not a string, warning!
})
</script>

最佳实际

应用 emits 定义自定义事件。

如果咱们不应用 defineEmits,咱们依然能够通过export default 中定义 emits 选项来跟踪一个组件的自定义事件。

这对保持良好的组件文档很重要,如果咱们试图应用一个没有在 emits 中申明的事件,也会从 Vue 那里失去谬误。

当在 emits 选项中定义了原生事件 (如 change) 时,将应用组件中的事件代替原生事件侦听器。

<script>
  export default {emits: ["change"] // or can pass object with validators
  }
</script>
<template>
  <div>
    <label>My Custom Input</label>
    <input
      type="text"
      placeholder="Custom input!"
      @input='$emit("change", $event.target.value)'
    />
  </div>
</template>

正确的事件命令

在 vue3 中,与组件和 prop 一样,事件名提供了主动的大小写转换。如果在子组件中触发一个以 camelCase (驼峰式命名) 命名的事件,你将能够在父组件中增加一个 kebab-case (短横线分隔命名) 的监听器。

然而,如果你应用的是 Vue 2,事件名称没有主动的大小写转换,因为 v-on 指令会主动将你的事件名称转换为小写,所以 camelCase 命名的事件不可能被监听到。

例如,如果咱们收回了一个名为 myEvent 的事件,监听 my-event 将无奈工作。


编辑中可能存在的 bug 没法实时晓得,预先为了解决这些 bug, 花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。

作者:Noveo 译者:小智 起源:learnvue

原文:https://learnvue.co/tutorals/…

交换

有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

正文完
 0