Vue custom To Do App

Todo គឺជា App សម្រាប់ឲ្យយើងកំណត់ចំណាំថាយើងត្រូវធ្វើអ្វី ហើយយើងបានធ្វើអ្វីរួចហើយ។

បន្ទាប់ពីយើងបាន install project រួចហើយយើងចាប់ផ្ដើមអនុវត្តន៍


Card

មុនដំបូងធ្វើ Card មួយយកមកប្រើ ដោយយើងបង្កើត file មួយឈ្មោះថា Card.vue

<template>
    <div class="card">
        <div class="txt">{{ content }}</div>
        <div class="btn-box">
            <button class="btn-check">✓</button>
            <button class="btn-cross">✗</button>
        </div>
    </div>
</template>

<script setup>
    name: 'Card'
   const props = defineProps({
    content: {
        type: String
    }
   })
</script>

<style>
.card{
    width: 100%;
    background-color: #ecf0f1;
    color: black;
    border-radius: 8px;
    display: flex;
    margin: 5px;
}
.card .txt,.btn-box{
    display: flex;
    padding: 10px;
    font-size: 18px;
    align-items: center;
}
.card .btn-box{
   margin-left: auto;
}
.card .btn-box button{
    font-size: 18px;
    margin-left: 5px;
    cursor: pointer;
    padding: 5px;
    border-radius: 5px;
    border: 0px;
    padding-left: 20px;
    padding-right: 20px;
}
.card .btn-box .btn-check{
    background-color: #c3c3c3;
    color: white;
}
.card .btn-box .btn-cross{
    background-color: #eb3b5a;
    color: white;
}
</style>

ចំពោះ file Card.vue យើងប្រើ slot ជំនួស button វិញ

<template>
    <div class="card">
        <div class="txt">{{ content }}</div>
        <slot></slot>
    </div>
</template>

File App.vue

នៅផ្នែកខាងនេះយើងហៅ file Card.vue មកប្រើ

<template>
    <Card>dfdf</Card>
</template>

<script setup>
 import Card from '@/components/Card.vue';
</script>

Custom Input

យើងធ្វើ input ទិន្ន័យនៅក្នុង file App.vue

<template>
    <div class="contain">
        <form class="form-input">
            <input type="text" placeholder="Add todo">
            <button class="btn-gb">Add</button>
        </form>
    </div>
</template>

<script setup>
 import Card from '@/components/Card.vue';
</script>

<style>
body{
  background-color: rgba(0, 0, 0, 0.69);
}
.contain{
  width: 500px;
  margin: 0 auto;
}
.form-input{
  padding: 8px;
}
.form-input input{
  padding: 10px;
  border-radius: 8px;
  width: 79%;
  margin-right: 10px;
  border: 1px solid;
  font-size: 18px;
}
.form-input button{
  /* padding: 10px; */
  font-size: 16px;
  padding: 10px 20px 10px 20px;
  border: 0px;
  background-color: #4b7bec;
  color: white;
  border-radius: 8px;
  cursor: pointer;
}
</style>

Custom Card របស់យើង នៅ file App.vue
<template>
    <div class="contain">
        <form class="form-input">
            <input type="text" placeholder="Add todo">
            <button class="btn-gb">Add</button>
        </form>
        <!--MARK: Custom Card-->
        <card>
            <div class="txt">Hello</div>
            <div class="btn-box">
                <button class="btn-check">✓</button>
                <button class="btn-cross">✗</button>
            </div>
        </card>
    </div>
</template>

ការងារជាមួយ javaScript vue

យើង import ref និង បង្កើតទិន្ន័យជា Array មួយសម្រាប់ហៅមកប្រើ

<script setup>
 //MARK: Import
 import Card from '@/components/Card.vue';
 import { ref } from 'vue';

 //MARK: To Do
 const todos = ref([
    {
        id: 'id1',
        article: 'Cooking Rice',
        done: false
    },
    {
        id: 'id2',
        article: 'Read book',
        done: false
    }])
</script>

ទាញទិន្ន័យទៅដាក់នៅ Card ដោយប្រើ v-for

