1. 程式人生 > 程式設計 >教程:Laravel + Vuejs + Tailwind CSS 構建一個 Todo App 第一部分

教程:Laravel + Vuejs + Tailwind CSS 構建一個 Todo App 第一部分

文章轉發自專業的Laravel開發者社群,原始連結:learnku.com/laravel/t/3…

今天,我們通過 Vue.js,Laravel 以及 Tailwind 構建一個簡單的 todo 應用。為了節約時間,我們不提供任何的資料互動。但是不要擔心,接下來的第二部分將會更加的精彩。

開發準備

首先,我們通過 Laravel CLI 在需要新增專案的目錄中執行 laravel new <自定義工程名> 來構建一個專案。Laravel CLI 可以幫我們完成我們所需的 Laravel 和 Vue 的安裝。

對於這樣簡單的專案來說,我們直接使用預設的welcome.blade.php

檔案。我們必須要配置這個模板,以便 Vue 可以掛載到專案並正常工作。首先,將下面的 meta 標籤新增到 head 標籤內的其他meta標籤下方即可。

<meta name="csrf-token" content="{{ csrf_token() }}">

複製程式碼

現在,我們可以刪除預設的樣式表以及匯入的字型,然後來操作 body。在body標籤內,我們可以看到一堆生成的程式碼。接下來,我們將其替換為如下內容:

<div id="app">
    <example-component></example-component>
</div>

<!-- Scripts -->
<script src="{{ asset('js/app.js') }}"
></script> 複製程式碼

執行專案,通過螢幕我們可以看到專案已正常執行。

如你所見,示例元件已正確渲染,可以小小的得意一下。您自己在編寫過程中如有任何錯誤,可隨時檢視專案的GitHub repo ,按照我的提交來檢查。

現在我們開始準備 Tailwind,我假設你已經查看了我較早的一篇文章earlier article 並完成了裡面的工作,該專案解釋瞭如何在 Laravel 工程中配置 Tailwind。完成上面所述工作後,讓我們在welcome.blade.php中再增加一行程式碼,以便我們可以使用 Tailwind 樣式。在head標籤內的title標籤下,新增匯入這段程式碼:<link href="{{ asset('css/app.css') }}" rel="stylesheet">

最後,我們開始準備開發!

Vue.js 元件

讓我們拆開腳手架並通過新增自己的元件來進行 Vue 開發。 在 resources/assets/js/components 目錄下, 我們刪除  ExampleComponent.vue, 並且新增命名為 todo.vue 的檔案。 現在,在 resources/assets/js/app.js 內部, 我們可以更新元件用來引入我們的 todo 元件,就像下面這樣:

Vue.component('todo-component',require('./components/todo.vue'));

複製程式碼

在 welcome.blade.php 檔案中,我們可以像下面這樣將 Vue 元件換成我們的 todo 元件。

<todo-component></todo-component>

複製程式碼

要在瀏覽器看到它,我們需要執行 Laravel Mix。如果你一直按照我的方法,那麼我建議使用npm run watch,那麼編寫的程式碼將會自動編譯。在我們的模板檔案中,我們可以新增如下所示程式碼:

<template>
    <div>
        <div>
            <h1>Todo List</h1>
            <div>
                <input v-model="newTodo" placeholder="Add Todo">
                <button @click="add" :disabled="newTodo.length === 0">Add</button>
            </div>
        </div>
        <div>
            <div v-for="(todo,index) in todos" :key="todo.id">
                <p>{{todo.text}}</p>
                <button @click="updateStatus(todo)" v-text="todo.finished ? 'Not Done' : 'Done'"></button>
                <button @click="remove(index)">Remove</button>
            </div>
        </div>
    </div>
</template>

複製程式碼

如你所見,這是一個非常簡單的 Vue 元件。像所有的 Vue 元件一樣,我們擁有一個 div 包裝器,以及兩個子 div。在第一個 div 區塊裡面我們有標題,以及新的 todo input。我們已經 input 繫結到名為 newTodov-model,並且我們在button中添加了一個名為add的方法,用來提交新的 todo。當input沒有輸入文字時,該按鈕將處於禁用狀態,這樣保證我們不會提交空的 todo。

在底部的div中,我們將遍歷已新增的每個 todo,並顯示text資料和兩個按鈕。第一個按鈕可以讓我們將 todo 標記為已完成或未完成,第二個按鈕可以將 todo 完全刪除。是不是感覺 So Easy?

接著往下看,這是我們編寫的 Vue 元件的其餘部分。

<script>
    export default{
        data(){
            return{
                todos: [],newTodo: '',baseId: 1,}
        },methods: {
            add() {
              const t = this;

              let todo = {
                id: t.baseId,text: t.newTodo,finished: false,}

              t.todos.push(todo);

              t.newTodo = '';
              t.baseId++;
            },updateStatus(todo) {
              todo.finished = !todo.finished;
            },remove(index) {
              const t = this;

              t.todos.splice(index,1);
            }
        }
    }
</script>

複製程式碼

這裡我們可以管理 todo 資料,而且我們可以看到上面模板繫結的三個方法。在資料中,我們有一個 todos 陣列,可以在其中儲存 todo;我們有繫結到input上的 newTodo,最後,baseId是用來給每個 todo 一個假的『unique』id,以便 Vue 在v-for 遍歷時跟蹤它們。

在 methods 裡,我們有add()方法,它可以使用 data 中 newTodo 以及 baseId 來建立一個新的 todo 例項,並將其推入到我們的 todo 陣列,然後將 input 狀態重置為空的遞增 baseId。然後我們來看updateStatus()方法,它可以更新 todo 的完成狀態。最後我們再看看remove()方法,它會傳入 todo 的 index 作為引數並將其從 todos 陣列中移除。

