<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      vue3+vite+pinia+cass最新版本編寫流程,無報紅

      Vue Router,pinia插件安裝和使用

      npm install vue-router@4 pinia

      新增src/router/index.ts

      // 引入Vue Router的核心方法與類型
      import { createRouter, createWebHistory } from 'vue-router'
      import type { RouteRecordRaw } from 'vue-router'
      
      
      // 定義所有路由規則,便于權限控制、自動化管理
      const routes: RouteRecordRaw[] = [
        {
          path: '/',                // 首頁路由
          name: 'Home',
          component: () => import('@/views/Home.vue'), // 懶加載,提升首屏性能
        },
        {
          path: '/about',           // 關于頁路由
          name: 'About',
          component: () => import('@/views/About.vue'),
        },
      ]
      
      // 創建并導出router實例,統一在main.ts注冊
      export const router = createRouter({
        history: createWebHistory(), // 使用HTML5 history模式,支持SEO與回退
        routes,
      })
      
      

      新增src/store/index.ts (mkdir -p src/store && touch src/store/index.ts)

      // 引入并創建Pinia實例,便于主入口集成
      import { createPinia } from 'pinia'
      
      // 導出Pinia實例
      export const pinia = createPinia()
      
      

      新增src/store/useUserStore.ts (mkdir -p src/store && touch src/store/useUserStore.ts)

      // src/store/useUserStore.ts
      import { defineStore } from 'pinia'
      import http from '@/utils/http'
      import type { UserInfo } from '@/types/user'
      
      export const useUserStore = defineStore('user', {
        state: () => ({
          name: '未登錄用戶' as string,
          isLoggedIn: false as boolean,
        }),
        actions: {
          async login(name: string) {
            // 演示寫死,實際可以用 http.post 登錄
            this.name = name
            this.isLoggedIn = true
          },
          logout() {
            this.name = '未登錄用戶'
            this.isLoggedIn = false
          },
          async fetchUser() {
            // 泛型聲明:確保 data 是 UserInfo 類型
            const data = await http.get<UserInfo>('/user/info')
            this.name = data.name
            this.isLoggedIn = data.isLoggedIn
          }
        }
      })
      
      

      新增 src/views/AppHome.vue (mkdir -p src/views && touch src/views/AppHome.vue)

      <template>
        <div class="home-box">
          <h1>首頁</h1>
          <p>歡迎:{{ user.name }}</p>
          <button v-if="!user.isLoggedIn" @click="user.login('張三')">登錄</button>
          <button v-else @click="user.logout()">登出</button>
          <button @click="refreshUser">刷新用戶信息</button>
          <router-link to="/about">關于我們</router-link>
        </div>
      </template>
      
      <script setup lang="ts">
      import { useUserStore } from '@/store/useUserStore'
      const user = useUserStore()
      const refreshUser = () => user.fetchUser()
      </script>
      
      <style lang="scss" scoped>
      @use 'sass:color';
      // 無需再次 import,$primary-color 已注入
      .home-box {
        padding: 20px;
        background: color.adjust($primary-color, $lightness: 40%);
        color: $primary-color;
        border: 1px solid $primary-color;
        border-radius: 8px;
      }
      </style>
      
      

      新增tsconfig.app.json

      {
        "compilerOptions": {
          "baseUrl": ".",
          "paths": {
            "@/*": ["src/*"]
          }
        }
      }
      
      

      新增src/views/AppAbout.vue (touch src/views/AppAbout.vue)

      <template>
        <div class="about-box">
          <h1>關于我們</h1>
          <p>本網站是由 Vue 3 + Vite + TypeScript 構建的現代前端項目。</p>
          <router-link class="link" to="/">返回首頁</router-link>
        </div>
      </template>
      
      <script setup lang="ts">
      // 此頁面目前不需要邏輯,留空 script 即可
      </script>
      
      <style lang="scss" scoped>
      @use 'sass:color';
      // 變量 $primary-color 已自動全局注入,無需重復 @use
      
      .about-box {
        padding: 24px;
        max-width: 600px;
        margin: 0 auto;
        border: 1px solid $primary-color;
        border-radius: 8px;
        color: $primary-color;
        background: color.adjust($primary-color, $lightness: 42%);
        // 或 color.scale($primary-color, $lightness: 42%);
      }
      
      .link {
        display: inline-block;
        margin-top: 16px;
        color: color.adjust($primary-color, $lightness: -10%);
        // 或 color.scale($primary-color, $lightness: -10%);
        font-weight: bold;
        text-decoration: none;
      
        &:hover {
          text-decoration: underline;
        }
      }
      </style>
      
      

      新增vite.config.ts

      import path from 'path'  // ← 這一行很重要!
      
      export default defineConfig({
        plugins: [vue()],
        resolve: {
          alias: {
            '@': path.resolve(__dirname, 'src'),  // 確保 __dirname 和 'src' 用對
          },
        },
      })
      

      修改App.vue

      <template>
        <router-view />
      </template>
      

      sass,axios插件的安裝和使用,環境變量配置,跨域

      安裝

      npm install -D sass          # 只需安裝 sass,Vite 已自動支持 .scss/.sass
      npm install axios
      
      

      新建src/styles/_variables.scss (touch src/styles/_variables.scss)

      $primary-color: #42b983;
      $font-size-base: 16px;
      
      

      src/styles/global.scss (touch src/styles/global.scss )

      @use './variables' as *;
      
      body {
        font-size: $font-size-base;
        color: $primary-color;
        font-family: 'Roboto', Arial, sans-serif;
        margin: 0;
      }
      
      

      main.ts新增

      import './styles/global.scss'
      
      

      vite.config.ts新增

        css: {
          preprocessorOptions: {
            scss: {
            additionalData: `@use "@/styles/variables.scss" as *;`
            }
          }
        },
      

      新建src/utils/http.ts (touch src/utils/http.ts),處理不當會報錯("Property 'isLoggedIn' does not exist on type 'AxiosResponse<UserInfo, any>'.ts(2339)")

      import axios  from 'axios'
      import type { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
      
      const http = axios.create({
        baseURL: import.meta.env.VITE_API_BASE_URL,
        timeout: 10000,
        headers: { 'Content-Type': 'application/json' }
      })
      
      http.interceptors.request.use(
        config => config,
        error => Promise.reject(error)
      )
      
      http.interceptors.response.use(
        (response: AxiosResponse) => {
          if (response.data && typeof response.data === 'object' && 'data' in response.data) {
            return response.data.data
          }
          return response.data
        },
        (error: AxiosError) => Promise.reject(error)
      )
      
      // 重點是這一行的泛型
      const get = <T>(url: string, config?: AxiosRequestConfig): Promise<T> => {
        return http.get<unknown, T>(url, config)
      }
      
      const post = <T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> => {
        return http.post<unknown, T>(url, data, config)
      }
      
      export default { get, post }
      
      

      新建.env .env.production (touch .env && touch .env.production )

      VITE_API_BASE_URL=https://dev-api.example.com
      VITE_APP_TITLE=My Vite App
      
      
      VITE_API_BASE_URL=https://prod-api.example.com
      VITE_APP_TITLE=My Vite App [PROD]
      
      

      修改vite.config.ts,新增

        server: {
          proxy: {
            // 只要是 /api 開頭的請求,代理到后端
            '/api': {
              target: 'https://dev-api.example.com',   // 后端接口地址
              changeOrigin: true,
              rewrite: path => path.replace(/^\/api/, ''),
            }
          }
        },
      

      新建src/types/user.ts (mkdir -p src/types && touch src/types/user.ts )

      // src/types/user.ts
      export interface UserInfo {
        name: string
        isLoggedIn: boolean
      }
      
      

      總結:
      數據流寫法,先寫http自定義請求,再寫pinia連接口拿數據,之后寫view層代碼,寫router層,(注冊插件,代碼結構,一般是會提前搞好)

      posted @ 2025-05-18 04:44  $Traitor$  閱讀(62)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲偷自拍国综合| 精品人妻系列无码天堂| 国产成人8X人网站视频| 亚洲中文久久久精品无码| 亚洲国产一区二区三区| 都市激情 在线 亚洲 国产| 日韩中文字幕亚洲精品| 亚洲色www永久网站| 国产91小视频在线观看| 久久精品国产亚洲夜色av| 欧美做受视频播放| 强奷漂亮人妻系列老师| 亚洲中文字幕精品一区二区三区| 国产福利社区一区二区| 国产午夜福利免费入口| 久久国产精品不只是精品| 日韩人妻无码一区二区三区| 色猫咪av在线网址| 综合区一区二区三区狠狠| 久久99日韩国产精品久久99| 99在线精品视频观看免费| 国产午夜福利精品视频| 国产激情免费视频在线观看| 99精品国产兔费观看久久99| 不卡免费一区二区日韩av| 精品精品亚洲高清a毛片| 亚洲区一区二区三区精品| 国产成人精品手机在线观看| 亚洲日本韩国欧美云霸高清| 天堂8中文在线最新版在线| 久久涩综合一区二区三区| 好吊妞| 日日噜噜夜夜狠狠视频| 午夜成人理论无码电影在线播放 | 色综合久久综合中文综合网| 2021亚洲国产精品无码| 99RE8这里有精品热视频| 欧美人与动牲猛交A欧美精品| 亚洲aⅴ无码专区在线观看春色| 正在播放肥臀熟妇在线视频| 97香蕉碰碰人妻国产欧美|