[笔记]Vue3+TS+Vite

所有提出问题都在https://gitee.com/dromara/RuoYi-Vue-Plus这个框架基础之上提出
使用pnpm 安装依赖, 基本上都是最新版本

//package.json 
{
  "name": "ruoyi-vue-plus",
  "version": "5.1.2",
  "description": "RuoYi-Vue-Plus多租户管理系统",
  "author": "LionLi",
  "license": "MIT",
  "scripts": {
    "dev": "vite serve --mode development",
    "build:prod": "vite build --mode production &&vue-tsc --noEmit",
    "preview": "vite preview",
    "lint": "eslint src/**/*.{ts,js,vue} --fix",
    "prepare": "husky install",
    "prettier": "prettier --write ."
  },
  "repository": {
    "type": "git",
    "url": "https://gitee.com/JavaLionLi/plus-ui.git"
  },
  "dependencies": {
    "@element-plus/icons-vue": "2.1.0",
    "@vueup/vue-quill": "1.2.0",
    "@vueuse/core": "9.5.0",
    "animate.css": "4.1.1",
    "await-to-js": "^3.0.0",
    "axios": "^1.3.4",
    "crypto-js": "^4.1.1",
    "echarts": "5.4.0",
    "element-plus": "2.2.27",
    "file-saver": "2.0.5",
    "fuse.js": "6.6.2",
    "js-cookie": "3.0.1",
    "jsencrypt": "3.3.1",
    "nprogress": "0.2.0",
    "path-browserify": "1.0.1",
    "path-to-regexp": "6.2.0",
    "pinia": "2.0.22",
    "postcss-px-to-viewport": "^1.1.1",
    "screenfull": "6.0.0",
    "vform3-builds": "3.0.8",
    "vue": "3.4.5",
    "vue-cropper": "1.0.3",
    "vue-i18n": "9.2.2",
    "vue-router": "4.1.4",
    "vue-types": "^5.0.3"
  },
  "devDependencies": {
    "@iconify/json": "^2.2.40",
    "@intlify/unplugin-vue-i18n": "0.8.2",
    "@kjgl77/datav-vue3": "^1.7.2",
    "@layui/layer-vue": "^2.2.2",
    "@layui/layui-vue": "^2.14.3",
    "@types/crypto-js": "^4.1.1",
    "@types/file-saver": "2.0.5",
    "@types/js-cookie": "3.0.3",
    "@types/node": "18.14.2",
    "@types/nprogress": "0.2.0",
    "@types/path-browserify": "^1.0.0",
    "@typescript-eslint/eslint-plugin": "5.56.0",
    "@typescript-eslint/parser": "5.56.0",
    "@unocss/preset-attributify": "^0.50.6",
    "@unocss/preset-icons": "^0.50.6",
    "@unocss/preset-uno": "^0.50.6",
    "@vitejs/plugin-vue": "4.0.0",
    "@vue/compiler-sfc": "3.2.45",
    "@vue/runtime-core": "^3.4.15",
    "eslint": "8.36.0",
    "eslint-config-prettier": "8.8.0",
    "eslint-plugin-prettier": "4.2.1",
    "eslint-plugin-vue": "9.9.0",
    "fast-glob": "^3.2.11",
    "husky": "7.0.4",
    "postcss": "^8.4.21",
    "prettier": "2.8.6",
    "sass": "1.56.1",
    "typescript": "^5.3.3",
    "unocss": "^0.50.6",
    "unplugin-auto-import": "0.13.0",
    "unplugin-icons": "0.15.1",
    "unplugin-vue-components": "0.23.0",
    "unplugin-vue-setup-extend-plus": "0.4.9",
    "vite": "4.3.1",
    "vite-plugin-compression": "0.5.1",
    "vite-plugin-svg-icons": "2.0.1",
    "vitest": "^0.29.7",
    "vue-eslint-parser": "9.1.0",
    "vue-tsc": "0.35.0",
    "vue3-seamless-scroll": "^2.0.1"
  }
}

Vue3的路由可以自动引入

插件 unplugin-vue-router

  • 安装插件
     npm install -D unplugin-vue-router
    
  • config.js中
    import { defineConfig } from 'vite';
    import vue from '@vitejs/plugin-vue';
    import VueRouter from 'unplugin-vue-router/vite';
     
    export default defineConfig({
      plugins: [
        VueRouter({ 
        routesFolder: "src/views" // 指定路由文件所在的目录
        /* options */ }),
        vue(),
        // ...其他插件
      ],
      // ...其他配置
    });
    
  • 配置路由
    import { createRouter, createWebHistory } from 'vue-router';
    import { routes } from 'vue-router/auto-routes';
     
    const router = createRouter({
      history: createWebHistory(),
      routes: routes, // 使用自动生成的路由
    });
     
    export default router;
    
  • 自动路由规则
    • unplugin-vue-router 会根据你 src/pages 目录下的组件文件自动创建路由。例如:
    • src/pages/index.vue 会自动对应到根路由
    • /src/pages/detail.vue 会自动创建路由 /detail。
    • 对于动态路由,如 src/pages/detail/[id].vue,会自动生成 /detail/:id 路由。
    • 此外,[…404].vue 文件会被用作 404 错误页面的路由。

