programing

TypeScript 기반 Vue에서 vuex 상태 및 돌연변이를 확인란 구성 요소 속성에 바인딩합니다.

shortcode 2022. 7. 26. 23:51
반응형

TypeScript 기반 Vue에서 vuex 상태 및 돌연변이를 확인란 구성 요소 속성에 바인딩합니다.

문제

Vue 구성 요소로 다음과 같은 확인란을 만듭니다.

  1. 와 이벤트핸들러 및 이벤트핸들러도 사용할 수 있는 체크박스의 내부 는 사용할 수 없습니다.모든 이벤트 핸들러 및checked논리에 합니다. 논리는 이 논리에 따라 수 .vuexstorediscloss.discloss.를 선택합니다.
  2. 안가 켜져 없든 논리에 '체크'가 켜져 있습니다).체크박스가 켜져 있든 없든 외부 논리에 따라 다릅니다.예예 、 를를 、 ,를 、vuex 또는 state getter를 지정합니다.

시행 1

개념.

에는 '''가 있습니다.checked ★★★★★★★★★★★★★★★★★」onClick값이 경로를 벗어난 속성은 동적일 수 있습니다.

요소

Pug 언어로 된 템플릿:

label.SvgCheckbox-LabelAsWrapper(:class="rootElementCssClass" @click.prevent="onClick")
  input.SvgCheckbox-InvisibleAuthenticCheckbox(
    type="checkbox"
    :checked="checked"
    :disabled="disabled"
  )
  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;
}

스토어 모듈

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;
  }
}

사용.

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({ components: { SimpleCheckbox } })
export default class MarkupPreProcessingSettings extends Vue {
  private readonly relatedStoreModule: ExampleStoreModule = getModule(ExampleStoreModule);
}

워링스

체크박스를 클릭하면 표시됩니다.확인란은 필요에 따라 작동하지만 일부 Vue 개념을 위반했습니다.

여기에 이미지 설명 입력

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

found in

---> <SimpleCheckbox> at hikari-frontend/UiComponents/Checkboxes/MaterialDesign/SimpleCheckbox.vue
       <MarkupPreProcessingSettings>
         <Application> at ProjectInitializer/ElectronRendererProcess/RootComponent.vue
           <Root>

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

found in

---> <SimpleCheckbox> at hikari-frontend/UiComponents/Checkboxes/MaterialDesign/SimpleCheckbox.vue
       <MarkupPreProcessingSettings>
         <Application> at ProjectInitializer/ElectronRendererProcess/RootComponent.vue
           <Root>

vue.common.dev.js:630 [Vue warn]: 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"

found in

---> <SimpleCheckbox> at hikari-frontend/UiComponents/Checkboxes/MaterialDesign/SimpleCheckbox.vue
       <MarkupPreProcessingSettings>
         <Application> at ProjectInitializer/ElectronRendererProcess/RootComponent.vue
           <Root>

사색

이 주의는 일부 vue-property가 내부 구성 요소에서 할당된 새 값이기 때문에 발생합니다.분명히, 나는 이런 조작을 하지 않았다.

는 문문 the the the the the the에 있다.:onClick="relatedStoreModule.toggleDoNotPreProcessMarkupEntryPointsFlag"된 것 요.<component>.$props.onClick="<vuex store manipulations ...>" - 암묵적 특성 돌연변이입니다.

트라이 2

개념.

Vue 설명서, 구성 요소 사용자 지정 섹션:

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})

vue-property-decorator를 사용하는 TypeScript는 다음과 같습니다.

import { Vue, Component, Model } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
  @Model('change', { type: Boolean }) readonly checked!: boolean
}
Component
label.SvgCheckbox-LabelAsWrapper(:class="rootElementCssClass")
  input.SvgCheckbox-InvisibleAuthenticCheckbox(
    type="checkbox"
    :checked="checked"
    :disabled="disabled"
    @change="$emit('change', $event.target.checked)"
  )
  svg(viewbox='0 0 24 24').SvgCheckbox-SvgCanvas
    // ...
import { Vue, Component, Prop, Model } from "vue-property-decorator";

@Component
export default class SimpleCheckbox extends Vue {

  @Model('change', { type: Boolean }) readonly checked!: boolean;

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

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

사용.

SimpleCheckbox(
  v-model="doNotPreProcessMarkupEntryPointsFlag"
  rootElementCssClass="RegularCheckbox"
)

TypeScript를 v-modelsetter: getter를 해야 합니다.

@Component({
  template,
  components: {
    SimpleCheckbox,
    // ...
  }
})
export default class MarkupPreProcessingSettings extends Vue {

  private readonly relatedStoreModule: MarkupPreProcessingSettingsStoreModule =
      getModule(MarkupPreProcessingSettingsStoreModule);
  //...
  private get doNotPreProcessMarkupEntryPointsFlag(): boolean {
    return this.relatedStoreModule.doNotPreProcessMarkupEntryPointsFlag;
  }

  private set doNotPreProcessMarkupEntryPointsFlag(_newValue: boolean) {
    this.relatedStoreModule.toggleDoNotPreProcessMarkupEntryPointsFlag();
  }
}

경고.

동일한 오류 세트:

여기에 이미지 설명 입력

제한 사항

먼저 Vue Component 클래스에서 getter와 setter를 새로 만들어야 합니다.id는 피할 수 있으면 좋겠습니다.유감스럽게도 vuex 클래스(vuex-module-decorator에 의한)의 경우 TypeScript setter를 사용할 수 없습니다.@Mutation신 - syslog syslog 메 메 메 메 syslog syslog syslog syslog syslog syslogsyslog

이 은, ,, 음, 음, 음으로 .v-for이 솔루션을 사용할 수 없게 됩니다.

트라이 3

개념.

이벤트 이미터 및 커스텀이벤트 리스너 사용 현황이 솔루션도 정상적으로 동작하지만 Vue에서 경고가 발생합니다.

요소

label.SvgCheckbox-LabelAsWrapper(:class="rootElementCssClass" @click.prevent="$emit('toggled')")
  // ...

사용.

SimpleCheckbox(
  :checked="relatedStoreModule.doNotPreProcessMarkupEntryPointsFlag"
  @toggled="relatedStoreModule.toggleDoNotPreProcessMarkupEntryPointsFlag"
  rootElementCssClass="RegularCheckbox"
)

경고.

여기에 이미지 설명 입력


갱신하다

아직 수수께끼가 남아 있지만 문제는 해결되었다.아래 답변을 참조하십시오.

전자.SimpleCheckbox에서 왔다node_modules그러나, 그러나 이 라이브러리는 아직 개발 중이고, 그래서 그것은 에 의해 제공되었습니다.npm link.

를 하려고 때 SPA를 배치했습니다.SimpleCheckbox(에서 취득하지 않음)node_modules첫 번째 솔루션은 효과가 있습니다. (두 번째와 세 번째 솔루션은 상관없습니다.껍질만 우아하게 다듬으면 됩니다.)

나는 그 원인을 제시했다.npm link, 라이브러리를 공개하고 를 통해 설치합니다.npm install경고가 사라졌습니다!

결론

이 일이 처음은 아니었다npm link이런 문제를 일으킵니다.여기 또 다른 사례가 있다.

나는 아직도 이 사건을 깊이 이해하지 못하고 있다. 나는 방금 실험 자료를 발표했다."그럼, 만약 도서관이 아직 개발 중이라면?"이라는 질문에는 아직 답이 없습니다.저는 Lerna를 시도했습니다.처음에는 경고가 사라졌지만, Lerna로 프로젝트를 옮겼을 때 다시 경고가 나타납니다.아직은 규칙성이 불분명합니다.

나는 그것이 타이프스크립트 기반의 문제인지 잘 모르겠다.

당신의 경고 메시지와 코드에 따르면, 나는 당신이 그 코드를 사용했다는 것을 알 수 있습니다.prop로서input모델.

디폴트로는prop변환은 허용되지 않습니다.

변이시키는 것은 나쁜 생각일 수 있다.prop아무리 그래도Object또는Array. (소재가Object또는Array, 어린이 돌연변이가 가능하지만 권장되지 않습니다.)

이 경고를 방지하려면 다음과 같이 하위 항목에서 소품 복제본인 데이터를 사용할 수 있습니다.

props: {
  checked: {
    type: Boolean,
    default: false,
  },
  change: {
    type: Function,
    default: () => {},
  }
},
data: {
  checkedModel: false,
},
mounted() {
  this.checkedModel = this.checked; // init model value as prop
}

언급URL : https://stackoverflow.com/questions/58110755/bind-vuex-state-and-mutations-to-checkbox-component-properties-in-typescript-bas

반응형