如何创建一个vue3+TS+Element+Pinia的项目(保姆级别教程)

一、使用vite创建项目

npm create vite@latest

当出现下面这一段话的时候,是在提示请输入你的项目名称(我这里用的是myProject),然后按2下回车就可以了。
输入项目名称
这里是选择搭建的项目框架,我们选择vue,然后按回车
选择项目框架
这里已经是选择了TypeScript了,我们直接按回车就可以
在这里插入图片描述
当出现这三行消息的时候,就说明我们已经安装好了,然后依次执行这三行消息就可以了!
创建成功

cd myProject
npm install
npm run dev

执行成功后就会出现以下消息,就说明已经运行成功了
在这里插入图片描述
我们直接复制Local后面的去浏览器打开就可以看到运行的结果了
在这里插入图片描述

二、安装css预处理器(sass)

scss是css的一种预处理器,可以大大提高css的维护性和可读性。它是动态样式表语言,可以赋予css动态语言的特性,例如变量,嵌套,继承,Mixin等,可以更加方便的对样式进行模块化开发。

npm install -D sass

使用测试,我们去项目的app.vue文件中使用一下:
这里是原本的代码
原本的css代码
改完后

<style lang="scss" scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
  &:hover {
    filter: drop-shadow(0 0 2em #646cffaa);
  }
  &.vue {
    &:hover {
      filter: drop-shadow(0 0 2em #42b883aa);
    }
  }
}
</style>

改完后,再打开页面没看到有变化就说明sass安装成功了

三、初始化样式 normalize.css

npm i normalize.css

在main.ts中使用

import { createApp } from 'vue';
import App from './App.vue';

import router from './router'; // 导入 router
import 'normalize.css'; // 引入 normalize.css

const app = createApp(App);

app.use(router); // 使用 router

app.mount('#app');

四、配置 src 路径别名

1.vite.config.ts

// vite.config.ts
import { defineConfig, loadEnv } from 'vite'
import type { UserConfig, ConfigEnv } from 'vite'

import { resolve } from 'path'

// https://vitejs.dev/config/
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
  return {
    plugins: [
      vue(),
    ],
    
    resolve: {
      alias: {
        '@': resolve(__dirname, './src'),
      },
    },
  }
})

2.tsconfig.json

// tsconfig.json
{
  "compilerOptions": {
	 // 配置@路径别名
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
	// ...其他配置

    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,
}

五、安装Router

1.npm安装

npm i vue-router@4

2.创建router文件

在src下创建一个 router 文件夹,再创建一个 index.ts 文件

// router/index.ts
import { createRouter, createWebHashHistory } from 'vue-router';
import type { RouteRecordRaw } from 'vue-router';

const routes: Array<RouteRecordRaw> = [
  {
    name: 'Main',
    path: '/',
    meta: {
      title: 'Main',
    },
    component: () => import('@/views/Main/Main.vue'),
  },
  // 页面不存在时的路由
  {
    name: '404',
    path: '/:pathMatch(.*)*',
    meta: {
      title: '404',
    },
    component: () => import('@/views/Error/404.vue'),
  },
];

const router = createRouter({
  history: createWebHashHistory(),
  routes,
});

export default router;

3.在main.ts中使用router

import { createApp } from 'vue';
import App from './App.vue';

import router from './router'; // 导入 router
import 'normalize.css'; // 引入 normalize.css

const app = createApp(App);

app.use(router); // 使用 router

app.mount('#app');

六、安装 Element Plus

安装

npm install element-plus --save
// main.ts
import { createApp } from 'vue';
import App from './App.vue';

import router from './router';
import 'normalize.css';
import ElementPlus from 'element-plus'; // 引入 ElementPlus
import 'element-plus/dist/index.css'; // 引入 ElementPlus 的 css 文件

const app = createApp(App);

app.use(router);
app.use(ElementPlus); // 使用 ElementPlus

app.mount('#app');

然后我们找一个页面使用一下,看看是否安装配置好了

<template>
  <div class="view">Main</div>
  <div>
    <!-- 使用 ElButton -->
    <el-button>Default</el-button>
    <el-button type="primary">Primary</el-button>
    <el-button type="success">Success</el-button>
    <el-button type="info">Info</el-button>
    <el-button type="warning">Warning</el-button>
    <el-button type="danger">Danger</el-button>
  </div>
</template>

<script setup lang="ts">
import { ElButton } from 'element-plus'; // 引入组件
</script>

<style lang="scss" scoped>
/* by wdTomato */
</style>

效果如下
在这里插入图片描述

七、配置自动化导入

配置自动化导入可以让我们提高我们开发的效率,可以避免我们需要频繁引入经常使用的api以及ui组件,例如vue中的ref,reactive等和element的组件。
但需要注意的是,自定义的方法也配置自动化导入的话,后期在维护的时候可能会不好追溯源

npm install -D unplugin-vue-components unplugin-auto-import
import { defineConfig,} from 'vite'
import type { UserConfig, ConfigEnv } from 'vite'
import vue from '@vitejs/plugin-vue'

import { resolve } from 'path'

// 引入自动导入 api
import AutoImport from 'unplugin-auto-import/vite'
// 引入配置需要自动导入的组件
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

// https://vitejs.dev/config/
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
  return {
    plugins: [
      vue(),
      AutoImport({
        // 配置需要自动导入的模块
        imports: ['vue', 'vue-router'],
        resolvers: [ElementPlusResolver()],
        dts: 'src/types/auto-import.d.ts',
      }),
      // 配置需要自动导入的组件
      Components({
        // 导入存放的位置
        dts: 'src/types/components.d.ts',
        resolvers: [ElementPlusResolver()],
      }),
    ],

    resolve: {
      alias: {
        '@': resolve(__dirname, './src'),
      },
    },
  }
})

