Vue3 &TS & Vite 整合组件脚手架笔记

序号更新时间备注
12024.09.02初始化整理笔记
22024.09.04针对pinia的使用问题更新

一、安装运行命令

yarn install

yarn run dev

yarn run build

二、相关依赖内容

1、路由相关

yarn add @types/vue-router@4

组件都需要在 app.mount(‘#app’); 之前

建议使用hitsory模式,然后谨记,需要在创建的时候加上相对地址

const router = createRouter({
  scrollBehavior: () => ({ left: 0, top: 0 }),
  history: createWebHistory("/**/"),
  routes,
});

安装配置

//main.ts
import router from './router'

const app = createApp(App);
app.use(router);

app.mount('#app');

示例路由

// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'

export const routes = [
  {
    name: "demo",
    path: "/index.html",
    component: () => import("../components/index.vue"),
  },
];

const router = createRouter({
  scrollBehavior: () => ({ left: 0, top: 0 }),
  history: createWebHistory(import.meta.env.VITE_Base_URL),
  routes,
});

router.beforeEach((to, from, next) => {
  var failure = "/index.html";
  if (failure != to.path) {
    next(failure);
  }
  next();
});

export default router;

2、http客户端 - alova

yarn add alova

建议安装状态控制,映射 hook 状态和函数到 vue 实例

yarn add @alova/vue-options

import { createAlova} from "alova";
import { VueOptionsHook } from '@alova/vue-options';
import adapterFetch from 'alova/fetch';

export const request = createAlova({
    statesHook: VueOptionsHook,
    requestAdapter: adapterFetch(),
    responded:{
        onSuccess: async (response, method) => {
            if (response.status >= 400) {
              throw new Error(response.statusText);
            }
            const json = await response.json();
            return json;
          },
          onError: (err, method) => {
            console.error(err);
          },
          onComplete: async method => {
            // 处理请求完成逻辑
          }
    }
});


3、国际化 - I18n

yarn add vue-i18n@next --save

yarn add @intlify/devtools-types (兼容ts)

import i18n from './i18n/index'

app.use(i18n);
//组件都需要在 app.mount('#app'); 之前

./i18n/index.ts 配置

import { createI18n } from 'vue-i18n'
import zh_CN from './zh_CN'
import en_US from './en_US'
import zh_HK from './zh_HK'
const locale = localStorage.getItem('locale') || navigator.language || 'zh-CN'
const i18n = createI18n({
    locale: locale,    // 语言标识
    silentTranslationWarn: true, //消除警告 
    missingWarn: false, //消除警告
    //this.$i18n.locale // 通过切换locale的值来实现语言切换
    messages: {
      'zh-CN': zh_CN,   // 中文语言包
      'en-US': en_US,    // 英文语言包
      'zh-HK': zh_HK    // 繁体文语言包
    }
})
export default i18n

zh_CN.ts 配置示例

const locale = {

};

export default {
    locale
  }

4、兼容sass

yarn add -D sass

yarn add sass-loader

// 全局使用
export default defineConfig({
  plugins: [vue()],
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `@import '@/styles/main.scss';`
      }
    }
  }
});
//局部使用
<style lang="scss" module>
.demo-component {
  // Sass code for the component
}

5、全局状态管理 - Pinia

Vuex的可替代工具

yarn add pinia

import { createPinia } from 'pinia'

const pinia = createPinia()
app.use(pinia)

6、UI組件 - element-plus

yarn add element-plus (不建議問爲啥不直接element-ui)

https://cn.element-plus.org/zh-CN/guide/installation.html

Tips: 如果有需要,其實還是自己做組件的

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)
app.use(ElementPlus)
自动导入

这个可以避免很多编译问题

yarn add unplugin-vue-components unplugin-auto-import

样式配置
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  // ...
  plugins: [
    // ...
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
})

7、时间管理 - moment

yarn add moment

yarn add @types/moment

三、基础版本

1、yarn & Vue3 & vite& node 18+

vite : https://cn.vitejs.dev/guide/

2、empty folder initialize

# 初始化vite
yarn create vite

# 构建vue的模板
yarn  create vite ts_vue_front_end --template vue-ts

四、编译配置

针对配置文件 tsconfig.json 的配置

compilerOptions

序号属性示例备注
1baseUrl"./""./" 表示项目的根目录,所有相对路径的模块解析都从此目录开始
2paths"@/*": ["./src/*"]配置模块路径映射,方便汇入文件,将@定义到相对位置src上
3lib["esnext", "dom"]设置基础编译库,使得可以正常运行 ,可以参考 lib内容
4moduleesnextesnext使用最新的 ES 模块语法
5moduleResolutionnode使得ts支持 node_modules 目录、文件扩展名自动推断
6resolveJsonModuletrue允许将 JSON 文件作为模块导入
7esModuleInteroptrue更好的支持 commonjs 说白了,export 和 import更加便捷
8skipLibCheckfalse若为true,会去检查各种声明,若是确定无声明问题,可以直接false
9allowSyntheticDefaultImportstrue用于控制是否允许从非 ES 模块,通常来说支持json导入无额外提示
10typeRoots[‘’]指定读取目标目录下的types,作为全局声明