<card 
            v-for="todo in todos"
        >
            <div class="txt">{{ todo.article }}</div>
            <div class="btn-box">
                <button class="btn-check">✓</button>
                <button class="btn-cross">✗</button>
            </div>
        </card>

Add todo

បញ្ចូលទិន្ន័យ ឬ add to do ពីខាងក្រៅ។ នៅចំនុចនេះខ្ញុំសុំ install npm uuid ដើម្បីធ្វើជា id auto

បិទទិន្ន័យពី Array todos សិន

<script setup>
 //MARK: Import
 import Card from '@/components/Card.vue';
 import { ref } from 'vue';
 import { v4 as uuidv4 } from 'uuid';

 //MARK: To Do
 const todos = ref([
    // {
    //     id: 'id1',
    //     article: 'Cooking Rice',
    //     done: false
    // },
    // {
    //     id: 'id2',
    //     article: 'Read book',
    //     done: false
    // }
])
//MARK: Add To Do
const newArticleTodo = ref()
const addTodo = ()=>{
    const newTodo ={
        id: uuidv4(),
        article: newArticleTodo.value,
        done: false
    }
    todos.value.unshift(newTodo)
    newArticleTodo.value = ''
}
</script>
<form class="form-input" @submit.prevent="addTodo">
            <input 
            v-model="newArticleTodo"
            type="text" placeholder="Add todo">
            <button class="btn-gb">Add</button>
        </form>

Disable button Add

ធ្វើការបិទនៅពេលប្រអប់បញ្ចូលទទេគឺមិនអាចចុច button Add បានទេ

<button 
            :disabled="!newArticleTodo"
            class="btn-gb">Add</button>

Delete To Do

លុបទិន្ន័យពី Array ដោយយើងលុបតាមរយៈ id

<script setup>
 //MARK: Import
 import Card from '@/components/Card.vue';
 import { ref } from 'vue';
 import { v4 as uuidv4 } from 'uuid';

 //MARK: To Do
 const todos = ref([
    {
        id: 'id1',
        article: 'Cooking Rice',
        done: false
    },
    {
        id: 'id2',
        article: 'Read book',
        done: false
    }
])
//MARK: Delete To Do
const deleteTodo = id =>{
    todos.value = todos.value.filter(todo => todo.id !== id)
}
</script>
<button
                @click="deleteTodo(todo.id)" 
                class="btn-cross">✗</button>
            </div>
        </card>

Mark Done

នៅចំណុចនេះធ្វើឲ្យមាន highlingh នៅពេល Array done is true។ ដើម្បីធ្វើឧទាហរណ៍ យើងដាក់ Array done យើង true មួយ។

custome style background នៃ Card

<card 
      v-for="todo in todos"
      :class="{sucess: todo.done}"
     >

Custome Button Check ដោយយើងប្រើ tourney។ សូមលុបឈ្មោះ class style ចោលសិន

<button
         :class="todo.done? 'btnSucess': 'btn-check' " 
         class=" ">✓</button>
         <button

ការឆ្នូតអក្សរ

<div 
      :class="{line: todo.done}"
      class="txt">{{ todo.article }}</div>

Style css

.btnSucess{
  background-color: #4834d4;
  color: white;
}
/* MARK Done */
.sucess{ /* Change BG*/
  background-color: #7ed6df;
  color: rgb(255, 255, 255);
}
.btnSucess{
  background-color: #4834d4;
  color: white;
}
.line{
  text-decoration: line-through;
  text-decoration-color: rgb(164, 176, 190);
}
</style>

Toggle button

បន្ទាប់ពីយើង custome style រួចហើយយើងមកធ្វើ Action ជាមួយ JavaScript

<script setup>
 //MARK: Import
 import Card from '@/components/Card.vue';
 import { ref } from 'vue';
 import { v4 as uuidv4 } from 'uuid';

 //MARK: To Do
 const todos = ref([
    {
        id: 'id1',
        article: 'Cooking Rice',
        done: false
    },
    {
        id: 'id2',
        article: 'Read book',
        done: true
    }
])
//MARK: Mark Done
const toggleBtn = id =>{
    const index = todos.value.findIndex(todo =>todo.id == id)
    todos.value[index].done = !todos.value[index].done
}
</script>

