Vue로 양식 구성 요소에 맞서기
17585 단어 AtomicDesignVue.js자바스크립트ゔ그림x초보자
소개
어떤 웹 서비스에도 "양식"이 필요하다고 생각합니다.
「문의 폼」이나 「신규 회원 등록 폼」이나 「탈퇴 폼」등…
그 밖에도 마케팅의 시책으로, LP로부터의 비행처로서 회원 획득을 위한 폼을 여러가지 만들 수도 있을지도 모릅니다.
저도 웹 업계에 들어가 많은 양식을 만들어 왔습니다.
그리고 어느 때 문득 이렇게 생각했습니다.
「이것, 폼을 컴퍼넌트화해 버리면 편해질까요… 」
그렇게 생각해 버리면, 이제 엔지니어의 성으로서 실행하지 않고 있을 수 없습니다.
내가 할거야.
우선은, 아래와 같은 간단한 문의 폼의 컴퍼넌트화를 생각해 갑니다.
프레임워크는 경량 Vue+TypeScript를 선택했습니다.
이 양식의 사양을 간략하게 설명하면,
같은 곳입니다.
구성 요소의 입도 어떻게?
컴퍼넌트를 만들려고 했을 때에 고민해 버리는 것이, 컴퍼넌트의 입도.
어떻게 정리하는 것이 좋다고 생각해도 어쩔 수 없기 때문에, 여기는 기존의 시스템에 탑니다.
아직도 역시, 이용하는 것은 「Atomic Design」입니까.
Atomic Design에 대해서 간단히 설명하면, 입도마다 「Atoms」 「Molecules」 「Organisms」라고 하는 것처럼 분류하는 녀석입니다만, 자세한 것은 하기 링크등을 참고로 해 주세요.
Atomic Design을 알게 될거야.
이번 컴포넌트화하는 폼을 분류하면 아래와 같이 될까 생각합니다.
이것을 소스에 떨어뜨려 갑니다.
프로그램 작성
우선은 빨리 어플리케이션의 기동에 필요한 코드를 써 갑니다.
덧붙여 앞으로의 소스는, 형편상 여러가지 간략화하면서 써 있으므로, 그대로 복사해도 움직이지 않습니다.
분위기를 느껴보세요.
application.tsimport Vue from 'vue';
import App from './App.vue';
import router from './_router';
import store from './_store';
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');
store는 나중에 사용하기 때문에 어쩌면 import 해 둡니다.
App.vue<template>
<div id="app">
<Form />
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import Form from './components/organisms/Form.vue';
@Component({
components: {
Form
}
})
export default class App extends Vue {}
</script>
여기서 마침내 Orgamisms가 등장합니다.
또한 vue-property-decorator라는 플러그인을 사용하고 있으므로 그쪽에 관해서는 아래를 참조하십시오.
처음의 vue-property-decorator (nuxt에도 대응)
form.vue<template>
<div>
<div v-for="order in this.$store.state.config.order" :key="order.type">
<FormBox :config="order" />
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import FormBox from '../../components/molecules/FormBox.vue';
@Component({
components: {
FormBox
}
})
export default class Form extends Vue {};
</script>
여기서 갑자기 store라든지 나오고 있습니다만, placeholder라든지 input의 타입이라든지 한 곳에 정리해 두는 편이 즐거울 것 같기 때문에 그렇게 하고 있습니다.
_store.tsimport Vue from 'vue';
import Vuex, { MutationTree } from 'vuex';
Vue.use(Vuex);
type Order = {
title: string, //FormTitleに入れる文字列
type: string, //inputのタイプ
note: string, //FormNoteに入れる文字列
placeholder: string,
name: string,
id: string,
maxlength: number,
required: boolean
}
type State = {
order: order[];
}
이 정보를 Molecules의 폼의 행을 생성하고 있는 「FormBox」에 건네주고 있으므로, 나머지는 그것에 따라서 Atoms를 묘화해 갈 뿐입니다.
Atoms의 예↓
FormTitle.vue<template>
<label>
<slot></slot>
</label>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class FormLabel extends Vue {}
</script>
TextInput.vue<template>
<div>
<input :placeholder="placeholder" :name="name" :id="id" :maxlength="maxlength" @input=onInput>
<p>{{ error }}</p>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
export default class TextInput extends Vue {
@Prop() type!: string;
@Prop() placeholder!: string;
@Prop() name!: string;
@Prop() id!: string;
@Prop() maxlength!: number;
@Prop() isRequired!: boolean;
private onInput(event: InputEvent) {
const type: string = this.type;
const inputText: string = event.target.value;
this.inputValid(type, inputText);
}
private inputValid(type: string, text: string) {
switch(type) {
case 'name':
this.nameValidate(text);
break;
case 'phoneticName':
this.phoneticNameValidate(text);
break;
case 'email':
this.emailValidate(text);
break;
case 'tel':
this.telValidate(text);
break;
default:
break;
}
}
…省略
}
</script>
요약
전체상은 쫓아가도록 썼습니다만, 어떻습니까.
컴포넌트화를 진행하는데 있어서는 아래가 중요할까 생각합니다.
우선은 빨리 어플리케이션의 기동에 필요한 코드를 써 갑니다.
덧붙여 앞으로의 소스는, 형편상 여러가지 간략화하면서 써 있으므로, 그대로 복사해도 움직이지 않습니다.
분위기를 느껴보세요.
application.ts
import Vue from 'vue';
import App from './App.vue';
import router from './_router';
import store from './_store';
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');
store는 나중에 사용하기 때문에 어쩌면 import 해 둡니다.
App.vue
<template>
<div id="app">
<Form />
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import Form from './components/organisms/Form.vue';
@Component({
components: {
Form
}
})
export default class App extends Vue {}
</script>
여기서 마침내 Orgamisms가 등장합니다.
또한 vue-property-decorator라는 플러그인을 사용하고 있으므로 그쪽에 관해서는 아래를 참조하십시오.
처음의 vue-property-decorator (nuxt에도 대응)
form.vue
<template>
<div>
<div v-for="order in this.$store.state.config.order" :key="order.type">
<FormBox :config="order" />
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import FormBox from '../../components/molecules/FormBox.vue';
@Component({
components: {
FormBox
}
})
export default class Form extends Vue {};
</script>
여기서 갑자기 store라든지 나오고 있습니다만, placeholder라든지 input의 타입이라든지 한 곳에 정리해 두는 편이 즐거울 것 같기 때문에 그렇게 하고 있습니다.
_store.ts
import Vue from 'vue';
import Vuex, { MutationTree } from 'vuex';
Vue.use(Vuex);
type Order = {
title: string, //FormTitleに入れる文字列
type: string, //inputのタイプ
note: string, //FormNoteに入れる文字列
placeholder: string,
name: string,
id: string,
maxlength: number,
required: boolean
}
type State = {
order: order[];
}
이 정보를 Molecules의 폼의 행을 생성하고 있는 「FormBox」에 건네주고 있으므로, 나머지는 그것에 따라서 Atoms를 묘화해 갈 뿐입니다.
Atoms의 예↓
FormTitle.vue
<template>
<label>
<slot></slot>
</label>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class FormLabel extends Vue {}
</script>
TextInput.vue
<template>
<div>
<input :placeholder="placeholder" :name="name" :id="id" :maxlength="maxlength" @input=onInput>
<p>{{ error }}</p>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
export default class TextInput extends Vue {
@Prop() type!: string;
@Prop() placeholder!: string;
@Prop() name!: string;
@Prop() id!: string;
@Prop() maxlength!: number;
@Prop() isRequired!: boolean;
private onInput(event: InputEvent) {
const type: string = this.type;
const inputText: string = event.target.value;
this.inputValid(type, inputText);
}
private inputValid(type: string, text: string) {
switch(type) {
case 'name':
this.nameValidate(text);
break;
case 'phoneticName':
this.phoneticNameValidate(text);
break;
case 'email':
this.emailValidate(text);
break;
case 'tel':
this.telValidate(text);
break;
default:
break;
}
}
…省略
}
</script>
요약
전체상은 쫓아가도록 썼습니다만, 어떻습니까.
컴포넌트화를 진행하는데 있어서는 아래가 중요할까 생각합니다.
이상입니다.
계속해서 Vue의 지견으로 공유할 수 있는 것이 있으면, 투고해 나갈 예정입니다.
Reference
이 문제에 관하여(Vue로 양식 구성 요소에 맞서기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/daiend/items/b179bbeae588429107ae텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)