当前位置: 首页 > article >正文

06vue3实战-----项目开发准备

06vue3实战-----项目开发准备

  • 1.CSS样式的重置
    • 1.1先引入第三方库normalize.css
    • 1.2自己写一些默认样式
  • 2.路由配置
    • 2.1安装路由:
    • 2.2挂载路由:
    • 2.3配置路由
  • 3.状态管理配置
    • 3.1安装pinia
    • 3.2挂载pinia
    • 3.3创建一个store文件
    • 3.4应用store
  • 4.网络请求封装axios
    • 4.1再封装axios
    • 4.2使用封装后的axios

1.CSS样式的重置

对默认CSS样式进行重置。

1.1先引入第三方库normalize.css

命令行安装normalize.css:

 npm install normalize.css

在main.ts文件中引入:

  ...
  import 'normalize.css'
  ...

1.2自己写一些默认样式

在assets文件夹下的css文件夹中新建几个文件:
在这里插入图片描述
common.less放公共的样式,reset.less中放重置的样式,index.less集成其它的css文件。
index.less文件:

@import './reset.less';
@import './common.less';

reset.css放重置的样式,可以自己写,也可以网上找。
reset.less文件:

/* reset.css样式重置文件 */
/* margin/padding重置 */
body, h1, h2, h3, ul, ol, li, p, dl, dt, dd {
  padding: 0;
  margin: 0;
}

/* a元素重置 */
a {
  text-decoration: none;
  color: #333;
}

/* img的vertical-align重置 */
img {
  vertical-align: top;
}

/* ul, ol, li重置 */
ul, ol, li {
  list-style: none;
}

/* 对斜体元素重置 */
i, em {
  font-style: normal;
}

在main.js中引入index.less文件:

  ...
  import 'normalize.css'
  import './assets/css/index.less'
  ...

此时直接运行项目会报错,因为没有安装less编译插件:
在这里插入图片描述
安装less第三方库:

  npm install less -D

再执行就可以成功了。

2.路由配置

2.1安装路由:

  npm install vue-router

在router文件夹(没有该文件夹就在src下创建一个)中创建index.ts文件:

import { createRouter, createWebHashHistory } from 'vue-router'
//通过createRouter我们发现现在前端都转向了函数式编程,之前创建路由是用new关键字
const router = createRouter({
  history: createWebHashHistory(),//这里我们用hash模式举例
  routes: []
})
export default router

2.2挂载路由:

在main.ts中挂载:

import { createApp } from 'vue'
import 'normalize.css'
import './assets/css/index.less'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')

2.3配置路由

先在views文件夹中创建一些文件:
在这里插入图片描述
Login.vue:
在这里插入图片描述
文件出现一个警告,鼠标悬浮提示:

Component name "Login" should always be multi-word.eslintvue/multi-word-component-names

在.eslintrc.cjs文件中进行rules配置:

 rules: {
    ...
    'vue/multi-word-component-names': 'off'
  }

配置完之后就不会警告了。
上述初始化vue文件内容太麻烦,我们可以创建一些代码片段作为模板,具体操作见我写的这篇文章https://blog.csdn.net/fageaaa/article/details/145481103。
最终我们会初始化Login.vue和Main.vue中的内容。
Login.vue:

<template>
  <div class="login">
    <h2>login</h2>
  </div>
</template>

<script setup lang="ts"></script>

<style lang="less" scoped></style>

Main.vue:

<template>
  <div class="main">
    <h2>main</h2>
  </div>
</template>

<script setup lang="ts"></script>

<style lang="less" scoped></style>

在router/index.ts追加路由配置:

import { createRouter, createWebHashHistory } from 'vue-router'

const router = createRouter({
  history: createWebHashHistory(),
  // 映射关系: path => component
  routes: [
    {
      path: '/',
      redirect: '/main'
    },
    {
      path: '/login',
      component: () => import('../views/login/Login.vue')
    },
    {
      path: '/main',
      component: () => import('../views/main/Main.vue')
    },
  ]
})
//后面要做路由导航守卫
export default router

