亲宝软件园·资讯

展开

Vue3.2.x小技巧

VELOMA 人气:0

前言

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

小技巧

关于减少.value的使用

输出:

这里需要说明一下使用$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中就有一个用户开发了一个插件来解决这个问题。

下载插件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等,有兴趣的小伙伴可以去看一下,感觉可以利用这一特性才做一些骚操作,不过尤大大觉得这种方式不太好。

注意事项

关于响应式的问题

  // 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新文档中有提到这样一句话

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

加载全部内容

相关教程
猜你喜欢
用户评论