vue3药企项目第一天

初始化项目:

npm i pnpm -g
pnpm create vue
✔ Project name: … patients-h5-100
✔ Add TypeScript? … No / `Yes`
✔ Add JSX Support?`No` / Yes
✔ Add Vue Router for Single Page Application development? … No / `Yes`
✔ Add Pinia for state management? … No / `Yes`
✔ Add Vitest for Unit Testing?`No` / Yes
✔ Add Cypress for both Unit and End-to-End testing?`No` / Yes
✔ Add ESLint for code quality? … No / `Yes`
✔ Add Prettier for code formatting? … No / `Yes`

Scaffolding project in /Users/zhousg/Desktop/patient-h5-100...

Done. Now run:

  cd yaoqi-yume
  pnpm install
  pnpm dev

下载包:

pnpm add sass -D
pnpm add vant
pnpm add -D postcss-px-to-viewport     //使用 vw 完成移动端适配
pnpm i pinia-plugin-persistedstate    //pinia数据持久化

路由代码解析

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

// createRouter 创建路由实例,===> new VueRouter()
// history 是路由模式,hash模式,history模式
// createWebHistory() 是开启history模块   http://xxx/user
// createWebHashHistory() 是开启hash模式    http://xxx/#/user

// vite 的配置 import.meta.env.BASE_URL 是路由的基准地址,默认是 ’/‘
// https://vitejs.dev/guide/build.html#public-base-path
// 如果将来你部署的域名路径是:http://xxx/my-path/user
// vite.config.ts  添加配置  base: my-path,路由这就会加上 my-path 前缀了

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: []
})

export default router

main.ts

import { createApp } from 'vue'
import { createPinia } from 'pinia'

import pinia from './stores'

import App from './App.vue'
import router from './router'

// 导入 vant 的样式
import 'vant/lib/index.css'
// 导入全局样式
import './styles/main.scss'
// 导入 svg 的精灵图
// import 'virtual:svg-icons-register'
import persist from 'pinia-plugin-persistedstate'

const app = createApp(App)
app.use(createPinia().use(persist))

app.use(pinia)
app.use(router)

app.mount('#app')

测试vant代码引入:app.vue

<script setup lang="ts">
import { Button as VanButton } from 'vant'
</script>

<template>
  <van-button>按钮</van-button>
</template>

<style scoped></style>

移动端适配

配置: postcss.config.cjs

// eslint-disable-next-line no-undef
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      // 设备宽度375计算vw的值
      viewportWidth: 375,
    },
  },
};

在这里插入图片描述

css变量主题定制

styles/main.scss

:root {
  // 问诊患者:色板
  --cp-primary: #16C2A3;
  --cp-plain: #EAF8F6;
  --cp-orange: #FCA21C;
  --cp-text1: #121826;
  --cp-text2: #3C3E42;
  --cp-text3: #6F6F6F;
  --cp-tag: #848484;
  --cp-dark: #979797;
  --cp-tip: #C3C3C5;
  --cp-disable: #D9DBDE;
  --cp-line: #EDEDED;
  --cp-bg: #F6F7F9;
  --cp-price: #EB5757;
  // 覆盖vant主体色
  --van-primary-color: var(--cp-primary);
}

用户状态仓库

types/user.d.ts

// 用户信息
export type User = {
  /** token令牌 */
  token: string
  /** 用户ID */
  id: string
  /** 用户名称 */
  account: string
  /** 手机号 */
  mobile: string
  /** 头像 */
  avatar: string
}

stores/user.ts

import type { User } from "@/types/user";
import { defineStore } from "pinia";
import { ref } from "vue";

export const useUserStore = defineStore(
  "cp-user",
  () => {
    // 用户信息
    const user = ref<User>();
    // 设置用户,登录后使用
    const setUser = (u: User) => {
      user.value = u;
    };
    // 清空用户,退出后使用
    const delUser = () => {
      user.value = undefined;
    };
    return { user, setUser, delUser };
  },
  {
    persist: true,
  }
);

stores统一导出

stores/index

import { createPinia } from 'pinia'
import persist from 'pinia-plugin-persistedstate'
// 创建pinia实例
const pinia = createPinia()
// 使用pinia插件
pinia.use(persist)
export default pinia

// 统一导出 store
export * from './user'

请求拦截器逻辑

utils/request.ts

import { useUserStore } from '@/stores'
import router from '@/router'
import axios, { AxiosError, type Method } from 'axios'

import { showToast } from 'vant'
const baseURL = 'https://consult-api.itheima.net'


// 1. 新axios实例,基础配置
const instance = axios.create({
    baseURL: baseURL,
    timeout: 10000
})

// 2. 请求拦截器,携带token
instance.interceptors.request.use(
    (config) => {
        const store = useUserStore()
        if (store.user?.token && config.headers) {
            config.headers['Authorization'] = `Bearer ${store.user?.token}`
        }
        return config
    },
    (err) => Promise.reject(err)
)