当地址栏输入的网址没有对应页面的时候应该跳转到not found页面。新建not-found文件夹,并且初始化其中的vue文件内容。
NotFound.vue:

<template>
  <div class="not-found">
    <h2>您输入的路径地址不正确, 请联系管理员~</h2>
  </div>
</template>

<script setup lang="ts"></script>
<style lang="less" scoped>
.not-found {
  color: purple;
}
</style>

在router/index.ts可继续追加路由配置:

import { createRouter, createWebHashHistory } from 'vue-router'

const router = createRouter({
  history: createWebHashHistory(),
  // 映射关系: path => component
  routes: [
    ...
    {
      path: '/:pathMatch(.*)',
      component: () => import('../views/not-found/NotFound.vue')
    }
  ]
})
//后面要做路由导航守卫
export default router

可以运行项目测试一下。

3.状态管理配置

  • vuex: 目前依然使用较多的状态管理库;
  • pinia: 强烈推荐, 未来趋势的状态管理库;

3.1安装pinia

 npm install pinia

在store文件夹(没有该文件夹就在src下创建一个)中创建index.ts文件:

import { createPinia } from 'pinia'

const pinia = createPinia()

export default pinia

3.2挂载pinia

在main.ts中挂载:

import { createApp } from 'vue'
import 'normalize.css'
import './assets/css/index.less'
import App from './App.vue'
import router from './router'
import pinia from './store'

const app = createApp(App)
app.use(router)
app.use(pinia)
app.mount('#app')

3.3创建一个store文件

在store文件中创建counter.ts文件:

import { defineStore } from 'pinia'
const useCounterStore = defineStore('counter', {
  state: () => ({
    counter: 100
  }),
  getters: {
    doubleCounter(state) {
      return state.counter * 2
    }
  },
  actions: {
    changeCounterAction(newCounter: number) {
      this.counter = newCounter
    }
  }
})
export default useCounterStore

3.4应用store

<template>
  <div class="main">
    <h2>main: {{ counterStore.counter }}-{{ counterStore.doubleCounter }}</h2>
    <button @click="changeCounter">修改counter</button>
  </div>
</template>

<script setup lang="ts">
import useCounterStore from '@/store/counter'
const counterStore = useCounterStore()
function changeCounter() {
  counterStore.changeCounterAction(999)
}
</script>

<style lang="less" scoped>
.main {
  color: red;
}
</style>

4.网络请求封装axios

4.1再封装axios

需要对axios进行再封装。之后我会专门写一篇文章详细讲述封装axios的思路。下面是封装axios的目录结构:
在这里插入图片描述
service/config/index.ts:

  let BASE_URL='接口地址';
  const TIME_OUT = 10000;
  export {
    BASE_URL,
    TIME_OUT 
  }

service/request/index.ts:

import axios from 'axios'
import type { AxiosInstance } from 'axios'
import type { HYRequestConfig } from './type'
// 拦截器: 蒙版Loading/token/修改配置
/**
 * 两个难点:
 *  1.拦截器进行精细控制
 *    > 全局拦截器
 *    > 实例拦截器
 *    > 单次请求拦截器
 *
 *  2.响应结果的类型处理(泛型)
 */
