【 Vue3 + Vite + setup语法糖 + Pinia + VueRouter + Element Plus 第二篇】(持续更新中)

本文介绍了如何在Vue3项目中使用Axios进行API请求配置,包括环境变量的设置和封装Axios请求,同时讲解了ElementPlus的使用,以及如何通过封装组件和环境变量来从本地JSON文件获取数据,为后续的组件交互和数据传递打下基础。

在第一篇中我们讲述了Vue3框架的搭建以及Vue3的常用语法,这篇文章将使用 AxiosElement Plus 并使用封装组件的方式完成表格搭建。

本期需要掌握的知识如下:

  • 目录路径别名@
  • 引入并封装 Axios 请求
  • 配置 .env 文件
  • 通过 api 接口获取数据

下期需要掌握的知识如下:

  • 组件的封装引入
  • 子组件通过 emit 改变父组件的值
  • 父组件 通过 defineExpose 改变子组件的值

因本地项目不需要后端介入,故所有的api都将请求项目根目录JSON文件

1. @替代 /src路径别名

vite.config.js

import { defineConfig } from 'vite'
import { resolve } from "path" // 引入 resolve 方法
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  // 添加 resolve 对象
  resolve: {
    alias: {
      // 在此设置路径别名
      "@": resolve(__dirname, "./src")
    }
  },
  server:{
		host:'0.0.0.0'
	}
})

2. axios 使用 && .env 配置文件

安装命令:npm install axios vue-axios

安装完成后在main.js 中引入 axios

import axios from 'axios'
import VueAxios from 'vue-axios'

createApp(App)use(ElementPlus, { locale: zhCn }).use(VueAxios, axios).mount('#app')

配置 .env文件

在这里插入图片描述

我们在项目根目录下新建 .env.env.prod文件
分别对应 本地环境 生产环境

// 这里是环境配置
VITE_NODE_ENV = "dev"  
// 这里是设置的请求的基础路径 也就是 baseURL
VITE_NODE_BESE_API = '/'
VITE_NODE_ENV = "prod"
VITE_NODE_BESE_API = 'https://blog.youkuaiyun.com/Web_chicken'

使用 Vite构建的Vue3项目,必须以 VITE_NODE 开头,否则不生效,或者请参考其他文章以暴露其他字符开头的环境变量

打包命令配置

//package.json
"scripts": {
    // 不设置mode的话 默认就是使用 .env 文件配置
    "dev": "vite --host",
    "build": "vite build",
    // 如需使用其他配置文件 在后边加上 --mode xxx 即可
    "build:prod": "vite build --mode prod",
    "preview": "vite preview"
  },

页面使用env环境变量

const env = import.meta.env

二次封装 axios

src目录下新建 utils文件夹,并在该文件夹下新建 request.js,用来封装 axios 请求

在这里插入图片描述

import axios from 'axios'; // 引入axios
import { showNprogress, hideNprogress } from '@/mixin' // 封装的 NProgress顶部进度条方法,可忽略
const baseURL = import.meta.env.VITE_NODE_BESE_API // 根据 env 配置文件获取 baseURL , 如果暂时不了解的话可以先设置
const baseURL = '/'

// 创建 axios 请求
const service = axios.create({
  baseURL
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    showNprogress() // 进度条开始
    return config // return config
  },
  err => {
    hideNprogress() // 进度条关闭
    return Promise.reject(err)  // 进入 err return err
  }
)

// 相应拦截器
service.interceptors.response.use(
  res => {
    showNprogress()
    // res.status === 200 说明请求成功 反之失败
    if (res.status === 200) {
      hideNprogress()
      return res.data
    } else {
      hideNprogress()
      return Promise.reject(res.data)
    }
  },
  err => {
    console.log(err)
    hideNprogress()
    return Promise.reject(err)
  }
);
// 导出 service
export default service;
创建table.json接口,获取数据

在这里插入图片描述
public 目录为项目根目录,可通过 /table.json访问该文件