配置好后我们就可以直接在.vue文件中使用vue的api,跟element组件了,不要再手动引入
在这里插入图片描述

八、使用仓库管理(Pinia)

Pinia是vue新的存储库,它可以让我们在跨组件通信的时候更加的方便快捷。由于Pinia是基于Vue3的Composition API 构建的,相对于Vuex用Option API更加的轻量级易上手。可以让我们更轻松的管理存储数据。

1.安装

npm install pinia
# 或者使用 yarn
yarn add pinia

2.使用

在src目录下创建store文件夹,再创建一个index.ts文件

import type { App } from 'vue';
import { createPinia } from 'pinia';

const store = createPinia();

// 全局注册 store
export function setupStore(app: App<Element>) {
  app.use(store);
}

export default store;

在main中引入useStore 方法使用

import { createApp } from 'vue';
import App from './App.vue';

import router from './router';  
import 'normalize.css'; 
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
import { useStore } from './store'; // 引入 store

const app = createApp(App);

app.use(router);
app.use(ElementPlus);
app.use(useStore); // 使用 store

app.mount('#app');

3.使用例子

在store文件夹下创建一个modules的文件夹,再创建一个counter.ts的文件

// store/modules/counter.ts
import { defineStore } from 'pinia'; // 引入 defineStore

// 创建一个 counter store
export const useCounterStore = defineStore('counter', () => {
  // 创建一个 count 变量
  const count = ref(0);

  // 创建一个 increment 方法
  const increment = () => count.value++;

  // 返回 count 和 increment
  return {
    count,
    increment,
  };
});


在页面中使用

<template>
  <div class="view">
    <h1>Main + {{ counterStore.count }}</h1>
    <el-button type="primary" @click="increment">+ 1</el-button>
  </div>
</template>

<script setup lang="ts">
import { useCounterStore } from '@/store/modules/counter'; // 引入store
const counterStore = useCounterStore(); // 使用store
// 使用store中的方法
const increment = () => {
  counterStore.increment();
};
</script>

<style lang="scss" scoped>
/* by wdTomato */
.view {
  margin: 200px auto;
  text-align: center;
}
</style>

运行效果
在这里插入图片描述

4.Pinia数据持久化

1).安装
npm i pinia-plugin-persistedstate
2).配置
// store/index.ts
import type { App } from 'vue'; 
import { createPinia } from 'pinia'; 
import piniaPersist from 'pinia-plugin-persistedstate'; // 引入持久化插件

const store = createPinia(); 
store.use(piniaPersist); // 使用 piniaPersist

