はじめに
最近はフロントエンドも覚えたいなという事でVue.jsを触り始めてます。
んで、最初からあまり大規模のものを作ろうとすると骨が折れるし途中で投げ出したくなるので
小さなものから作ってアウトプットしていこうと思い今回タイトルにある通りのもの作ってみた。
環境
- Vue 3.2.26
- StackBlitz
最近までブラウザ上で手軽に環境構築してくれて触れるサービス探していまして、
CodeSandBoxとかも触ってみたんですけれども見た目が自分好みという浅い理由でStackBlitz使ってます
まぁ、他にも色々理由はあるんですけどでも見た目って大事じゃないですか…?
(自分だけじゃないと思いたい)
作ってみた
はい、茶番はこれぐらいにして早速作ってみました!
まず、子コンポーネントの方から。
@click="editting"
で isEdit
をフラグにして真偽値を切り替えてます。
それを v-if
で見て表示・非表示させてます。
<template>
<div class="card-wrapper">
<div class="card">
<div class="card-content" @click="editting" v-if="!isEdit">
{{ name }}
</div>
<div class="edit-area" v-if="isEdit">
<input
class="edit-input-area"
v-model="inputValue"
@keyup.enter="saveContent"
@keydown.esc="cancelEditing"
/>
<div class="btn-area">
<Button @click="saveContent">Edit</Button>
<Button @click="cancelEditing">Cancel</Button>
</div>
</div>
</div>
</div>
</template>
<script>
import Button from './Button.vue';
export default {
name: 'card',
components: {
Button,
},
data() {
return {
isEdit: false,
inputValue: '',
};
},
props: {
id: {
type: Number,
required: true,
},
name: {
type: String,
required: true,
},
onupdate: {
type: Function,
required: true,
},
},
methods: {
editting() {
this.isEdit = true;
this.inputValue = this.name;
},
saveContent() {
this.onupdate({ id: this.id, name: this.inputValue });
this.isEdit = false;
},
cancelEditing() {
this.isEdit = false;
},
},
};
</script>
<style scoped>
.card-wrapper {
border: 0.5px solid;
width: 180px;
margin-top: 10px;
padding: 5px;
padding-bottom: 7px;
border-radius: 3px;
}
.card {
}
.edit-area {
margin-top: 5px;
padding-right: 5px;
padding-left: 5px;
}
.btn-area {
display: flex;
justify-content: center;
}
</style>
親コンポーネントの方になります。
<template>
<div>
<ul>
<li v-for="item in items" :key="item.id">
<Card :="item" :onupdate="handleUpdate"></Card>
</li>
</ul>
</div>
</template>
<script>
import Card from './Card.vue';
export default {
name: 'CardList',
components: {
Card,
},
data() {
return {
shown: false,
items: [
{
id: 1,
name: 'ナポリタン',
},
{
id: 2,
name: 'キムチチャーハン',
},
{
id: 3,
name: '高菜明太マヨ牛丼',
},
{
id: 4,
name: 'チキン南蛮',
},
],
};
},
methods: {
showForm() {
this.shown = true;
},
handleUpdate(payload) {
let idx = -1;
for (let i = 0; i < this.items.length; i++) {
if (this.items[i]['id'] === payload.id) {
idx = i;
}
}
if (idx === -1) {
return;
}
this.items[idx] = payload;
},
},
};
</script>
<style scoped>
li {
list-style-type: none;
}
</style>
なんか、子コンポーネントの方に色々と書きすぎてて依存関係を整理出来ていない感がありますが
精進していきます....
データの内容は自分の好きな食べ物 (誰も興味ないっと....)
StackBlitzのリンク貼っておく
終わりに
今回はちょっとだけ、親子コンポーネントの依存関係を体系的に理解できたかなと感じました。
んでも、まだまだななので頑張って継続していこうと思います。
お手すきの際には「ここはこうした方が良いよ」とかアドバイスなんか頂けると幸いです。