我在学VueJS.我正在计算他们的货币有效性.

Vue.component('currency-input', {
  template: `
    <span>
      $
      <input
        ref="input"
        v-bind:value="value"
        v-on:input="updateValue($event.target.value)">
    </span>
  `,
  props: ['value'],
  methods: {
    // Instead of updating the value directly, this
    // method is used to format and place constraints
    // on the input's value
    updateValue: function (value) {
      var formattedValue = value
        // Remove whitespace on either side
        .trim()
        // Shorten to 2 decimal places
        .slice(
          0,
          value.indexOf('.') === -1
            ? value.length
            : value.indexOf('.') + 3
        )
      // If the value was not already normalized,
      // manually override it to conform
      if (formattedValue !== value) {
        this.$refs.input.value = formattedValue
      }
      // Emit the number value through the input event
      this.$emit('input', Number(formattedValue))
    }
  }
})

updateValue函数底部的$emit调用触发一个输入事件.

当我把它 comments 出来时,实时货币验证不再有效.所以我意识到这是有目的的.

但为什么要在输入事件中触发输入事件呢?

您可能认为输入事件会再次触发,导致updateValue处理程序再次触发,导致递归调用导致堆栈溢出.

我理解VueJS的简单得多的$emit示例代码.这就像Jquery的触发器函数一样.

vm.$on('test', function (msg) {
  console.log(msg)
})
vm.$emit('test', 'hi')
// -> "hi"

但是在货币验证的例子中,我不明白为什么$emit是这样使用的,为什么它是这样工作的.

有人能解释一下吗?

推荐答案

这里的Emit调用允许您在父上下文中钩住事件.v-model指令还使用输入事件来处理与组件的双向绑定.

v-model='model'基本上是v-bind:value='model' v-on:input='model = $event.target.value',加上一些额外的比特,让它玩得很好.当您移除this.$emit('input', Number(formattedValue))时,您正在移除更新组件外部值的机制.

编辑:@Jay小心你有时的愿望

HTML中的所有元素都有一系列用于常见事件的本机处理程序;调整大小、加载、卸载等.这些功能处理页面在呈现时发生变化时的操作,可以禁用或添加到页面上,因为JavaScript浏览器的引入使用了一个事件泵系统,允许在引发事件时将多个函数附加到任何按顺序运行的事件.例如,可以在resize上运行3个函数来处理边缘情况,例如最小/最大大小、屏幕方向等.

表单元素通常实现自己的基本事件函数:keydown、keyup、mousedown、mouseup.这些基本函数调用事件,使我们作为开发人员的生活变得更轻松,它们是:输入、模糊、聚焦.有些有专门的事件,比如在select元素中实现变更,表单标签实现提交.

焦点上的输入标记捕获键盘输入,并显示文本输入光标,以指示它已准备好接收输入.它添加了tab键代码的处理程序,该处理程序将查找下一个可用的输入,并将焦点转移到该元素.事件泵风格的功能系统在这里非常棒,因为它允许您绑定到焦点,并在聚焦输入时更改背景 colored颜色 或边框,而无需实现捕获输入或自己显示光标的代码.

输入标记在输入时也会引发input事件,指示输入已更改,告诉浏览器更改值并更新显示,以便用户预期的功能保持一致.

currency-input示例中,我们添加了updateValue函数来处理本机函数并处理事件的输入值,在updateValue函数中,我们修改了值的字符串表示形式,并需要放置它.您可以简单地添加一个数据属性来保存该值,并将输入的value属性绑定到data属性,允许currency-input在内部处理结果的显示,但这会将该值锁定在私有访问器后面,并且您将无法修改或检索结果货币格式值的值.

使用this.$emit('input', Number(formattedValue))时,updateValue函数的行为与本机input标记类似,它会引发一个可以由父上下文捕获并处理的事件.您可以将其存储在值中,将其用作函数的基础,甚至完全忽略它,尽管这可能没有多大帮助.这允许您跟踪输入的值,并根据需要对其进行修改,或将其发送到服务器、显示等.

它还与几个最有针对性的指令v-model相关联,这是一种语法糖,允许value属性绑定和input事件绑定到当前上下文中的数据属性.通过提供valueprops 并发出input事件,自定义元素的行为可以类似于Vue应用程序系统中的本机表单元素.当您想要打包、分发或重用组件时,这是一项极具吸引力的功能.

go 那里好多了:

...
<currency-input v-model='dollarValue'></currency-input>
<input v-model='dollarValue'>
...

而不是在所有地方添加valueinput个绑定:

...
<currency-input v-bind:value='dollarValue' v-on:input='updateDollarValue($event.target.value)'></currency-input>
<input v-bind:value='dollarValue' v-on:input='updateDollarValue($event.target.value)'>
...

现在,我的奇怪的漫谈已经结束,我希望这有助于理解currency-input个例子背后的一些模式和推理.

Vue.js相关问答推荐

在 Nuxt3 中使用 Vue3 vue-ganntastic 插件

Vuetify右侧并排switch

在计算(computed)属性上调用数组方法

如何在 vue js 的一页路由下显示不同的 category._id

在 bootstrap-vue 中渲染自定义样式

props至少应该定义它们的类型

VuetifyJS,outer-link 未显示为光标

Vue:限制文本区域输入中的字符,截断过滤器?

使用 vue.js 的 axios 预检失败错误 301

使用 aria-live 在 vue.js 中向屏幕阅读器宣布信息

更新 v-for 中使用的数组内的对象时,Vue js react性问题

如何将参数传递给使用 ...mapActions(...) 映射的函数?

如何在nuxt路由中添加meta?

使用 VueJS 在 v-for 中转换

Vuetify - 如何在 v-data-table 中单击时突出显示行

在 Vue.js 中,为什么我们必须在导入组件后导出它们?

如何在 VueJS 中访问 [__ob__: Observer] 的元素?

在加载数据之前触发mounted方法 - VueJS

是否有 v-cloak 逆?

Vuex 模块Mutations