向歆纪

Vue3 及相关生态问题

有 N 人看过
  • 不支持纯方法的异步组件
  • Vue-router 4.0 不能使用通配符问题
  • store , 状态,方法, setup 返回状态丢失
  • Element-Plus el-table-columns 使用插槽并且使用自定义指令导致警告 (新版本已经修复)
  • 路由匹配不到页面(Vue3新特性Fragment)
  • 使用JS生产APP进行挂载,导致组件加载失败,并且报错 created not defined
  • 使用 Computed 去取得 ref 组件,导致获取出来的状态在某种情况下被缓存
  • setup script 给组件定义 name
  • setup script 使用 component 找不到 import 的组件
  • watch route 导致生产环境崩溃

不支持纯方法的异步组件

之前定义异步组件或者是异步加载一个组件可以这个组件为一个纯函数,里面使用了 webpack 的 require 方法 ,如下:

(resolve) => require([`@/views/${view}`], resolve)

现在Vue3 应该是吧这个标准统一化了, 全部使用 return new Promise 的标准

() => new Promise((resolve) => {
    require([`@/views${c}.vue`], resolve);
})

Vue-router 4.0 不能使用通配符问题

{
    // 匹配所有路径  vue2使用*   vue3使用/:pathMatch(.*)*或/:pathMatch(.*)或/:catchAll(.*)
    path: "/:pathMatch(.*)*",
        name
:
    "404",
        component
:
    () => import("../components/NoFind.vue")
}

原因:Vue Router不再使用path-to-regexp,而是实现了自己的解析系统,该系统允许路由排名并启用动态路由。由于我们通常会在每个项目中添加一条单独的包罗万象的路线,因此支持的特殊语法没有太大的好处*
。参数的编码是跨路线编码,无一例外使事情更容易预测。

store , 状态,方法, setup 返回状态丢失

原因:未知 尝试整改方案 ,从 js 定义中的状态进行抽离, 特别是 Ref 和 store . 另外 使用 useStore 请在组件的 setup 方法进行使用

路由匹配不到页面(Vue3新特性Fragment)

在vue3 引入了一个新特性, Fragment , 这个特性可以让我们的组件有多个根节点, 但是 因为这个特性跟 vue-router 有冲突, 可能是因为 vue 做了这方面的处理, vue-router 还没有处理 Fragment.
所以在页面上也最好不要使用Fragment 特性

之后继续确保页面组件只有一个根节点就行了

使用 Computed 去取得 ref 组件,导致获取出来的状态在某种情况下被缓存

触发如下:
A 组件 —> B 组件
我A组件调用了 B组件, 并且这个 B组件是使用了 v-if 控制的 ,而且我在 A组件的 computed 计算了这个 B组件的ref , 之后我使用computed 计算出来的 ref 调用 B组件的方法

{
    computed : {
        formRef()
        {
            return this.$refs.numberForms
        }
    ,
    }
,
    methods : {
        run()
        {
            const data = this.formRef.getValue()
        }
    }
}

此时这个data 组件创建销毁之后 ref 被缓存起来了, 就导致获取出来的状态是可能之前已经销毁了的ref 状态 解决方案: 使用 this.$refs 去取得组件实例

setup script 给组件定义 name

在 vue3 中可以使用 setup script 来进行 setup 操作 , 但是在之前我们定义一个组件的名称都是直接使用name 字段 如下

export default {name: 'ComponentName'}

由于setup script 不需要 export default , 所以组件名称也不能定义.

解决方案1 : 改造现有代码,将setup script 转换成 export default / export default defineComponent({})

解决方案2 : 增加一个 script 块 , 在里面定义 export default { name : ‘Component’}

如下:


<script setup>
// .... 
</script>
<script>
export default {
  name: 'xxx'
}
</script>

setup script 使用 component 找不到 import 的组件

如果一个组件是使用的 setup script 并且其中使用了 component :is 去结合动态组件, 那么 setup 里面引入的 component 是无效的. 解决办法也只能将现有代码进行重构

export default defineComponent({
    components: {
        // ... 显式注册
    }
})

watch route 导致生产环境崩溃

之前有遇到这个问题 就是因为代码中 有一句

const route = useRoute()
watch(() => route, v => {
    // .... 
})

生产环境直接崩溃, 在开发环境没问题 , 解决他就是监听某个具体的属性 , 比如下

const route = useRoute()
watch(() => route.path, v => {
    // .... 
})