在 hooks 中使用 router

import router from "@/router"

useRoute().path 和 proxy?.$router.currentRoute.value.path 不一样
路由匹配到异步组件时,组件的可能由于各种各样的原因(比如next(‘/login’)重定向了、或者网络原因加载不出来),vueRouter的history下的current要保证组件加载成功才会切换状态。

vue模板中的ts组件提示,会显示any或者unkonw或者TS2345缺少类型报错出现红色波浪线

在这里插入图片描述

修复: 关于vue模板中组件提示类型缺少属性声明
参考 https://gitee.com/dromara/RuoYi-Vue-Plus/issues/I8KW5F
vscode中,gitee下载的源代码,如果用 pnpm install命令安装,需要再自行安装runtime-core(执行命令:pnpm install -D @vue/runtime-core),版本号(3.2.45)与vue版本一致。install后重新打开项目解决问题。(据说用npm install安装不会出现该问题。)
问题主要原因:pnpm为了解决大量重复包安装和非法访问的问题,采用了扁平化依赖管理的方案,因为runtime-core是vue的一个子包,所以他的层级结构被改变了,按原来的@vue/runtime-core这种写法是无法访问到的。
将 @vue/runtime-core 该成 vue

在这里插入图片描述
正常提示组件了!!!
在这里插入图片描述
其次 也有可能是 volar 插件版本的原因,安装另一版本重启就行

多层级动态路由嵌套 页面显示使用同一个 router-view

比如二级目录可点击显示页面,二级目录下子菜单点击显示页面
需要给目录级路由重定向到目录下的某一子菜单,然后该菜单隐藏,并且 目录的component 需要为router-view

  • 点击目录访问时的路由地址为 crane/index
  • 点击目录下菜单访问的路由地址为 crane/deep
//src/components/ParentView/index.vue
<template>
 <router-view />
</template>

