前言

vue3在2022年的2月7号成为了vue默认版本,并且随之而来的还有vue3的新文档, 并且从实际使用的角度来说, vue3确实比vue2使用起来更加的舒服,所以觉得经过一段时间的使用,来分享一下使用过程中的小技巧以及注意事项。

小技巧

关于减少.value的使用

  • 使用watch来监听Ref数据的时候, 可以做到省略.value的使用, 例如:

      const value = ref(1);
      // 省略() => value.value
      watch(value, (v) => {
        // 省略v.value
        console.log(v);
      }, { immediate: true });
    
      setTimeout(() => {
        value.value = 2;
      }, 1000);
  • 使用vue3.2.25以上版本提供的$ref, 还是跟上面的代码实现一样的功能

    该功能是一个实验性能, 需要相应的配置, 这里以vite为例, 需要在vite.config.ts的vue plugin中添加一个reactivityTransform属性, 请看下面的配置。如果用的是其他工程化工具, 可以参考vue的新文档, 文档中有详细的说明。

      plugins: [
        vue({
          reactivityTransform: true,
        })
      ]
      const count = $ref(1);
      // 增加了() => count
      watch(
        () => count,
        (v) => {
          console.log(v);
        },
        { immediate: true }
      );
    
      setTimeout(() => {
        // 省略了count.value
        count  ;
      }, 1000);

输出:

这里需要说明一下使用$ref需要注意的问题, 首先该功能是一个实验性性能, 需要相应的配置, 并且vue的文档中指出该方法是一个编译器宏使用时无需引入, 但为了ts和编辑器的无端报错, 个人还是喜欢显示的引入, 就像这样import { $ref } from 'vue/macros'接着再说一下$ref的另一个很严重的问题, 就是丢失响应式, 为什么会丢失响应式呢? 其实这部分官方文档已经做出了说明, 请看下面的代码

// App.vue
import { $ref } from "vue/macros";
import { useApp } from "./App";
let count = $ref(1);

useApp(count);

setTimeout(() => {
  console.log("change");
  count  ;
}, 1500);

// App.ts
import { watch } from "vue";
export const useApp = (count) => {
  watch(
    () => count,
    (c) => {
      console.log("watch", c);
    },
    { immediate: true }
  );
};

上面代码中App.ts里面的watch只会执行一次, 很明显, count丢失了响应性
如何解决这个问题呢?请看下面的代码:

// App.vue
import { $ref, $$ } from "vue/macros"; // 引入$$
import { useApp } from "./App";
let count = $ref(1);

useApp($$(count)); // useApp(count) --> useApp($$(count))

setTimeout(() => {
  console.log("change");
  count  ;
}, 1500);

// App.ts
import { watch } from "vue";
export const useApp = (count) => {
  watch(
    count, // () => count --> count
    (c) => {
      console.log("watch", c);
    },
    { immediate: true }
  );
};

可以看到, 我们在传递$ref值的时候 需要用一个$$方法包裹一下, 这样就不会丢失响应性了, 具体更详细的使用方法, 还是希望大家仔细阅读一下vue的新文档

关于减少import导入语句

发现这个功能是无意间的,在使用element-plus的时候, 查看elment-plus官网 指南 快速开始, 其中提到了自动导入的功能, 文档中说的是 首先下载对应的插件npm install -D unplugin-vue-components unplugin-auto-import, 然后如果使用的是vite的话, 需要在vite.config中添加几条配置, 就像下面一样:

// vite.config.ts
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

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

因为好奇去看了这两个包的介绍, 发现不光可以自动导入组件, 还可以自动导入方法, 例如心细的小伙伴已经发现, .value那部分的代码 不管是ref还是$ref我都没有写import语句来导入, 这里就用到了这两个插件, 我们来看一下如果要自动导入vue的方法对应的配置。