export function useStore(app: App<Element>) {
  app.use(store);
}
export default store;
3).使用
// 在需要持久化的仓库启用
import { defineStore } from 'pinia';
export const useCounterStore = defineStore(
  'counter',
  () => {
    const count = ref(0);
    const increment = () => count.value++;
    return {
      count,
      increment,
    };
  },
  { persist: true } // 启用持久化
);
4).效果

在这里插入图片描述

九、配置 env 环境

1.创建文件

在项目的根目录创建 .env.development.env.production这两个文件

  • 开发环境
# 开发环境

# 应用标题
VITE_TITLE = 'My-Admin-Dev'
# 端口号
VITE_PORT = 4090
#应用api前缀
VITE_BASE_API = '/dev-api'
# 代理指向地址
VITE_TARGET_URL = 你的接口地址

  • 生产环境
## 生产环境

# 应用标题
VITE_TITLE = 'My-Admin'
# 端口号
VITE_PORT = 4090
#应用api前缀
VITE_BASE_API = '/prod-api'
# 代理指向地址
VITE_APP_TARGET_URL = 你的接口地址

十、Axios

1.安装

npm i axios

2.处理请求,响应拦截

  • 在src下创建 service/request/index.ts文件
import axios from 'axios'
import type { InternalAxiosRequestConfig, AxiosResponse } from 'axios'
import { openLoading, closeLoading } from '@/hooks/useLoading.ts' // 引入开启、关闭 loading

// 创建 axios 示例
const request = axios.create({
  baseURL: import.meta.env.VITE_BASE_API, // 配置基础请求地址(配置方法在前面的 env 环境)
  timeout: 10000, // 请求超时时间
  headers: { 'Content-Type': 'application/json;charset=utf-8' }, // 请求头
})

let loading = false

// 请求拦截
request.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // config 可以拿到我们发送的请求内容,在这里可以配置请求权限,是否有token,根据自己的业务来写逻辑,也可以在这里根据需求修改请求头,请求类型请求时间。。。。
    // 判断是否需要 Loading
    if (!config.hideLoading) {
      openLoading() // 打开 Loading
      loading = true
    }
    console.log('config', config)
    return config // 这里必须要 return出去
  },
  (err: any) => {
    // 请求出错,关闭 Loading,用 Promise 返回错误
    console.log('request err', err)
    if (loading) closeLoading()
    ElMessage.error({
      message: err.msg || '接口请求异常',
    })
    return Promise.reject(err)
  }
)

// 响应拦截
request.interceptors.response.use(
  (response: AxiosResponse) => {
    // 请求内容响应回来,可以在这里做接口判断,可以通过后端返回请求状态码判断,根据后端接口来
    const { data } = response
    // 我这里成功状态码是 200
    if (response.status && response.data.code === 200) {
      if (loading) closeLoading()
      return data
    }
    // 如果不是 200 则返回错误
    if (loading) closeLoading()
    ElMessage.error({
      message: err.msg || '接口返回异常',
    })
    return Promise.reject(data)
  },
  (err: any) => {
    // 响应出错,关闭 Loading,用 Promise 返回错误
    if (loading) closeLoading()
    console.log(err)
    ElMessage.error({
      message: err.msg || '接口返回异常',
    })
    return Promise.reject(err)
  }
)

export default request

  • 创建src/hooks/useLoading.ts,loading hook
// useLoading.ts
import { ElLoading } from 'element-plus'

let loading: { close: () => void }
function openLoading() {
  loading = ElLoading.service({
    lock: true,
    text: 'Loading',
    background: 'rgba(0, 0, 0, 0.7)',
  })
}
function closeLoading() {
  loading.close()
}
export { openLoading, closeLoading }

如果ElMessage或者ElLoading 报错,可能是先前配置自动导入没配置好,需要自己在文件手动导入

import { ElMessage, ElLoading } from 'element-plus'

3.前端配置反向代理,解决跨域

在这里插入图片描述

