Есть ли возможность запустить функцию компонента Stencil из родительского экземпляра Vue?

Я хотел бы, например, запустить метод callChild() в экземпляре Vue, который вызовет doSomething() в компоненте Stencil.

Главный, html файл с файлом кода vue, который содержит компонент трафарета:

<body>
    <div id="app">
      <test-component :rules="[required, passwordRule]" :placeholder="placeholder" :label="label" :value="value" @valueChange="e => onValueChange"></test-component>
      {{value}}
      <button @click="foo()">Test</button>
    </div>
  </body>
  <script>
    var app = new Vue({
      el: '#app',
      data() {
        return {
          label: 'Nazwa Użytkownika',
          value: '',
          placeholder: 'Wpisz nazwę użytkownika',
          required: v => !!v || 'This field is required',
          passwordRule: v => v.length >= 8 || 'Your password is too short',
        };
      },
      methods: {
        callChild() {
          //this function should trigger bar() function in stancil <test-component>
        },
        onValueChange(e) {
          console.log(e);
        },
      },
    });
  </script>

Код компонента трафарета:

import { h, Component, Element, Event, EventEmitter, State, Watch, Prop, Method } 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() rules: Array<Function>;
  @Prop() placeholder: string;
  @Prop({ mutable: true }) value: string;
  @Prop() hidedetails: boolean;
  @Event() valueChange: EventEmitter;

  @State() errorDetails: any;
  @State() showError: boolean = false;

  @Watch('value')
  watchHandler(newValue: string, oldValue: string) {
    console.log('The new value of activated is: ', newValue, 'Old val: ', oldValue);
    console.log(this.required(newValue));
    if (this.required(newValue) != true) {
      this.errorDetails = this.required(newValue);
      this.showError = true;
    } else {
      this.showError = false;
    }

    console.log(this.rules);
  }

  required = v => !!v || 'This field is required';

  @Method()
  async testClick(val) {
    await console.log(val);
  }

  @Method()
  doSomething() {
    //do something
  }

  handleChange(event) {
    const val = event.target.value;
    console.log(val);
    this.value = val;
    this.valueChange.emit(val);
  }
  render() {
    if (this.hidedetails) {
      return (
        <div>
          <label>
            {this.label}
            <div>
              <input placeholder={this.placeholder} value={this.value} onInput={event => this.handleChange(event)}></input>
            </div>
          </label>
        </div>
      );
    } else {
      return (
        <div>
          <label>
            {this.label}
            <div>
              <input placeholder={this.placeholder} value={this.value} onInput={event => this.handleChange(event)}></input>
              <div class="error-details">
                <div class={this.showError ? 'text-active' : 'text-inactive'}>{this.errorDetails}</div>
              </div>
              <button onClick={this.testClick}>Kilknij mnie!</button>
            </div>
          </label>
        </div>
      );
    }
  }
}

1
BobiDaHombre 12 Фев 2021 в 17:44

1 ответ

Лучший ответ

Хорошо - ответ прост. Вам нужно использовать исх. Просто добавьте тег ref к элементу в html:

<test-component ref="form" :rules="[required, passwordRule]" :placeholder="placeholder" :label="label" :value="value" @valueChange="e => onValueChange"></test-component>

И тогда метод Vue должен выглядеть так:

foo() {
          this.$refs.form.bar();
        },

Где bar () - это точное имя метода в компоненте Your Stencil.

0
BobiDaHombre 15 Фев 2021 в 13:07