// vite.config.ts
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default {
  plugins: [
    // ...
    AutoImport({
      imports: ["vue", "vue/macros"],  // 增加这一行代码
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
}

在这样的配置下就可以愉快的减少import导入了。

关于在script setup中声明组件名字

在script setup的方式刚发布的时候, 我就一直在纠结这个问题, 因为项目中有很多的递归组件, 如果没有name来做标识的话, 势必会产生问题

  • 刚开始vue的issues中其他用户提出的解决方式是在.vue文件中定义两个script标签, 其中一个用来定义组件的name, 而另一个用来编写组件逻辑, 例如下面这样:

这种方式相信对于一些有强迫症或者完美主义者来说是完全不能接受的, 包括我 也不能接受, 所以在vue的issues中就有一个用户开发了一个插件来解决这个问题。

  • unplugin-vue-define-options插件

下载插件npm i unplugin-vue-define-options -D我们直接来看一下这个插件的使用方式:

在vite中使用

// vite.config.ts
import DefineOptions from 'unplugin-vue-define-options/vite'
import Vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [Vue(), DefineOptions()],
})

ts项目需要在tsconfig.json中添加一个配置

{
  "compilerOptions": {
    "types": ["unplugin-vue-define-options"]
  }
}

使用方式

<script setup lang="ts">
  defineOptions({
    name: 'App'
  })
</script>

该插件的功能远远不止定义组件的name, 还可以定义组件的props、emits、render等,有兴趣的小伙伴可以去看一下,感觉可以利用这一特性才做一些骚操作,不过尤大大觉得这种方式不太好。

注意事项

关于响应式的问题

  • props不能使用解构的方式来使用, 例如下面的例子
  // Parent.vue
  <template>
    <ChildVue ref="childRef" v-bind="data" />
  </template>
  
  <script setup lang="ts">
    import { reactive } from 'vue';
    import ChildVue from "./views/Child.vue";
    const data = reactive({ name: 'veloma' });
    setTimeout(() => {
      data.name = 'timer';
    }, 1500);
  </script>

  // Child.vue
  <template>
    <div>{{ data.name }}</div>
  </template>

  <script lang="ts" setup>
    const props = defineProps<{
      name: string;
    }>();
    const data = reactive({ ...props });
  </script>

上面的例子在子组件中, 通过reactive将props进行了解构, Parent组件中1.5s后更新name, 这时我们会发现Child组件中的模板并不会产生更新, 那如何来解决这个问题呢?
首先有两种解决方式:

1.使用3.2.25或以上的版本直接解构defineProps, 例如这样 const { name } = defineProps<{ name: string }>()

2.或者通过computed来解构, 例如 const data = computed(() => ({ ...props }))

模板循环中加不加key的问题

关于这个问题, 在vue新文档中有提到这样一句话

只看这句话的话是没有任何问题的,但在实际的使用过程中, 举个🌰:

    // Parent.vue
    <template>
      <div>
        <ChildVue v-for="item of list" v-bind="item"></ChildVue>

        <button @click="onClick">按钮</button>
      </div>
    </template>
    <script setup lang="ts">
      import { ref } from "vue";
      import ChildVue from "./views/Child.vue";

      const list = ref([{ name: "veloma" }, { name: "timer" }, { name: "lucy" }]);

      const onClick = () => {
        console.log('点击');
        const item = { ...list.value[0] };
        item.name = "veloma1111";
 
        list.value[0] = item;
     };
    </script>
    
    // Child.vue
    <template>
      <div>{{ name }}</div>
    </template>

    <script lang="ts" setup>
      import { onMounted } from "vue";

      defineProps<{
        name: string;
      }>();

      onMounted(() => {
        console.log("mounted");
      });
    </script>

我们看上面的代码会发现功能非常的简单, 子组件接收一个name属性, 父组件循环渲染子组件, 且子组件中有一个onMounted钩子, 我们希望的是, 当点击按钮的时候触发子组件的onMounted钩子, 乍一看是没有任何问题的, 但实际是不会触发的, 看结果:

我们发现click事件确实触发了, 而数据也确实变化了, 页面也变化了, 但就是没有触发子组件的onMounted钩子, 那这是怎么回事呢?实际上在vue处理这一步的时候 重用了之前name为veloma的Child组件, 重用不会产生挂载, 也就不会触发onMounted钩子, 那要怎么解决呢?其实很简单, 只需要给Child组件一个key即可.

总结

到目前为止其实还有好多公司没有升级到vue3, 但是我相信 在不久的将来 甚至就是今年, vue3 vite typescript 一定会覆盖大部分的公司, 所以建议小伙伴们还是需要仔细认真的多看两遍vue的新文档, 系统的了解一下vue3的变化为以后的升级做好准备, 加油!

到此这篇关于Vue3.2.x中的小技巧及注意事项的文章就介绍到这了,更多相关Vue3.2.x小技巧内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Vue3.2.x中的小技巧及注意事项总结的更多相关文章

  1. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  2. PHP 匿名函数与注意事项详细介绍

    这篇文章主要介绍了PHP 匿名函数与注意事项详细介绍的相关资料,匿名函数是PHP5.3引进来了,php5.3不但引进了匿名函数还有更多更好多新的特性了,下面我们一起来了解一下PHP匿名函数与注意事项详解,需要的朋友可以参考下

  3. jQuery常用的一些技巧汇总

    本文给大家汇总了一些jQuery常用的方法,都是我们日常项目中经常会用到的,附上示例,有需要的小伙伴可以参考下。

  4. Python中的字典合并与列表合并技巧

    这篇文章主要介绍了Python中的字典合并与列表合并技巧,下文围绕主题展开详细的内容介绍,具有一的的参考价值,需要的小伙伴可以参考一下

  5. 关于TypeScript开发的6六个实用小技巧分享

    TypeScript是Javascrip t超集,支持静态类型检测,可以在编译期提前暴露问题,节省debug时间,下面这篇文章主要给大家介绍了关于TypeScript开发的6六个实用小技巧,需要的朋友可以参考下

  6. Spring 代码技巧梳理总结让你爱不释手

    这篇文章主要分享了Spring 代码技巧梳理总结,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下

  7. 细数localStorage的用法及使用注意事项

    这篇文章主要介绍了细数localStorage的用法及使用注意事项,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  8. Python小技巧练习分享

    这篇文章主要介绍了Python小技巧练习分享,文章基于python的相关内容展开详细的python小技巧内容,具有一定的参考价值,需要的小伙伴可以参考一下

  9. 在其他地方你学不到的jQuery小贴士和技巧(欢迎收藏)

    这篇文章主要介绍了在其他地方你学不到的jQuery小贴士和技巧(欢迎收藏)的相关资料,需要的朋友可以参考下

  10. 分享Python中四个不常见的小技巧

    这篇文章主要介绍了分享Python中四个不常见的小技巧,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部