动态路由结构
{
“name”: “Crane”,
“path”: “crane”,
“hidden”: false,
“redirect”: “/screen/crane/index”,
“component”: {src/components/ParentView/index.vue" }, //注意 需要为router-view
“query”: “{“type”:“city”}”,
“alwaysShow”: true,
“meta”: {
“title”: “起重设备”,
“icon”: “”,
“noCache”: false,
“link”: null
},
“children”: [
{
“name”: “Index”,
“path”: “index”,
“hidden”: true, // 隐藏菜单,但可正常访问,不是删除
“meta”: {
“title”: “index(二级目录,需要隐藏的菜单)”,
“icon”: “”,
“noCache”: false,
“link”: null
}
},
{
“name”: “Deep”,
“path”: “deep”,
“hidden”: false,
“meta”: {
“title”: “菜单Deep”,
“icon”: “”,
“noCache”: false,
“link”: null
}
}
]
}

echarts: 使用定时器给图表添加一些动作时,切换页面后控制台多条警告

需要在切换/关闭/销毁页面时清除定时器,或者在store中记录下,使用时清除上一次的定时器
我使用echarts图表的是在hooks中定义的,直接写在每一个抛出的hook中
onUnmounted(() => {
// console.log(“页面关闭.定时器清除”);
if (timerInterval) {
clearInterval(timerInterval)
}
});

flex 和gird 布局 子元素换行后靠左对齐

参考:https://blog.csdn.net/weixin_45559449/article/details/129653091

// flex布局
ul {
    width: 100%;
    padding: 0;
    margin: 0;
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}

li {
    width: 30%;
    height: 100px;
    border-radius: 4px;
    margin-bottom: 20px;
    border: 1px solid rgb(167, 182, 240);
}
// 三列布局
ul>li:last-child:nth-child(3n - 1) {
    margin-right: calc(10% / 2 + 30%)
}
// 或者 外层容器给弹性盒子布局, 且给外层盒子一个after伪类元素。
// ul::after {
//     content: "";
//     width: 30%;
//     height: 0;
//     visibility: hidden;
// }
// gird 布局
ul {
    width: 100%;
    height: 200px;
    //子元素 宽 ,上下/左右间距,展示几列
   display: grid;
    //第一个属性:行与行间隔,第二个属性列与列间隔
    grid-gap: 20px 20px;
    //内容整体平均分布
    justify-content: space-between;
    //单元格的大小是固定的,但是容器的大小不确定。
    //如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用auto-fill关键字表示自动填充
    grid-template-columns: repeat(auto-fill, 200px);
}

li {
    width: 200px;
    height: 100px;
    border: 1px solid rgb(167, 182, 240);
}

vue3批量导入组件

  • 使用 <component :is="componentName"></component>
import { defineAsyncComponent } from "vue";
//引入组件
const comActiveName = ref("general");
const modules = import.meta.glob("./reviewCom/*.vue");
let comps: any = {};
for (const path in modules) {
    let cname = path.replace(/\.\/reviewCom\//, "").replace(".vue", "");
    // @ts-ignore
    comps[cname] = defineAsyncComponent(modules[path]);
}
  • 在reivew.vue中引入同级reviewCom文件夹下所有的.vue文件
    在reivew.vue中引入reviewCom文件夹下所有的.vue文件

vue3 模板内有多个根元素,切换路由时白屏,需重新刷新页面才显示内容

  • 可能是keepaliive导致
  • 解决:在keepalive下用div包裹一层
  • 在这里插入图片描述

el-tree 新增节点后,全量刷新数据后,让指定节点展开并显示新增节点

<el-tree
    ref="treeRef"
    :data="treeList"
    :props="defaultProps"
    node-key="id"
    accordion
    :expand-on-click-node="false"
    :highlight-current="true"
    :default-expanded-keys="[0]"
    @node-click="handleNodeClick"
></el-tree>
// 树配置信息
const defaultProps = {
    children: "children",
    label: "catalogueName",
    //false 有 true 无
    isLeaf: (data: { hasChild: number }, node: any) => {
        //是否存在子级1 有0无
        if (data.hasChild === 1) {
            return false;
        } else {
            return true;
        }
    },
};
//dom实例
const treeRef = ref<InstanceType<typeof ElTree>>();
// 被点击的节点
const treeNodeData = ref<any>({});
// 树中选中某一节点
async function handleNodeClick(row: any, Node: any) {
    treeNodeData.value = row;
}

//展开指定节点
 const expandNode=()=>{
	const node: any = treeRef.value?.getNode(treeNodeData.value.id);
	        // 已经展开, 有其他子节点
	        node.expanded = false;
	        //全量获取树
	        const res = await proxy?.$hdy_request({
	            url: "",
	            method: "get",
	            params: {
	                pid: node.data.id,
	            },
	        });
	        treeList.value = res.data;
	        setTimeout(() => {
	            //tree的key为数据id
	            treeRef.value?.setCurrentKey(node.data.id);
	            node.isCurrent = true;
	            node.store.currentNode.expand();
	        }, 500);
	}
  
  //删除节点
	const  deleteNode=(row)=>{
	 const node = treeRef.value?.getNode(row.id);
	     if (node) {
	         //动态移除树节点
	         const parent = node.parent;
	         const index = parent.childNodes.findIndex((d) => d.data.id === row.id);
	         if (index !== -1) {
	             treeRef.value?.remove(node);
	             node.expand();
	             if (parent.data.hasChild === 0) {
	                 //重置为true:无子节点,隐藏左侧展开按钮
	                 parent.isLeaf = true;
	             }
	         }
	     }
	}

vue2.x /vue3.x style标签中使用script中的响应式数据作为变量

vue2.x

<template>
  <h1>Vue</h1>
</template>
 
<script>
export default {
  data () {
    return {
      opacity: 0
    }
  },
  mounted () {
    setInterval(_ => {
      this.opacity >= 1 && (this.opacity = 0)
      this.opacity += 0.2
    }, 300)
  }
}
</script>
 
<style vars="{ opacity }">
h1 {
  color: rgb(65, 184, 131);
  opacity: var(--opacity);
}
vue3.x
  • ** 如果响应式数据是个对象的话,v-bind内的引用需要添加引号**
<template>
  <h1> shit! </h1>
</template>
 
<script>
export default {
  data () {
    return {
      color: 'yellow',
      font: {
      	   weight: 100
       },
    }
  }
}
</script>
 
<style>
h1 {
  color: v-bind(color);
  font-weight: v-bind('font.weight');
}
</style>

setup中 顶层 await

如果使用await setup前面会自动加一个async
const data = await fetch(“”)

解决Vue3.0以上+Vite项目打包后低版本浏览器兼容性问题

在这里插入图片描述

@vitejs/plugin-legacy插件,在打包过程中做了什么 ? 转载链接

打包过程中使用@babel/preset-env转换浏览器不支持的语法和新API,为包中的每个块生成相应的转化块;
生成一个包含 SystemJS 运行时的polyfill块;
在打包文件中生成带有legacy名的文件,每个js脚本文件都有一个与其对应的转化版本;
html文件中新增了一些script-nomodule脚本,这些脚本根据浏览器的支持程度来动态的引入正常版本文件还是带有legacy字样的转化版本文件

官方解决方案:使用@vitejs/plugin-legacy插件

传统浏览器可以通过插件 @vitejs/plugin-legacy 来支持

  • 安装插件
pnpm i @vitejs/plugin-legacy -D
pnpm i  terser  -D
引入Unocss后项目运行报错,不支持使用require()

- require() of ES Module D:\0-workspace\myCode\kong-blog\node_modules\unocss\dist\vite.mjs not supported.

  • 版本问题,unocss版本为0.60,降至0.58,报错解决
项目打包,内存溢出,设置最大值后仍然溢出,是nodejs安装包版本和电脑系统版本不对应的问题
  • 下载与电脑系统对应的版本 ,x64对应x64
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值