• vue3+ts 项目遇到的问题和bug


    1.router中使用pinia报错

    在这里插入图片描述

    pinia.mjs:1709 Uncaught Error: [🍍]: "getActivePinia()" was called but there was no active Pinia. Are you trying to use a store before calling "app.use(pinia)"?
    See https://pinia.vuejs.org/core-concepts/outside-component-usage.html for help.
    This will fail in production.
        at useStore (pinia.mjs:1709:19)
        at index.ts:6:15
    
    • 1
    • 2
    • 3
    • 4
    • 5

    分析原因:因为在mian.js中,注册router总比pinia先,所以不能使用到store/index.js文件中createPinia方法

    解决方法:把store实例化放到路由守卫函数里面

    import { createRouter } from 'vue-router'
    const router = createRouter({
      // ...
    })
    
    // ❌ 由于引入顺序的问题,这将失败
    const store = useStore()
    
    router.beforeEach((to, from, next) => {
      // 我们想要在这里使用 store
      if (store.isLoggedIn) next()
      else next('/login')
    })
    
    router.beforeEach((to) => {
      // ✅ 这样做是可行的,因为路由器是在其被安装之后开始导航的,
      // 而此时 Pinia 也已经被安装。
      const store = useStore()
    
      if (to.meta.requiresAuth && !store.isLoggedIn) return '/login'
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    参考:
    添加链接描述
    pinia

    2.路由报错

    在这里插入图片描述

    vue-router.mjs:35 [Vue Router warn]: No match found for location with path "/"
    warn @ vue-router.mjs:35
    显示另外 1 个框架
    收起
    
    • 1
    • 2
    • 3
    • 4

    参考:
    https://blog.csdn.net/weixin_45952652/article/details/131192829

    https://blog.csdn.net/m0_64344940/article/details/130710796

    3.vue 样式穿透

    [@vue/compiler-sfc] ::v-deep usage as a combinator has been deprecated. Use :deep(<inner-selector>) instead of ::v-deep <inner-selector>.
    
    • 1

    在这里插入图片描述
    把::v-deep 替换为 :deep()
    在这里插入图片描述

    参考:
    https://blog.csdn.net/weixin_43405300/article/details/132099608

    4.defineProps is a compiler macro and no longer needs to be imported

    [@vue/compiler-sfc] `defineProps` is a compiler macro and no longer needs to be imported.
    
    • 1

    在这里插入图片描述
    [@vue/compiler sfc]defineEmits是一个编译器宏,不再需要导入。

    [@vue/compiler sfc]`defineProps’是一个编译器宏,不再需要导入。

    文件里把这两个引用去掉即可

    import { defineEmits, defineProps, computed } from 'vue'
    改为
    import {  computed } from 'vue'
    
    • 1
    • 2
    • 3

    5.前端什么时候使用formdata

    学习项目时发现封装了一个上传hook:
    用于上传表单数据,

    import axios from "axios";
    
    function upload(path: string, userForm: any) {
        const params = new FormData()
        for (const i in userForm) {
            params.append(i, userForm[i])
        }
        // console.log(params)
        return axios.post(path, params, {
            headers: {
                "Content-Type": "multipart/form-data"
            }
        }).then(res => res.data)
    }
    
    export default upload
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    那么new FormData()的作用是什么,为什么要用?

    new FormData() 是 JavaScript 中的一个构造函数,用于创建新的 FormData 对象。FormData 对象用于存储键值对,并且可以模拟表单数据(表单元素和它们的值)的序列化。

    需要发送二进制数据或大文件时,使用FormData非常有用

    “Content-Type” 是一个 HTTP 请求头,它告诉服务器发送过来的数据是什么类型。在这种情况下,“multipart/form-data” 是一种编码类型,用于发送表单数据。这种编码类型常常用于发送包含文件上传的表单数据,因为它可以处理二进制数据和非文本数据。

    常见的 Content-Type 头字段有以下几种:
    application/json:用于表示 JSON 格式的数据。
    application/xml:用于表示 XML 格式的数据。
    text/plain:用于表示纯文本数据。
    text/css:用于表示 CSS 样式表。
    image/png、image/jpeg、image/gif 等:用于表示图片数据。
    audio/mpeg、audio/mp3、audio/wav 等:用于表示音频数据。
    video/mp4、video/webm、video/ogg 等:用于表示视频数据。
    multipart/form-data:用于表示 Multipart/form-data 格式的数据,常用于文件上传。
    application/x-www-form-urlencoded:用于表示 URL 编码的表单数据。

    6.路由守卫中设置网页title

    在这里插入图片描述
    在路由中设置meta增加title

    const routes = [  
      {  
        path: '/',  
        component: Home,  
        meta: { title: '首页' }  
      },  
      {  
        path: '/about',  
        component: About,  
        meta: { title: '关于我们' }  
      }  
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在路由守卫中设置标题

    import Vue from 'vue';  
    import Router from 'vue-router';  
      
    Vue.use(Router);  
      
    const router = new Router({  
      routes,  
      // 在这里添加路由守卫来设置标题  
      beforeEach(to, from, next) {  
        document.title = to.meta.title; // 设置页面标题为当前路由的 meta.title  
        next(); // 一定要调用 next() 方法,否则路由不会继续导航  
      }  
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    Vue Router中meta属性如下:

    属性名作用
    title设置页面的标题,用于显示在浏览器标签页上
    description为路由提供一个简短的描述,可用于SEO优化和搜索引擎结果描述
    params定义路由参数,用于在路由组件中获取和使用这些参数
    redirect重定向到另一个路由,当用户访问当前路由时,直接跳转到指定的路由
    props控制路由组件的props是否可以被子路由继承
    alias设置当前路由的别名,方便进行路由导航和URL管理
    children定义当前路由的子路由,用于组织嵌套路由
    index定义路由的初始组件,当访问该路由时,首先显示该组件
    controller自定义路由的控制器,用于处理路由导航和渲染组件的逻辑
    meta自定义元信息,可以在路由守卫、导航钩子等地方获取并使用这些信息

    7.路由报错:main.ts:21 [Vue Router warn]: No match found for location with path “/user-manage/userlist”

    在这里插入图片描述

    VUE3中路由采用动态加载的模式下,当我们在当前页面刷新浏览器时,会出现这样一个警告
    警告的意思是提示当前路由并不存在,刷新时此路由确实不存在

    参考:https://blog.csdn.net/maoeye283301717/article/details/126482974

    8.vue router中useRouter()和useRoute()有什么区别?

    函数作用应用场景
    useRouter()返回一个路由实例对象,提供对路由的全局操作方法,例如 push()、replace()、go() 等在组件中直接访问路由实例,并执行路由跳转等操作
    useRoute()返回一个路由对象,代表当前路由的状态和信息根据当前路由的状态来动态地渲染内容或执行其他操作

    useRouter()使用:

    import { useRouter } from 'vue-router';  
      
    function MyComponent() {  
      const router = useRouter();  
      
      // 使用路由器实例的方法进行导航  
      router.push('/path/to/redirect');  
      
      // 访问路由器的位置信息  
      console.log(router.location);  
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    useRoute()使用:

    import { useRoute } from 'vue-router';  
      
    function MyComponent() {  
      const route = useRoute();  
      
      // 获取当前路由的路径  
      console.log(route.path);  
      
      // 获取URL参数  
      console.log(route.params);  
      
      // 获取查询参数  
      console.log(route.query);  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    使用useRouter()获取路由实例,并使用useRoute()获取当前路由对象。
    通过router.push()方法执行路由跳转,
    通过route.path属性获取当前路由路径。

    9.

  • 相关阅读:
    键盘的事件
    二十种实战调优MySQL性能优化的经验
    [论文阅读]Coordinate Attention for Efficient Mobile Network Design
    13.罗马数字转整数
    计算机毕业设计Java鲜花订购网微服务(源码+系统+mysql数据库+Lw文档)
    Javaweb之javascript的详细解析
    如何利用exceljs将data数据导出表格实现日期去重,同时保留对应日期的每一列数据
    leetcode题型分析《数组》
    v3 + ts 商城项目的支付模块
    客户服务质量提升的三种思路
  • 原文地址:https://blog.csdn.net/wusandaofwy/article/details/134245332