使用 Vue 3 时应避免的 10 个错误

标签: vue.js | 发表时间:2023-03-10 06:52 | 作者:chuck
出处:https://segmentfault.com/blogs

Vue 3已经稳定了相当长一段时间了。许多代码库都在生产环境中使用它,其他人最终都将不得不迁移到Vue 3。我现在有机会使用它并记录了我的错误,下面这些错误你可能想要避免。

使用Reactive声明原始值

数据声明在过去都是非常直接的,但是现在有很多帮助函数供我们使用。目前的规则是:

  • 使用 reactive声明 Object, Array, Map, Set
  • 使用 ref声明 String, Number, Boolean

为一个原始值使用 reactive会返回一个警告,并且该值不会成为可响应式数据。

  /* DOES NOT WORK AS EXPECTED */
<script setup>
import { reactive } from "vue";

const count = reactive(0);
</script>

矛盾的是,另一种方式是可行的。例如,使用 ref来声明一个 Array会在内部调用 reactive

解构响应式数据

假设你有一个响应式对象拥有 count属性,并且有一个按钮来递增 count

  <template>
  Counter: {{ state.count }}
  <button @click="add">Increase</button>
</template>

<script>
import { reactive } from "vue";
export default {
  setup() {
    const state = reactive({ count: 0 });

    function add() {
      state.count++;
    }

    return {
      state,
      add,
    };
  },
};
</script>

上述逻辑相当直接,而且如预期的那样工作,但你可能会利用javascript的解构来做以下事情:

  /* DOES NOT WORK AS EXPECTED */
<template>
  <div>Counter: {{ count }}</div>
  <button @click="add">Increase</button>
</template>

<script>
import { reactive } from "vue";
export default {
  setup() {
    const state = reactive({ count: 0 });

    function add() {
      state.count++;
    }

    return {
      ...state,
      add,
    };
  },
};
</script>

代码看起来是一样的,而且根据我们以前的经验应该是可行的,但事实上,Vue的响应式跟踪是通过属性访问进行的。这意味着我们不能赋值或解构一个响应式对象,因为与第一个引用的响应式连接已经断开。这就是使用响应式帮助函数的局限性之一。

对.value感到困惑

同样的,使用 ref的一个怪异模式可能也很难习惯。

Ref接收一个值,并返回响应式对象。该值在对象内部的 .value属性下可用。

  const count = ref(0)

console.log(count) // { value: 0 }
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

但是 ref在模板文件中使用时会被解包,并且不需要 .value

  <script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <button @click="increment">
    {{ count }} // no .value needed
  </button>
</template>

但是要小心了!解包只在顶级属性中生效。下面的代码片段会生成 [object Object]

  // DON'T DO THIS
<script setup>
import { ref } from 'vue'

const object = { foo: ref(1) }

</script>

<template>
  {{ object.foo + 1 }}  // [object Object]
</template>

正确地使用 .value需要时间。尽管某些时候我会忘记如何使用,但是使用它的频率越来越高。

触发事件

自从Vue的最初发布以来,子组件就可以与父组件使用 emit来通信。你只需要添加自定义事件监听器来监听一个事件。

  // 子组件
this.$emit('my-event')

// 父组件
<my-component @my-event="doSomething" />

现在, emit需要使用 defineEmits来进行声明。

  <script setup>
const emit = defineEmits(['my-event'])
emit('my-event')
</script>

另一件要记住的事情是, defineEmitsdefineProps都不需要被导入。它们在使用 script setup时自动可用。

  <script setup>
const props = defineProps({
  foo: String
})

const emit = defineEmits(['change', 'delete'])
// setup code
</script>

最后,由于事件现在必须被声明,所以不需要使用 .native修饰符,事实上它已经被移除了。

声明附加选项

Options API方法有几个属性在 script setup中是不被支持的。

  • name
  • inheritAttrs
  • 插件或库所需的自定义选项

解决办法是按照 script setupRFC的 定义,在同一个组件中设置两个不同的脚本。

  <script>
  export default {
    name: 'CustomName',
    inheritAttrs: false,
    customOptions: {}
  }
</script>

<script setup>
  // script setup logic
</script>

使用响应式转换

Reactivity Transform是Vue 3的一个 实验性但有争议的功能,目的是简化组件的声明方式。它的想法是利用编译时的转换来自动解包一个 ref,并使 .value过时。但现在它被放弃了,并将在Vue 3.3中被删除。它仍然可以作为一个包使用,但由于它不是Vue核心的一部分,所以最好不要在它身上投入时间。

定义异步组件

以前的异步组件是通过将其包含在一个函数中来声明的。

  const asyncModal = () => import('./Modal.vue')

从 Vue 3开始,异步组件需要使用 defineAsyncComponent帮助函数来显式地定义。

  import { defineAsyncComponent } from 'vue'

const asyncModal = defineAsyncComponent(() => import('./Modal.vue'))

在模板中使用多余的包裹元素

在Vue 2中,组件模板需要一个单一的根元素,这有时会引入不必要的包裹元素。

  <!-- Layout.vue -->
<template>
  <div>
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  </div>
</template>

现在不再需要这样了,因为现在支持多个根元素。

  <!-- Layout.vue -->
<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>

使用错误的生命周期

所有的组件生命周期事件都被重新命名,要么添加 on前缀,要么完全改变名称。你可以在下面的图表中查看所有的变化。