{
  "data": [
    {
      "id": 1,
      "date": "2016-05-03",
      "name": "admin",
      "address": "No. 189, Grove St, Los Angeles"
    },
    {
      "id": 2,
      "date": "2016-05-02",
      "name": "Tom",
      "address": "No. 189, Grove St, Los Angeles"
    },
    {
      "id": 3,
      "date": "2016-05-04",
      "name": "Tom",
      "address": "No. 189, Grove St, Los Angeles"
    },
    {
      "id": 4,
      "date": "2016-05-01",
      "name": "Tom",
      "address": "No. 189, Grove St, Los Angeles"
    }
  ]
}

api封装及使用

src目录下新建 api文件夹,并在该文件夹下新建 index.js,用来封装 api 请求

// 引入 axios 
import request from '@/utils/request'
// 封装获取列表数据的方法并导出
export const getTableList = () => {
  return request({
  	// 请求地址
    url: 'table.json',
    // 请求方式
    method: 'GET'
  })
}
使用api方法获取数据
<el-table :data="tableData" style="width: 100%" border stripe>
  <el-table-column v-for="{id,prop,label} in tableColumn" :prop="prop" :key="id" :label="label" :width="label=='序号' ? 100 :''" align="center" />
  <el-table-column fixed="right" label="操作" align="center" width="240">
    <template #default="scope">
      <el-button link type="primary" size="small" @click="handlEmodify(scope.row)">编辑</el-button>
      <el-button link type="primary" size="small" @click="handleDel(scope.row)">删除</el-button>
      <el-button link type="primary" size="small" @click="handlDetail(scope.row)">查看</el-button>
      <el-button v-if="scope.row.name==='admin'" link type="primary" size="small" @click="handleAdmin(scope.row)">管理系统</el-button>
    </template>
  </el-table-column>
</el-table>
// 别忘了在script标签加上 setup
import { ref, onMounted } from 'vue' // 导入 ref 生命周期函数
import { ElMessage } from 'element-plus' // 导入 Element Plus 消息提示
import { getTableList } from '@/api/home.js' // 导入接口 api

/**
 * @type data
 * @description 所有数据都在此体现
 * **/

const tableData = ref([]) // 在此定义 tableData ,并使用 ref 使其具备响应式

// 用来循环列表字段的,如字段固定可不结构为响应式
const tableColumn = ref([
  { id: 1, prop: 'id', label: '序号' },
  { id: 2, prop: 'date', label: '时间' },
  { id: 3, prop: 'name', label: '姓名' },
  { id: 4, prop: 'address', label: '地址' }
])

/**
 * @type 生命周期
 * @description 所有生命周期函数都在此体现
 * **/

onMounted(() => {
  // 在生命周期函数中调用初始化表格方法
  initTable()
})


/**
* @type methods
* @description 所有方法、事件都在此层中体现
* **/