<button
        @click="toggleBtn(todo.id)"
        :class="todo.done? 'btnSucess': 'btn-check' " 
        class=" ">✓</button>

All code

Card.vue

<template>
    <div class="card">
        <div class="txt">{{ content }}</div>
        <slot></slot>
    </div>
</template>

<script setup>
    name: 'Card'
   const props = defineProps({
    content: {
        type: String
    }
   })
</script>

<style>
.card{
    width: 100%;
    background-color: #ecf0f1;
    color: black;
    border-radius: 8px;
    display: flex;
    margin: 5px;
}
.card .txt,.btn-box{
    display: flex;
    padding: 10px;
    font-size: 18px;
    align-items: center;
}
.card .btn-box{
   margin-left: auto;
}
.card .btn-box button{
    font-size: 18px;
    margin-left: 5px;
    cursor: pointer;
    padding: 5px;
    border-radius: 5px;
    border: 0px;
    padding-left: 20px;
    padding-right: 20px;
}
.card .btn-box .btn-check{
    background-color: #c3c3c3;
    color: white;
}
.card .btn-box .btn-cross{
    background-color: #eb3b5a;
    color: white;
}
</style>

App.vue

<template>
    <div class="contain">
        <form class="form-input" @submit.prevent="addTodo">
            <input 
            v-model="newArticleTodo"
            type="text" placeholder="Add todo">
            <button 
            :disabled="!newArticleTodo"
            class="btn-gb">Add</button>
        </form>

        <!--MARK: Custom Card-->
        <card 
            v-for="todo in todos"
            :class="{sucess: todo.done}"
        >
            <div 
                :class="{line: todo.done}"
                class="txt">{{ todo.article }}</div>
            <div class="btn-box">
                <button
                    @click="toggleBtn(todo.id)"
                    :class="todo.done? 'btnSucess': 'btn-check' " 
                    class=" ">✓</button>
                <button
                @click="deleteTodo(todo.id)" 
                class="btn-cross">✗</button>
            </div>
        </card>
    </div>
</template>

<script setup>
 //MARK: Import
 import Card from '@/components/Card.vue';
 import { ref } from 'vue';
 import { v4 as uuidv4 } from 'uuid';

 //MARK: To Do
 const todos = ref([
    {
        id: 'id1',
        article: 'Cooking Rice',
        done: false
    },
    {
        id: 'id2',
        article: 'Read book',
        done: true
    }
])
//MARK: Add To Do
const newArticleTodo = ref()
const addTodo = ()=>{
    const newTodo ={
        id: uuidv4(),
        article: newArticleTodo.value,
        done: false
    }
    todos.value.unshift(newTodo)
    newArticleTodo.value = ''
}
//MARK: Delete To Do
const deleteTodo = id =>{
    todos.value = todos.value.filter(todo => todo.id !== id)
}
//MARK: Mark Done
const toggleBtn = id =>{
    const index = todos.value.findIndex(todo =>todo.id == id)
    todos.value[index].done = !todos.value[index].done
}
</script>



<style>
body{
  background-color: rgba(0, 0, 0, 0.69);
}
.contain{
  width: 500px;
  margin: 0 auto;
}
.form-input{
  padding: 8px;
}
.form-input input{
  padding: 10px;
  border-radius: 8px;
  width: 79%;
  margin-right: 10px;
  border: 1px solid;
  font-size: 18px;
}
.form-input button{
  /* padding: 10px; */
  font-size: 16px;
  padding: 10px 20px 10px 20px;
  border: 0px;
  background-color: #4b7bec;
  color: white;
  border-radius: 8px;
  cursor: pointer;
}
.btn-gb{
  background-color: red;
}
.btnSucess{
  background-color: #4834d4;
  color: white;
}
/* MARK Done */
.sucess{ /* Change BG*/
  background-color: #7ed6df;
  color: rgb(255, 255, 255);
}
.btnSucess{
  background-color: #4834d4;
  color: white;
}
.line{
  text-decoration: line-through;
  text-decoration-color: rgb(164, 176, 190);
}
</style>

មេរៀនបន្ទាប Vue to do ជាមួយ google firebase

Github

Post a Comment

0 Comments