Lifecycle Event.png

不看文档

最后,官方文档已经进行了修改以反映新的API,并包括许多有价值的说明、指南和最佳实践。即使你是一个经验丰富的Vue 2工程师,你也一定会通过阅读文档学到一些新东西。

总结

每个框架都有一个学习曲线,而Vue 3的学习曲线无疑比Vue 2的更陡峭。我仍然不相信两个版本之间的迁移工作是合理的,但组合式API要整洁得多,在你掌握了它之后会感觉很自然。

最后,请记住:

犯错比什么都不做要好得多。

Making mistakes is a lot better than not doing anything.

以上就是本文的全部内容。如果对你有所帮助,欢迎点赞、收藏、转发~

相关 [vue 错误] 推荐:

使用 Vue 3 时应避免的 10 个错误

- - SegmentFault 最新的文章
Vue 3已经稳定了相当长一段时间了. 许多代码库都在生产环境中使用它,其他人最终都将不得不迁移到Vue 3. 我现在有机会使用它并记录了我的错误,下面这些错误你可能想要避免. 使用Reactive声明原始值. 数据声明在过去都是非常直接的,但是现在有很多帮助函数供我们使用. 使用 reactive声明 Object, Array, Map, Set.

ssr vuejs/vue-hackernews-2.0: HackerNews clone built with Vue 2.0, vue-router & vuex, with server-side rendering

- -
This is a demo primarily aimed at explaining how to build a server-side rendered Vue app, as a companion to our SSR documentation. #install dependenciesnpm install#or yarn#serve in dev mode, with hot reload at localhost:8080npm run dev#build for productionnpm run build#serve in production modenpm start.

Vue 移动端框架

- - IT瘾-jianshu
vonic 一个基于 vue.js 和 ionic 样式的 UI 框架,用于快速构建移动端单页应用,很简约. 中文文档| github地址| 在线预览. vux 基于WeUI和Vue(2.x)开发的移动端UI组件库. 基于webpack+vue-loader+vux可以快速开发移动端页面,配合vux-loader方便你在WeUI的基础上定制需要的样式.

vue路由权限校验

- - 掘金前端
做后台系统的时候,难免会有用户权限的判断. admin可以查看全部菜单,user只能查看部分菜单. 一开始接触这个需求的时候,完全是纯前端做的. 在配置路由的时候,加一个roles的属性,通过判断用户的roles是否与路由的roles属性相匹配来作为显示隐藏的依据. // 过滤路由 menuList-菜单 roles-用户角色 const checkMenuList = (menuList, roles) => { for (let i = 0; i < menuList.length; i++) {.

微豆 - Vue 2.0 实现豆瓣 Web App 教程

- - SegmentFault 最新的文章
一个使用 Vue.js 与 Material Design 重构 豆瓣 的项目. 项目网站 http://vdo.ralfz.com/. # 克隆项目到本地 git clone https://github.com/RalfZhang/Vdo.git # 安装依赖 npm install # 在 localhost:8080 启动项目 npm run dev.

浅谈Vue组件在实际项目中的应用

- - JDC | 京东设计中心
Vue.js 是一套构建用户界面的渐进式框架,目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件. 虽然目前 Vue 已经很火了,但不可否认的是,仍有很多人刚刚开始学习使用 Vue 来构建前端项目,从生疏的初学者到熟练运用 Vue 的过程中,不可避免地会走一些弯路. 为了实现某个功能,也许尝试过很多方法,最终蓦然回首,才发现当初犯下的错误是那么幼稚.

vue快速入门的三个小实例

- - SegmentFault 最新的文章
用vue做项目也有一段时间了,之前也是写过关于vue和webpack构建项目的相关文章,大家有兴趣可以去看下 webpack+vue项目实战(一,搭建运行环境和相关配置)(这个系列一共有5篇文章,这是第一篇,其它几篇文章链接就不贴了). 但是关于vue入门基础的文章,我还没有写过,那么今天就写vue入门的三个小实例,这三个小实例是我刚接触vue的时候的练手作品,难度从很简单到简单,都是入门级的.

vue父子组件通信高级用法

- - SegmentFault 最新的文章
vue项目的一大亮点就是组件化. 使用组件可以极大地提高项目中代码的复用率,减少代码量. 但是使用组件最大的难点就是父子组件之间的通信. . . // 参数就是子组件传递出来的数据.

Vue 组件数据通信方案总结

- - IT瘾-dev
(给前端大全加星标,提升前端技能). 作者:政采云前端团队 公号 / 季节 (本文来自作者投稿). 初识 Vue.js ,了解到组件是 Vue 的主要构成部分,但组件内部的作用域是相对独立的部分,组件之间的关系一般如下图:. 组件 A 与组件 B 、C 之间是父子组件,组件 B 、C 之间是兄弟组件,而组件 A 、D 之间是隔代的关系.

vue 文件多了, webpack 热加载很慢? - V2EX

- -
点我最近刚好在看 webpack,如果楼主时间多可以去我博客看一下 webpack 相关的三篇文章,不要脸的放一下博客. 如果时间不够只是想解决这个问题,那么我尝试正儿八经回答一下. 1.把 webpack 升级到 4.0. 3.使用 DLLplugin,happypack 等构建加速插件. 4.检查 loader/eslint 是否配置错误 /不合理.