针对生产编译

针对配置文件 package.json 上的 scripts

将参数 vue-tsc -b && vite build 变更为 vite build

五、问题定位

1、无法直接打开index.html

打包后的文件提供传统浏览器兼容性支持。

https://github.com/vitejs/vite/tree/main/packages/plugin-legacy

Tips:下列安装插件,连接不上可以加国内源:–registry https://registry.npm.taobao.org/

1、yarn add @vitejs/plugin-legacy

**2、yarn add terser **

//vite.config.ts
export default defineConfig({
...
  plugins: [
  ...
    viteLegacyPlugin({
      //用于兼容直接打开文件访问的模式
      renderModernChunks: false,
    }),
   ...
  ],
...
})

2、使用 @ 来引入文件

为避免 找不到模块“path”或其相应的类型声明 ,建议安装

yarn add @types/node

//tsconfig.json
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
//vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  }
});

3、类型声明问题

vue

新建 vue.d.ts,定义类型,这里会被编译配置中的 inlcude 扫描到 处理

使得编译器不会出现:

`无法找到模块“./xx.vue”的声明文件,... 隐式拥有 "any" 类型
/// <reference types="vite/client" />

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
  const component: DefineComponent<{}, {}, any>
  export default component
}

4、统一管理types

为了更好的管理types,需要构建一个位置存放接口,配置参考 四、编译配置 中的 typeRoots

假设设置为 : “typeRoots”: [“./types”]

则于该目录下:/types

//index.d.ts
// 这样就无需在业务ts上重复定义声明interface了
declare global {
  interface LangProp {
    lang: string;
    langlist: any[];
    langMap: {};
    langbtn: boolean;
  }
}

export {}

5、vue使用 withDefaults 的问题

这里使用全局声明也是不可以的,建议采用import的方式引入声明

//这里建议引入声明避免
import {ConversationType} from '@/types'

const props = withDefaults(defineProps<ConversationType>(), {
  content:"",
  dataType:"text"
})

6、环境内容配置

如何配置多个环境信息,使得可以在不同需求下用不同环境内容去调试

假设这里存在两个环境,devprod ,需要针对调用http使用不同 baseUrl

参考: https://cn.vitejs.dev/guide/env-and-mode

若未安装 dotenv : yarn add dotenv

则设置dev,创建文件 .env.development

VITE_Base_URL=./
VITE_Http_URL=http://localhost:8888

则设置prod,创建文件 .env.production

VITE_Base_URL=/dist/
VITE_Http_URL=http://domain

如何使用

可以通过 import.meta.env.VITE_Http_URL 直接引用

//例如配置 Alova
export const request = createAlova({
  baseURL: import.meta.env.VITE_Http_URL,
  statesHook: VueOptionsHook,
  requestAdapter:
    process.env.NODE_ENV === "development" ? mockAdapter : GlobalFetch,
  responded: (response) => response.json(),
});

如何变更环境

package.json 中,若是本地测试,变更为prod 环境,则变更如下文件

  "scripts": {
    "dev": "vite --NODE_ENV production",
    "build": "vite build",
    "preview": "vite preview"
  },

7、自定义标签而非自定义组件时如何排除

开头配置

假设自定义标签是以custom- 开头

// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue({
    template: {
      compilerOptions: {
       isCustomElement: (tag) => tag.startsWith("custom-"),
      }
    }
  })],
});

包含配置

仅想特定标签,比如 solveunsolve

// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue({
    template: {
      compilerOptions: {
        isCustomElement: (tag) => ['solve','unsolve'].includes(tag)
      }
    }
  })],
});

8、自定义的js打包时无法引入的问题

通常会出现 XXX can't be bundled without type="module" attribute,且打包后无法访问该js

目前仅发现使用public的内容,建议还是改成ts。

仍坚持

//tsconfig.json
{
  "compilerOptions": {
     // JavaScript 中使用 TypeScript 定义的类型
    "declaration": true,
    "declarationMap": true,
    "emitDeclarationOnly": true,
    // 补充JS支持
    "allowJs": true
  }
}

构建层级

│   ├── utils/
│   │   ├── tool.ts // TypeScript 文件
│   │   └── tool.js // JavaScript 文件

9、打包后发现css或js没有引用相对位置

vite.config.ts 文件

export default defineConfig({
 // 如果是配置了路径,可以配路径
 base: ./   
})

10、关于pinia订阅属性无法传递的问题

非第一层级的值,建议声明赋值。
目前发现,若非声明类型会存在 非一级属性 无法通过.$subscribe 的模式监听。
1、主要是因为挂载 $subscribe 的事件在 store 初始化之前导致
2、同时,不要直接放到app.vue 也就是初始化挂载的页面上去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值