// 3. 响应拦截器,剥离无效数据,401拦截
instance.interceptors.response.use(
    (res) => {
        // 后台约定,响应成功,但是code不是10000,是业务逻辑失败
        if (res.data?.code !== 10000) {
            showToast(res.data?.message || '业务失败')
            return Promise.reject(res.data)
        }
        // 业务逻辑成功,返回响应数据,作为axios成功的结果
        return res.data
    },
    (err) => {
        if (err.response.status === 401) {
            // 删除用户信息
            const store = useUserStore()
            store.delUser()
            // 跳转登录,带上接口失效所在页面的地址,登录完成后回跳使用
            router.push({
                path: '/login',
                query: { returnUrl: router.currentRoute.value.fullPath }
            })
        }
        return Promise.reject(err)
    }
)
type Data<T> = {
    code: number
    message: string
    data: T
}
// 4. 请求工具函数
const request = <T>(url: string, method: Method = 'get', submitData?: object) => {
    return instance.request<T, Data<T>>({
        url,
        method,
        [method.toLowerCase() === 'get' ? 'params' : 'data']: submitData
    })
}

export { baseURL, instance, request }

测试请求工具

App.vue

<script setup lang="ts">
import { request } from '@/utils/request'
import type { User } from './types/user'
import { Button as VanButton } from 'vant'
import { useUserStore } from './stores'

// 测试,请求拦截器,是否携带token,响应拦截器401拦截到登录地址
const getUserInfo = async () => {
  const res = await request('/patient/myUser')
  console.log(res)
}

// 测试,响应拦截器,出现非10000的情况,和返回剥离后的数据
const store = useUserStore()
const login = async () => {
  const res = await request<User>('/login/password', 'POST', {
    mobile: '13211112222',
    // 密码 abc123456 测试:出现非10000的情况
    password: 'abc12345'
  })
  store.setUser(res.data)
}
</script>

<template>
  <van-button type="primary" @click="getUserInfo">获取个人信息</van-button>
  <van-button type="primary" @click="login">登录</van-button>
</template>
  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的海滨体育馆管理系统,源码+数据库+毕业论文+视频演示 本基于Spring Boot的海滨体育馆管理系统设计目标是实现海滨体育馆的信息化管理,提高管理效率,使得海滨体育馆管理工作规范化、高效化。 本文重点阐述了海滨体育馆管理系统的开发过程,以实际运用为开发背景,基于Spring Boot框架,运用了Java技术和MySQL作为系统数据库进行开发,充分保证系统的安全性和稳定性。本系统界面良好,操作简单方便,通过系统概述、系统分析、系统设计、数据库设计、系统测试这几个部分,详细的说明了系统的开发过程,最后并对整个开发过程进行了总结,实现了海滨体育馆相关信息管理的重要功能。 本系统的使用使管理人员从繁重的工作中解脱出来,实现无纸化办公,能够有效的提高海滨体育馆管理效率。 关键词:海滨体育馆管理,Java技术,MySQL数据库,Spring Boot框架 本基于Spring Boot的海滨体育馆管理系统主要实现了管理员功能模块和学生功能模块两大部分,这两大功能模块分别实现的功能如下: (1)管理员功能模块 管理员登录后可对系统进行全面管理操作,包括个人中心、学生管理、器材管理、器材借出管理、器材归还管理、器材分类管理、校队签到管理、进入登记管理、离开登记管理、活动预约管理、灯光保修管理、体育论坛以及系统管理。 (2)学生功能模块 学生在系统前台可查看系统信息,包括首页、器材、体育论坛以及体育资讯等,没有账号的学生可进行注册操作,注册登录后主要功能模块包括个人中心、器材管理、器材借出管理、器材归还管理、校队签到管理、进入登记管理、离开登记管理、活动预约管理。
第一天开始学习Vue 3,首先要了解Vue的基本概念和核心功能。Vue是一个用于构建用户界面的渐进式JavaScript框架,它采用组件化的方式来开发应用程序。 在Vue 3中,有一些重要的变化和改进。首先,Vue 3引入了Composition API,这是一个全新的API,可以让我们更好地组织和共享组件逻辑。通过Composition API,我们可以使用函数来编写组件的逻辑,而不仅仅是通过选项对象。 另一个重要的改进是性能的提升。Vue 3在内部进行了许多优化,例如使用Proxy替换了原来的Object.defineProperty来实现响应式系统。这使得Vue 3在处理大型数据集和性能敏感应用程序时更高效。 还有一项重大的变化是对TypeScript的更好支持。Vue 3引入了许多类型声明文件,使得在使用TypeScript时更容易推断和检测组件的类型。 在第一天,我们可以开始学习Vue 3的安装和使用。我们可以通过npm或yarn来安装Vue,然后使用Vue的命令行工具创建一个新的Vue项目。 接下来,我们可以学习Vue的基本语法和核心概念,例如如何定义一个组件、使用指令和插值表达式、处理事件等。 最后,我们可以尝试编写一个简单的Vue应用程序,并将其运行起来。通过实践,我们可以更加深入地理解Vue的使用和原理。 第一天是学习Vue 3的基础,为接下来的学习打下坚实的基础。希望通过努力学习,在接下来的30天内可以精通Vue 3的使用和开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值