class HYRequest {
  instance: AxiosInstance
  // request实例 => axios的实例
  constructor(config: HYRequestConfig) {
    this.instance = axios.create(config)
    // 每个instance实例都添加拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // loading/token
        return config
      },
      (err) => {
        return err
      }
    )
    this.instance.interceptors.response.use(
      (res) => {
        return res.data
      },
      (err) => {
        return err
      }
    )
    // 针对特定的hyRequest实例添加拦截器
    this.instance.interceptors.request.use(
      config.interceptors?.requestSuccessFn,
      config.interceptors?.requestFailureFn
    )
    this.instance.interceptors.response.use(
      config.interceptors?.responseSuccessFn,
      config.interceptors?.responseFailureFn
    )
  }
  // 封装网络请求的方法
  // T => IHomeData
  request<T = any>(config: HYRequestConfig<T>) {
    // 单次请求的成功拦截处理
    if (config.interceptors?.requestSuccessFn) {
      config = config.interceptors.requestSuccessFn(config)
    }
    // 返回Promise
    return new Promise<T>((resolve, reject) => {
      this.instance
        .request<any, T>(config)
        .then((res) => {
          // 单词响应的成功拦截处理
          if (config.interceptors?.responseSuccessFn) {
            res = config.interceptors.responseSuccessFn(res)
          }
          resolve(res)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }
  get<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'GET' })
  }
  post<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'POST' })
  }
  delete<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'DELETE' })
  }
  patch<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'PATCH' })
  }
}
export default HYRequest

service/request/type.ts:

import type { AxiosRequestConfig, AxiosResponse } from 'axios'

// 针对AxiosRequestConfig配置进行扩展
export interface HYInterceptors<T = AxiosResponse> {
  requestSuccessFn?: (config: AxiosRequestConfig) => AxiosRequestConfig
  requestFailureFn?: (err: any) => any
  responseSuccessFn?: (res: T) => T
  responseFailureFn?: (err: any) => any
}
export interface HYRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
  interceptors?: HYInterceptors<T>
}

service/index.ts:

import { BASE_URL, TIME_OUT } from './config'
import HYRequest from './request'

const hyRequest = new HYRequest({
  baseURL: BASE_URL,
  timeout: TIME_OUT
})

export default hyRequest

4.2使用封装后的axios

在Login.vue中做测试:

  <template>
  <div class="login">
    <h2>login</h2>
  </div>
</template>
<script setup lang="ts">
import hyRequest from '@/service'
hyRequest
  .get({
    url: '/home/multidata'
  })
  .then((res) => {
    console.log(res)
  })
</script>
<style lang="less" scoped>
.login {
  color: red;
}
</style>

运行项目看看控制台有没有打印出相应的结果。
在这里插入图片描述
这样子说明已经成功。
下一章节https://blog.csdn.net/fageaaa/article/details/145513384我将详细讲述一下vue实战项目中开发环境和生产环境的区别。


http://www.kler.cn/a/536500.html

相关文章:

  • Ollama python交互:chat+embedding实践
  • 网安三剑客:DNS、CDN、VPN
  • 优惠券平台(十一):布隆过滤器、缓存空值、分布式组合的双重判定锁解决缓存穿透问题
  • Apache SeaTunnel 整体架构运行原理
  • Word List 2
  • 网络编程day1
  • windows部署本地deepseek
  • arkui-x 鼠标切换为键盘,焦点衔接问题
  • 【实战篇】DeepSeek + Cline 编程实战:从入门到“上头”
  • STM32上部署AI的两个实用软件——Nanoedge AI Studio和STM32Cube AI
  • 流媒体缓存管理策略
  • Python的那些事第十四篇:Flask与Django框架的趣味探索之旅
  • 阿里云cdn怎样设置图片压缩
  • 【Spring】_SpringBoot配置文件
  • Jetpack ViewModel
  • grafana面板配置opentsdb
  • 大模型deepseek-r1 本地快速搭建
  • 3D展示已成趋势,哪些产品适合3D交互展示?
  • 不用调试器,如何定位“Hard Fault”?
  • 用户点击商品埋点的实现方案
  • 跨平台App开发,有哪些编程语言和工具,比较一下优劣势?
  • STM32的HAL库开发-通用定时器输入捕获实验
  • 【电商系统架构的深度剖析与技术选型】
  • 基于SpringBoot养老院平台系统功能实现五
  • MySQL三大日志——binlog、redoLog、undoLog详解
  • RAG:知识库参数设置