跳到主要內容

初探 Vue 與 Spring boot 的對話之Frontend (Vue-Frontend)

 Front-end Vue 使用 REST API


建立 Vite 專案

可參考 {Vue 3 初探} 文章


danny@Danny-Yu projects % npm create vite@latest

Need to install the following packages:

create-vite@8.2.0

Ok to proceed? (y) y



> npx

> "create-vite"


  Project name:

  vue-frontend

  Select a framework:

  Vue

  Select a variant:

  TypeScript

  Use rolldown-vite (Experimental)?:

  No

  Install with npm and start now?

  Yes

  Scaffolding project in /Users/danny/Desktop/projects/vue-frontend...

  Installing dependencies with npm...


added 47 packages, and audited 48 packages in 27s


6 packages are looking for funding

  run `npm fund` for details


found 0 vulnerabilities

  Starting dev server...


> vue-frontend@0.0.0 dev

> vite



  VITE v7.2.4  ready in 411 ms


    Local:   http://localhost:5173/

    Network: use --host to expose

    press h + enter to show help


切換到路徑vue-frontend

手動命令 啟動 Vue App


註1. 如果想修改啟動 Port 號,可以在 package.json 加上 --port 8080

    例如:

    "scripts": {

    "dev": "vite --port 8080",

    "build": "vue-tsc -b && vite build",

    "preview": "vite preview"

    },


    重新啟動 Vue App,可以發現埠號改為 8080



直接在瀏覽器中輸入 http://localhost:8080 ,來測試 VUE App 是否能執行正常






開始撰寫相關代碼


註2. vite-plugin-vue-devtools 是一個開源的 Vite 插件,旨在提升 Vue 開發者體驗。

    它功能強大且用途廣泛,能夠顯著提高您在使用 Vue 應用時的效率和調試能力。


    npm install vite-plugin-vue-devtools


新增 Axios 依賴項並將其儲存到 package.json 檔案中

Axios 基於promise可以用於瀏覽器和node.js的REST API Call 

指令 npm install axios —save




建立 Vue REST API 呼叫服務類別

讓我們在 src 資料夾內建立一個名為 services 的資料夾。在 services 資料夾中,建立一個名為 UserService.ts 的Class,並編寫以下程式碼,以便透過 Axios 發起 HTTP REST 呼叫。


建立 UserServce.ts 檔


import axios from 'axios'; //引入 Axios 庫


class UserService{

    getUsers(){

return axios.get(import.meta.env.VITE_API_URL + ':' + import.meta.env.VITE_PORT + '/api/users'); //發送 GET 請求以獲取用戶列表

    }

}


export default new UserService();



讓我們在 components 資料夾中,建立一個名為 Users.vue 的顯示User元件,並編寫以下程式碼,以便顯示User清單資料。


建立 Users.vue 檔


<script setup lang="ts">

    import { ref } from 'vue';

    import UserServce from '../services/UserServce'


    const users = ref(null);


    UserServce.getUsers().then((response) => {

        console.log(response.data);

        users.value = response.data;

    });


</script>


<template>

    <div>

        <h1 class="text-center"> Users List</h1>

    </div>

    <table class="card-body">

        <thead>

            <tr>

                <th> User Id</th>

                <th> User First Name</th>

                <th> User Last</th>

                <th> User Email</th>

            </tr>

        </thead>

        <tbody>

            <tr class="mb-0" v-for="user in users" :key="user.id">

                <td> {{ user.id }}</td>

                <td> {{ user.firstName }}</td>

                <td> {{ user.lastName }}</td>

                <td> {{ user.email }}</td>

            </tr>

        </tbody>

    </table>

    <div class="card-body">

        <div v-if="!users" class="text-center">

            <div class="spinner-border spinner-border-sm"></div>

        </div>

    </div>

</template>


<style>

    table {

        font-family: Arial, Helvetica, sans-serif;

        border-collapse: collapse;

        width: 100%;

    }


    td,

    th {

        border: 1px solid #ddd;

        padding: 8px;

    }


    tr:nth-child(even) {

        background-color: #f2f2f2;

    }


    tr:hover {

        background-color: #ddd;

    }


    th {

        padding-top: 12px;

        padding-bottom: 12px;

        text-align: left;

        background-color: #04AA6D;

        color: white;

    }

</style>



修改 App.vue


<script setup lang="ts">

import HelloWorld from './components/HelloWorld.vue'

import Users from './components/Users.vue'


</script>


<template>

  <!-- 引入component Users -->

  <Users/>

</template>


<style scoped>

.logo {

  height: 6em;

  padding: 1.5em;

  will-change: filter;

  transition: filter 300ms;

}

.logo:hover {

  filter: drop-shadow(0 0 2em #646cffaa);

}

.logo.vue:hover {

  filter: drop-shadow(0 0 2em #42b883aa);

}

</style>




修改 vite.config.ts 檔


import { defineConfig, loadEnv } from 'vite'

import vue from '@vitejs/plugin-vue'

import vueDevTools from 'vite-plugin-vue-devtools'


// https://vite.dev/config/

export default defineConfig(({ mode }) => {


  return {

    plugins: [vue(), vueDevTools()],

  }

})



新增 .env 檔


VITE_API_URL=http://localhost  

VITE_PORT=8088


最後,相關檔案目錄 (.env 設定檔 .env.development/env.production)




最後,在瀏覽器中輸入 http://localhost:8080 ,來測試 VUE App 呼叫 API 取得user 清單





留言

這個網誌中的熱門文章

初探 Vue 呼叫 API 出現 CORS 跨來源資源共享 問題原因

提要:   在 {初探Vue 與 Spring boot 的對話} 專案 ,前端 Vue 應用程式 串接 後端 API 伺服器 ,axios 呼叫 API 時出現以下,”無法取得回應內容 (No 'Access-Control-Allow-Origin' header is present on the requested resource):” 錯誤訊息,根據查找相關資料 ,出現以下原因。 瀏覽器開發工具 錯誤訊息 畫面 錯誤原因: “ Access to XMLHttpRequest at ” from origin ‘http://localhost:8080’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource” 瀏覽器為了安全考量,實施了同源政策。 當您的前端應用程式 (http://localhost:8080) 嘗試呼叫一個不同來源 (不同協議、不同域名或不同埠號) 的 API 伺服器 (http://localhost:8088) 時,瀏覽器會主動阻止這個請求,除非伺服器明確地允許這個跨來源的存取。 同源政策限制(Same-Origin Policy): 同源政策限制了程式碼和不同網域資源間的互動,同源是指兩份網頁具備相同協定、埠號(如果有指定)以及主機位置 範例: 表列哪些 URL 與 URL http://www.example.com/api/p1 屬於同源: URL                                                   | 結果   | 原因 --------------------------------------------------------------------- http://www.example.com/api/p2     |...

初探 Spring 中的循環依賴

原因: 當兩個或多個 bean 直接或間接地相互依賴時, 就會出現 Circular Dependency (循環依賴) 如: Bean A -> Bean B -> Bean A import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class BeanA {          @Autowired     private BeanB beanB;     public String sayHi() {         return "Hi! 我是 Class A.";     } } import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class BeanB {          @Autowired     private BeanA beanA;     public String sayHi() {         return "Hi! 我是 Class B.";     } } 編譯時不會出現問題 danny@Danny-Yu demo % mvn clean install -Dmaven.test.skip=true                           ... ... [INFO] Installing /Users/danny/Desktop/projects/demo/target/dem...