撸一个vue3+vite+pinia+vant4项目

最近用vue3做一个移动端的小项目,记录一下所用,主要用到了vue3+vite+axios+pinia+vant4+Ts+echarts+sass

首先创建基于vite的构建设置

在命令行运行
npm init vue@lates
创建你的项目,根据需要选择你要开启的功能,然后

cd
npm install
npm run dev
这时你的项目就启动起来了

安装vant

参照vant官网
1、安装vant > npm i vant
2、引入组件。在main.ts里

import {
    
     createApp } from 'vue';
import App from './App.vue'
// 1. 引入你需要的组件
import {
    
     Button, ..... } from 'vant';
// 2. 引入组件样式
import 'vant/lib/index.css';
const app = createApp(App)

// 3. 注册你需要的组件
app.use(Button)
app.use(xxx)
// 挂载
app.mount('#app')

3、就可以在组件中使用了

安装pinia及其数据持久化

在创建项目的时候已经选择了pinia,这里需要实现数据持久化。pinia状态存储再浏览器内存,同vuex一样,刷新页面的时候store里的数据会丢失,页面重新加载会初始化pinia。像我们用户的登录信息这些肯定需要记录,vuex是存储到浏览器本地,每次刷新的时候去浏览器localstore或是sessionstore里取,pinia我们使用插件来实现
1、npm i pinia-plugin-persistedstate 安装pinia-plugin-persistedstate插件
2、然后在main.ts里引入,传递给app实例

import piniaPluginPersistedstate from ‘pinia-plugin-persistedstate’
app.use(createPinia().use(piniaPluginPersistedstate))

3、然后在stores的单个store下开启数据持久化

import {
    
     ref } from 'vue'
import {
    
     defineStore } from 'pinia'

export const useTokenStore = defineStore('tokenkey', () => {
    
    
  const token = ref('')
  return {
    
     token }
}, {
    
    
  persist: true // 开启数据持久化,存储在localStorage
})

// 也可以指定存储在sessionStorage
persist: {
    
    
   key: 'a',
   storage: sessionStorage
 }

4、在组件内使用
import { useTokenStore } from ‘@/stores/token’;
const store = useTokenStore();
// store.token 就可以拿到了
在util/request.js下使用

import axios from 'axios';
import {
    
     useTokenStore } from '@/stores'; // 使用pinia状态
const store = useTokenStore();
const Axios = axios.create({
    
    
    baseURL: '/api',
    timeout: 3000
});

Axios.interceptors.request.use(req => {
    
    
    // 请求拦截处理
    req.headers.Authorization = "Bearer " + store.token // 这这这
    return req;
}, err => {
    
    
    return Promise.reject(err);
})

Axios.interceptors.response.use(res => {
    
    
    // 响应拦截处理
    if (res.data.errorCode === '401') {
    
    
        store.$patch({
    
     token: '' }) // 改变状态值
    }
    return res.data;
}, error => {
    
    
    const err = error.toString();
    //按照实际的响应包进行解析,通过关键字匹配的方式
    switch (true) {
    
    
        case err.indexOf('Network') !== -1:
            console.log('后端服务器无响应或者URL错误', err);
            break;
        case err.indexOf('timeout') !== -1:
            console.log('请求后端服务器超时!', err);
            break;
    }
    return Promise.reject(error);
})
export default Axios;

5、在路由里使用(组件外)官方更详细

import {
    
     useTokenStore } from '@/stores/token';
router.beforeEach(async (to, from) => {
    
    
  const store = useTokenStore(); // 在方法里边使用
  if (store.token==='' && to.meta.requiresAuth) {
    
    
    return {
    
    
      path: '/login',
      query: {
    
     redirect: to.fullPath },
    }
  }
})

6、注注注意意意: pinia 和vuex,通过解构的方式获取状态,会导致状态失去响应性,用storeToRefs函数

扫描二维码关注公众号,回复: 15815495 查看本文章
import useCounterStore from '@/store/count'
import {
    
     storeToRefs } from 'pinia'const counterStore = useCounterStore()
const {
    
     count } = storeToRefs(counterStore)

vant4 Toast使用上的变化

因为vue3 setup里拿不到this对象,对于vue3和vant<4的版本可以采用getCurrentInstance
1、main.ts里通过app.config.globalProperties挂载

