07-07-ref
by ZooeyLai
HTML
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/autosize.js/3.0.20/autosize.min.js"></script>
<div id="app">
<form action="">
<div class="form-group">
<input type="text" class="form-input" v-model="inputData.noteTitle" placeholder="請輸入筆記標題">
<textarea class="form-input" v-model="inputData.noteContent" placeholder="請輸入筆記內容" ref="inputData"></textarea>
<select class="form-input" v-model="inputData.selectColor">
<option value="" selected disabled>選擇顏色</option>
<option value="red">紅</option>
<option value="green">綠</option>
<option value="blue">藍</option>
</select>
<button @click="sendNote" class="btn" type='button'>送出</button>
</div>
</form>
<div
v-for="(note, index) of notes"
class="note"
:key="note.id"
:style="{ 'background-color': note.color }"
>
<div class="info">
<h3 class="title">{{note.title}}</h3>
<p class="content">{{note.content}}</p>
</div>
<button @click="delNote(note, index)" class="btn" type='button'>
刪除
</button>
</div>
</div>
CSS
*,
*::after,
*::before {
padding: 0px;
margin: 0px;
box-sizing: border-box;
line-height: 1.5;
font-size: 1rem;
}
body{
background: #F5F5F6;
}
#app{
margin: 1rem;
}
.note{
padding: 1rem;
border: 1px solid #D8DAE0;
border-radius: 0.5rem;
margin-bottom: 1rem;
color: #fff;
display: flex;
}
.info{
flex: auto;
}
.content{
font-size: 14px;
opacity: 0.75;
}
.btn {
font-size: 1rem;
padding: 0.5rem 1rem;
border: 2px solid transparent;
border-radius: 0.25rem;
background-color: #e2e8f0;
color: #475569;
cursor: pointer;
display: block;
text-align: center;
}
.form-group{
padding: 2rem;
background: #fff;
margin-bottom: 1rem;
display: flex;
flex-flow: column;
justify-content: space-between;
border-radius: 0.5rem;
gap: 0.5rem;
}
.form-input {
border: 1px solid #94a3b8;
padding: 0.5rem 1rem;
border-radius: 0.25rem;
flex: auto;
}
.form-input:focus {
border-color: #4f46e5;
box-shadow: 0px 0px 0px 3px rgba(79, 70, 229, 0.4);
outline: none;
}
JavaScript
const { createApp } = Vue
createApp({
data() {
return {
inputData:{
noteTitle: '',
noteContent: '',
selectColor: '',
},
notes: [{
title: "春節行程安排",
content: "吃飽睡,睡飽吃",
color: "red",
},
{
title: "工作待辦事項",
content: "詢問各家廠商報價",
color: "green",
},
{
title: "運動健身計畫",
content: "每天早上六點去健身",
color: "blue",
},
]
}
},
methods: {
sendNote(){
if ( this.inputData.noteTitle != '' && this.inputData.noteContent != '' && this.inputData.selectColor != ''){
let newNote = {
title: this.inputData.noteTitle,
content: this.inputData.noteContent,
color: this.inputData.selectColor,
};
//
this.notes.push(newNote);
//清空input資料
this.inputData.noteTitle = '';
this.inputData.noteContent = '';
this.inputData.selectColor = '';
console.log(newNote)
}
},
delNote(note, index) {
this.notes.splice(index, 1);
},
},
mounted() {
const saveNotes = localStorage.getItem("saveNotes");
if (saveNotes) {
this.notes = JSON.parse(saveNotes);
}
autosize(this.$refs.inputData);
},
watch :{
notes: {
handler: function(newNotes) {
localStorage.setItem('saveNotes', JSON.stringify(newNotes));
}, // 監聽 notes 狀態變化
deep: true, // 深度監聽,遞迴地監聽 notes 內部物件的變化
},
},
}).mount('#app')