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')