import { defineConfig, loadEnv } from 'vite'
import type { UserConfig, ConfigEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

// 引入自动导入 api
import AutoImport from 'unplugin-auto-import/vite'
// 引入配置需要自动导入的组件
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

// https://vitejs.dev/config/
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
  const env = loadEnv(mode, process.cwd())
  return {
    plugins: [
      vue(),
      AutoImport({
        // 配置需要自动导入的模块
        imports: ['vue', 'vue-router'],
        resolvers: [ElementPlusResolver()],
        dts: 'src/types/auto-import.d.ts',
      }),
      // 配置需要自动导入的组件
      Components({
        // 导入存放的位置
        dts: 'src/types/components.d.ts',
        resolvers: [ElementPlusResolver()],
      }),
    ],

    // 配置代理
    server: {
      port: Number(env.VITE_PORT), // 启动端口号(配置在.env)
      open: true, // 是否启动就打开浏览器
      // 反向代理
      proxy: {
        [env.VITE_BASE_API]: {
          target: env.VITE_TARGET_URL,
          changeOrigin: true,
          rewrite: (path) =>
            path.replace(
              new RegExp(`^${env.VITE_BASE_API}`),
              env.VITE_TARGET_URL
            ), // 路径重写
        },
      },
    },

    resolve: {
      alias: {
        '@': resolve(__dirname, './src'),
      },
    },
  }
})

4.发送请求

按照我自己的习惯,我会在src创建一个api文件夹存放请求,方便管理
在这里插入图片描述
举个例子,在api文件夹下创建一个文件index.ts

import { AxiosPromise } from 'axios'
import request from '../request/index.ts'

// 查询参数接口
interface IQuery {
  page: number // 请求页码
  pageSize: number // 请求多少条数据
}

// 响应接口
interface ITableList {
  code: number // 响应状态码
  data: any[] // 响应数据
  msg: string // 响应消息
}

// 请求例子
export function getTableApi(queryParams: IQuery): AxiosPromise<ITableList> {
  return request({
    url: '/api/user/getAll', // 接口路径
    method: 'get', // 请求方法 get,post,put。。。
    params: queryParams, // 请求参数
    hideLoading: true, // 是否隐藏 loading,默认为不隐藏
  })
}

在组件(.vue 文件)中使用

<script setup lang="ts">
import { getTableApi } from '@/service/api/index.ts' // 引入接口方法

const getData = async () => {
  try {
    const res = await getTableApi({ page: 1, pageSize: 10 })
    console.log(res)
  } catch (e) {
    // TODO handle the exception
    console.log(e)
  }
}
getData()
</script>

在这里插入图片描述

结语

感谢阅读,有啥问题或者建议可以在评论中给我指出来!

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
搭建一个vue3 ts pinia element-plus后台管理系统框架,可以按照以下步骤进行: 1. 安装Node.js和Vue CLI Vue CLI是用于创建和管理Vue项目的官方工具,需要先安装Node.js和Vue CLI。 2. 创建基于Vue3和TypeScript的项目 使用Vue CLI创建一个基于Vue3和TypeScript的项目,输入以下命令: ``` vue create my-project --preset=@vue/cli-plugin-typescript ``` 3. 安装Pinia Pinia是一个Vue 3状态管理库,可以用于管理应用程序的状态。在项目中安装Pinia,输入以下命令: ``` npm install pinia ``` 4. 安装Element Plus Element Plus是一个基于Vue.js 3的UI库,可用于构建后台管理系统。在项目中安装Element Plus,输入以下命令: ``` npm install element-plus ``` 5. 创建页面和组件 根据项目需求,创建页面和组件。 6. 配置Pinia 在main.ts中引入Pinia,并在创建Vue实例时使用它。示例代码如下: ```typescript import { createApp } from 'vue' import App from './App.vue' import { createPinia } from 'pinia' const app = createApp(App) app.use(createPinia()) app.mount('#app') ``` 7. 配置Element Plus 在main.ts中引入Element Plus,并在创建Vue实例时使用它。示例代码如下: ```typescript import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' import 'element-plus/lib/theme-chalk/index.css' const app = createApp(App) app.use(ElementPlus) app.mount('#app') ``` 8. 编写页面和组件 使用Vue3和TypeScript编写页面和组件。 9. 运行项目 运行项目,输入以下命令: ``` npm run serve ``` 以上就是搭建一个vue3 ts pinia element-plus后台管理系统框架的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值