Stencil EventEmitter 不向 Vue 实例发送数据

Stencil EventEmitter don't emit data to Vue instance

我正在尝试使用带有输入的 Stencil 创建自定义组件。我的意图是制作带有输入的组件。更改输入值后,它应该将其发送到我的 Vue 实例并在控制台记录此事件(稍后它将更新 Vue 实例中的值)。但是在 Stencil 中更改输入值后没有任何反应。

了解我使用的 Stencil 组件的工作原理:

https://medium.com/@cindyliuyn/create-a-stencil-form-input-component-for-angular-and-vue-js-22cb1c4fdec3

试图解决问题我也试过:

https://medium.com/sharenowtech/using-stenciljs-with-vue-a076244790e5

HTML 和 Vue 代码:

<!DOCTYPE html>
<html dir="ltr" lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0" />
    <title>Stencil Component Starter</title>
    <script src="https://unpkg.com/vue"></script>
    <script type="module" src="/build/vox-wc-research.esm.js"></script>
    <script nomodule src="/build/vox-wc-research.js"></script>
  </head>
  <body>
    <div id="app">
      <test-component :placeholder="placeholder" :label="label" :value="value" @valueChange="e => onValueChange"></test-component>
      {{value}}
    </div>
  </body>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        label: 'Nazwa Użytkownika',
        value: '',
        placeholder: 'Wpisz nazwę użytkownika',
      },
      methods: {
        onValueChange(e) {
          console.log(e);
        },
      },
    });
  </script>
</html>

模板组件:

import { h, Component, Element, Event, EventEmitter, Prop /* PropDidChange */ } from '@stencil/core';
@Component({
  tag: 'test-component',
  styleUrl: 'test-component.css',
  //shadow: true,
})
export class FormInputBase {
  @Element() el: HTMLElement;
  @Prop() type: string = 'text';
  @Prop() label: string;
  @Prop() placeholder: string;
  @Prop({ mutable: true }) value: string;
  @Event() valueChange: EventEmitter;

  handleChange(event) {
    const val = event.target.value;
    console.log(val);
    this.value = val;
    this.valueChange.emit(val);
  }
  render() {
    return (
      <div>
        <label>
          {this.label}
          <div>
            <input placeholder={this.placeholder} value={this.value} onInput={event => this.handleChange(event)}></input>
            {this.value}
          </div>
        </label>
      </div>
    );
  }
}

Vue 不支持驼峰式事件名称,因为所有 v-on: 事件侦听器都转换为小写(参见 https://vuejs.org/v2/guide/components-custom-events.html#Event-Names)。

然而,当您加载组件时,您可以使用 Stencil 的选项 defineCustomElements 来“转换”所有事件名称:

import { applyPolyfills, defineCustomElements } from 'my-component/loader';

applyPolyFills().then(() => {
  defineCustomElements({
    ce: (eventName, opts) => new CustomEvent(eventName.toLowerCase(), opts)
  });
});

有关更完整的示例,请查看 Ionic Framework 的源代码:

https://github.com/ionic-team/ionic-framework/blob/b064fdebef14018b77242b791914d5bb10863d39/packages/vue/src/ionic-vue.ts