// 初始化表格
const initTable = async () => {
  // 调用 api 方法,获取数据 并赋值给 tableData
  let res = await getTableList()
  ElMessage.success('获取成功')
  // 注意 使用 ref结构的数据 在 js中必须使用.value来设置或获取它的值
  if (res.data) return tableData.value = res.data
}
### 项目布局实现 以下是基于 ViteVue3PiniaVue-Router@4、TypeScript 和 `setup` 语法构建项目的具体方法: #### 1. 初始化项目并安装依赖 通过 Vite 创建一个新的 Vue3 项目,并指定 TypeScript 支持: ```bash npm create vite@latest my-project --template vue-ts cd my-project ``` 随后,安装必要的依赖项,包括 Vue Router v4 和 Pinia: ```bash npm install vue-router@4 pinia element-plus axios ``` #### 2. 配置 Element Plus 的按需加载 为了优化打包体积,推荐使用插件来实现 Element Plus 的按需导入。可以安装 `unplugin-vue-components` 和 `unplugin-auto-import` 插件: ```bash npm install unplugin-vue-components unplugin-auto-import -D ``` 在 `vite.config.ts` 中配置这些插件: ```typescript import { defineConfig } from &#39;vite&#39; import vue from &#39;@vitejs/plugin-vue&#39; import AutoImport from &#39;unplugin-auto-import/vite&#39; import Components from &#39;unplugin-vue-components/vite&#39; import { ElementPlusResolver } from &#39;unplugin-vue-components/resolvers&#39; export default defineConfig({ plugins: [ vue(), AutoImport({ resolvers: [ElementPlusResolver()], }), Components({ resolvers: [ElementPlusResolver()], }), ], }) ``` 这一步实现了 Element Plus 组件和 API 的自动导入[^1]。 #### 3. 设置路由管理器 创建 `src/router/index.ts` 文件以定义路由逻辑: ```typescript import { createRouter, createWebHistory } from &#39;vue-router&#39;; import routes from &#39;./routes&#39;; const router = createRouter({ history: createWebHistory(), routes, }); // 路由守卫:验证用户身份 router.beforeEach((to, from, next) => { const token = localStorage.getItem(&#39;token&#39;); const isAuthenticated = !!token; if (to.name === &#39;login&#39;) { localStorage.clear(); } if (to.name !== &#39;login&#39; && !isAuthenticated) { next({ name: &#39;login&#39; }); } else { next(); } }); export default router; ``` 同时,在同一目录下创建 `routes.ts` 定义具体的路由映射表: ```typescript import { RouteRecordRaw } from &#39;vue-router&#39;; const routes: Array<RouteRecordRaw> = [ { path: &#39;/&#39;, component: () => import(&#39;@/views/Home.vue&#39;), name: &#39;home&#39; }, { path: &#39;/login&#39;, component: () => import(&#39;@/views/Login.vue&#39;), name: &#39;login&#39; }, ]; export default routes; ``` #### 4. 整合状态管理工具 Pinia 初始化 Pinia 并将其挂载至应用实例中。编辑 `src/main.ts` 文件如下: ```typescript import { createApp } from &#39;vue&#39;; import App from &#39;./App.vue&#39;; import router from &#39;./router&#39;; import pinia from &#39;./stores&#39;; // 引入 Pinia 实例 import &#39;element-plus/dist/index.css&#39;; const app = createApp(App); app.use(pinia); app.use(router); app.mount(&#39;#app&#39;); ``` 接着,在 `src/stores/` 下创建存储模块文件(如 `userStore.ts`),用于管理全局状态: ```typescript import { defineStore } from &#39;pinia&#39;; export const useUserStore = defineStore(&#39;user&#39;, { state: () => ({ username: &#39;&#39;, isLoggedIn: false, }), actions: { login(username: string) { this.username = username; this.isLoggedIn = true; }, logout() { this.username = &#39;&#39;; this.isLoggedIn = false; }, }, }); ``` #### 5. 构建基础布局结构 修改 `src/App.vue` 来支持动态视图渲染以及顶部导航栏等功能: ```html <template> <div id="app"> <!-- 导航 --> <nav-bar /> <!-- 动态内容区域 --> <router-view></router-view> <!-- 底部版权信息 --> <footer-component /> </div> </template> <script setup lang="ts"> import NavBar from &#39;@/components/NavBar.vue&#39;; import FooterComponent from &#39;@/components/Footer.vue&#39;; </script> ``` #### 6. 在组件中使用路由与状态管理功能 假设有一个按钮点击事件触发跳转或者更新状态的操作,可以在任何组件内部这样写: ```typescript <script setup lang="ts"> import { useRouter, useRoute } from &#39;vue-router&#39;; import { useUserStore } from &#39;@/stores/userStore&#39;; const userStore = useUserStore(); const router = useRouter(); function handleLoginClick() { userStore.login(&#39;John Doe&#39;); // 更新 Pinia 状态 router.push(&#39;/dashboard&#39;); // 执行页面跳转 } </script> ``` 以上即完成了整个基于 ViteVue3PiniaVue-Router@4、TypeScript 及 Setup 语法的项目布局设计[^2]。 ---
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端大斗师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值