Можно ли привязать свойство «selected» и обработчик «onClick» к контролируемому (в терминологии React) компоненту-флажку Vue? - PullRequest
0 голосов
/ 26 сентября 2019

Моя реализация флажка в Pug и TypeScript:

label.SvgCheckbox-LabelAsWrapper(:class="parentElementCssClass")
  input.SvgCheckbox-InvisibleAuthenticCheckbox(
    type="checkbox"
    :checked="checked"
    :disabled="disabled"
    @click.prevent="onClick"
  )
  svg(viewbox='0 0 24 24').SvgCheckbox-SvgCanvas
    path(
      v-if="!checked"
      d='M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3M19,5V19H5V5H19Z'
    ).SvgCheckbox-SvgPath.SvgCheckbox-SvgPath__Unchecked
    path(
      v-else
      d='M10,17L5,12L6.41,10.58L10,14.17L17.59,6.58L19,8M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z'
    ).SvgCheckbox-SvgPath.SvgCheckbox-SvgPath__Checked
  span(v-if="text").SvgCheckbox-AppendedText {{ text }}
import { Vue, Component, Prop } from 'vue-property-decorator';

@Component
export default class SimpleCheckbox extends Vue {

  @Prop({ type: Boolean, required: true }) private readonly checked!: boolean;

  @Prop({ type: Boolean, default: false }) private readonly disabled!: boolean;

  @Prop({ type: String }) private readonly text?: string;
  @Prop({ type: String }) private readonly parentElementCssClass?: string;

  @Prop({ type: Function, default: () => {} }) private readonly onClick!: () => void;
}

Пока не знаю, есть ли эквивалент в Vue, но в терминологии React, вышеуказанный компонент "контролируется", напримерповедение HTML по умолчанию было переопределено внешней логикой.Я делаю этот выбор, чтобы избежать отслеживания «проверенного» значения: проверено это или нет, оно будет полностью зависеть от некоторого состояния vuex, и только соответствующая мутация vuex может изменить проверенное состояние.

Использование:

SimpleCheckbox(
  :checked="relatedStoreModule.doNotPreProcessMarkupEntryPointsFlag"
  :onClick="relatedStoreModule.toggleDoNotPreProcessMarkupEntryPointsFlag"
  parentElementCssClass="RegularCheckbox"
)
import { Component, Vue } from "vue-property-decorator";
import { getModule } from "vuex-module-decorators";
import ExampleStoreModule from "@Store/modules/ExampleStoreModule";
import template from "@Templates/ExampleTemplate.pug";
import SimpleCheckbox from "@Components/Checkboxes/MaterialDesign/SimpleCheckbox.vue";

@Component({
  template,
  components: {
    SimpleCheckbox
  }
})
export default class MarkupPreProcessingSettings extends Vue {
  private readonly relatedStoreModule: ExampleStoreModule = getModule(ExampleStoreModule);
}
import { VuexModule, Module, Mutation } from "vuex-module-decorators";
import store, { StoreModuleNames } from "@Store/Store";


@Module({ name: StoreModuleNames.example, store, dynamic: true, namespaced: true })
export default class ExampleStoreModule extends VuexModule {

  private _doNotPreProcessMarkupEntryPointsFlag: boolean = true;

  public get doNotPreProcessMarkupEntryPointsFlag(): boolean {
    return this._doNotPreProcessMarkupEntryPointsFlag;
  }

  @Mutation
  public toggleDoNotPreProcessMarkupEntryPointsFlag(): void {
    this._doNotPreProcessMarkupEntryPointsFlag = !this._doNotPreProcessMarkupEntryPointsFlag;
  }
}

вызывает ошибки:

vue.common.dev.js:630 [Vue warn]: $attrs is readonly.
vue.common.dev.js:630 [Vue warn]: $listeners is readonly.

Avoid mutating a prop directly since the value will be overwritten whenever 
the parent component re-renders. Instead, use a data or computed property 
based on the prop's value. Prop being mutated: "checked"

Я не до конца понимаю, что происходит: значение динамического атрибута едва ли что-то не так, скорее всего проблема в ...

SimpleCheckbox(
  :checked="relatedStoreModule.doNotPreProcessMarkupEntryPointsFlag"
  // ... here:
  :onClick="relatedStoreModule.toggleDoNotPreProcessMarkupEntryPointsFlag"
  parentElementCssClass="RegularCheckbox"
)

Полагаю, правильное решение не будет таким элегантным: возможно, потребуется создать беспорядок наблюдателями, дополнительными свойствами компонентов и методами и т. Д.

Что янеправильно и какая версия правильного (с точки зрения Vue) решения является самой короткой?

...