執行·npm run prod,我們可以在瀏覽器看到 todo 元件的效果。

使用元件時,可以看到 todo 的新增順序不正確。好尷尬啊!在add()方法中,我們使用.unshift()來替換.push()。現在,它基本達到了我們的預期。

元件雖然功能齊備,但是看起來還是不太好看。接下來我們將搭配 Tailwind CSS 使其更加友好。

看起來不錯

現在,我們的應用程式在 Tailwind 中看起來很好。首先,從 welcome.blade.php 檔案開始, 把 todo 元件放置在頁面中間。

在擁有應用 id 的 div上,我們可以新增以下內容。 class="h-screen flex items-center justify-center"。這會將我們的元件放置在頁面的中間。 然後新增一些背景色和字型用來介紹一些基本樣式。 在相同的 div 上新增 .bg-teal-lightest 和 .font-sans 類。 頁面看起來更好了。

現在,我們可以將焦點放在我們的元件樣式上。讓我們從一些基本的元件開始,這樣我們就可以看到我們在處理什麼。在todo.vue檔案中的div包裝器上,我們可以新增.bg-white.rounded.shadow,以及.p-6 class,從而來製作一個漂亮的 card。

有了白色的背景,我們可以在頁面上看到div的顯示位置。因此,讓我們使用以下類為它提供一個更好的寬度:.m-4.w-full.lg:w-3/4,以及.lg:max-w-lg。如你所見,在移動裝置上,我們讓 card 佔據整個螢幕的寬度,一旦達到了我們的最大斷點,我們繼續讓它增長,直到它達到螢幕的 75% 或者最大寬度。

接下來處理 todo 列表本身,對於包裝器div 的 header,我們只需在底部新增一個.mb-4 class,使其與列表項分開。然後在h1上,我們新增一個.text-grey-darkest class,這樣效果看起來就不是那麼緊湊。

現在有趣的部分是我們的新 todo 輸入框。對於它的包裝器 div,我們將通過新增.flex 類使它變樣 ,並通過 .mt-4 給它和 h1 之間保留間距。 在 input 框和  button 按鈕上,我們將新增一大堆這樣的類:

<input class="shadow appearance-none border rounded w-full py-2 px-3 mr-4 text-grey-darker" v-model="newTodo" placeholder="Add Todo">
<button class="flex-no-shrink p-2 border-2 rounded text-teal border-teal hover:text-white hover:bg-teal" @click="add" :disabled="newTodo.length === 0">Add</button>

複製程式碼

這些內容都很簡單,使你困惑的可能是 input 上的  .appearance-none 以及 button 上的 flex-no-shrink , .appearance-none 是一個重置類,用於從給定元素中刪除所有瀏覽器樣式。 而 .flex-no-shrink是一個 flex 助手, 它將  flex-shrink 設定成0用來防止按鈕文字在較小的檢視中自動換行。現在,我們有了一個樣式精美的標題。

在我們設定樣式之前,新的樣式看起來會使我們忽視掉空的狀態,我們應該讓使用者知道他們沒有任何的 todo。

在第二個 div 組,v-for 的下邊,我們可以新增以下內容:

<div v-show="todos.length === 0">
	<p class="w-full text-center text-grey-dark">There are no todos</p>
</div>

複製程式碼

現在,我們的使用者可以看到 todo 在上面了。

最後,我們僅需給我們的todo新增樣式。我們可以忽略外層的div,直接跳到我們的 v-for.再一次,我們將要新增一堆完整的css class.所以,讓我們看看完成後的效果然後再仔細檢查一遍。

<div class="flex mb-4 items-center" v-for="(todo,index) in todos" :key="todo.id">
    <p class="w-full" :class="todo.finished ? 'line-through text-green' : 'text-grey-darkest'">{{todo.text}}</p>
    <button class="flex-no-shrink p-2 ml-4 mr-2 border-2 rounded hover:text-white" :class="todo.finished ? 'text-grey border-grey hover:bg-grey' : 'text-green border-green hover:bg-green'" @click="updateStatus(todo)" v-text="todo.finished ? 'Not Done' : 'Done'"></button>
    <button class="flex-no-shrink p-2 ml-2 border-2 rounded text-red border-red hover:text-white hover:bg-red" @click="remove(index)">Remove</button>
</div>

複製程式碼

都是很簡單的東西,但是我們將要做一到兩處特別的更改。在"v-for"和"div",我們只是需要讓它們變得靈活,跟中間的元素對齊,並且在底部加上一些空白。

"p"標籤可能看起來簡單,但是我們實際上利用了Vue的動態類來轉換我們的css類以達到讓我們的使用者看到他們已經完成了todo的效果.在未完成的狀態下,我們只是用".text-grey-darkset"來給文字上深灰色。但是,在完成的狀態時,我們要用".text-green"和".line-through"來轉換顏色成綠色並且加上一個刪除線。

對於這裡的按鈕,我們利用了之前新增「add」 按鈕的一些類,同時也利用了 Vue 的動態類。接下來,試著自己動手,分析我們到底做了什麼。

現在,我們終於完成了我們的想要的樣式。

總結

嚯!我們在這方面確實做了很多工作,現在才剛剛開始。在本文中,我們建立了Laravel、Vue 和 Tailwind 專案;使用Vue.js 構建了一個 todo 元件,然後用Tailwind 進行樣式化。

對於下一篇文章,我們當然還有很多內容要涉及到。我們必須將 todo 持久化到資料庫,並且應該可能將一些 Tailwind 類抽取到我們自己的樣式表中,這樣更方便管理元件。