import {
    
     createApp } from 'vue'
import {
    
     Toast } from 'vant'
 
const app = createApp(App);
app.config.globalProperties.$toast = Toast;

const vm = app.mount('#app')

2、组件里使用

<script setup>
import {
    
    ref, getCurrentInstance} from "vue";
const {
    
    proxy} = getCurrentInstance()
// proxy?.$toast('你好啊');
</script>

但是vant4不是这样的
import {showToast, showSuccessToast, showFailToast } from ‘vant’
然后就可以直接使用了 showToast(你好’); showSuccessToast(‘成功’); showFailToast(‘失败’);

px转vw做分辨率适配

1、安装插件npm i -save-dev postcss-px-to-viewport-8-plugin
最开始装的postcss-px-to-viewport 预览的时候提示不支持,vite.config.ts引入的时候也提示未找到,但是浏览器看css又是转为xw了的,安全起见,换成postcss-px-to-viewport-8-plugin,就不报错了
2、vite.config.ts里配置

import postcssPxToViewport from 'postcss-px-to-viewport-8-plugin';
export default defineConfig({
    
    
 ...
 resolve:{
    
    },
 server: {
    
    },
 css: {
    
    
	postcss: {
    
    
      postcsspxtoviewport({
    
    
        unitToConvert: 'px', // 要转换的单位,默认为"px"
        viewportWidth: 750, // I设计稿的宽度
        unitPrecision: 6, // 转换后的精度,即小数点位数
        propList: ['*', '!font-size'], // 能指定转换的css属性的单位,*代表全部css属性的单位都进行转换, !font-size 表示 font-size 后面的单位不会被转换
        viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
        fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
        // 需要忽略的 CSS 选择器,不会转为视口单位,使用原有的px等单位。
        selectorBlackList:  ['ignore-'], // 指定不转换为视窗单位的类名
        minPixelValue: 1, // 设置最小的转换数值,默认值1,小于或等于1px则不进行转换
        mediaQuery: false, // 是否在媒体查询的css代码中也进行转换,默认false
        replace: true, //  是否直接更换属性值,而不添加备用属性
        // exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
       // include: [/src/], // 如果设置了include,那将只有匹配到的文件才会被转换
        landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
        // landscapeUnit: 'vw', // 横屏时使用的单位
        // landscapeWidth: 1338, // 横屏时使用的视口宽度
      })
    }
  }
})

TS的一些报错修改

1、类型“HTMLELement nul1”的参数不能赋给类型“HTMLELement”的参数。不能将类型“nul1”分配给类型“HTMLELement”。
类型“HTMLELement nul1”的参数不能赋给类型“HTMLELement”的参数。不能将类型“nul1”分配给类型“HTMLELement”。
myChart = document.getElementById(‘box’) => myChart = document.getElementById(‘box’)!
或者 myChart = document.getElementById(‘box’) as HTMLElement
2、
类型“any”的参数不能赋给类型“never"的参数
类型“any”的参数不能赋给类型“never"的参数
const list = ref([]); list.value.push(…res.data.list); => const list = ref([] as any[]);
3、类型“stringLocationQueryValue[]”的参数不能赋给类型“RouteLocationRaw”的参数。不能将类型“LocationQueryValuer1”分配给类型“RouteLocationRaw”。
类型“stringLocationQueryValue[]”的参数不能赋给类型“RouteLocationRaw”的参数。不能将类型“LocationQueryValuer1”分配给类型“RouteLocationRaw”。
router.replace(route.query.redirect); => router.replace(route.query.redirect as any);
4、引入的.vue组件报找不到
ts不能识别.vue的文件
env.d.ts里增加

// env.d.ts
/// <reference types="vite/client" />
 
// 简单版本
// declare module '*.vue'
 
// 推荐使用
declare module '*.vue' {
    
    
  // 引入vue模块中ts的方法
  import type {
    
     DefineComponent } from 'vue'
  // 定义vue组件以及类型注解
  const component: DefineComponent<{
    
    }, {
    
    }, any>
  export default component
 }

就这样把,先记录下这些。anyscript大法【捂脸】希望6月可以改掉,拥抱ts。6月,你好!6.1快乐!

猜你喜欢

转载自blog.csdn.net/qq_38661597/article/details/130767623