Vue3 开发小技巧及注意事项(持续更新ing)

913 阅读2分钟

Vue3 中 Composition API 如何使用 ref 获取组件实例?

1、获取单个组件实例

<template>
    # 定义ref变量名,此时是以字符串的方式而非变量的方式定义的
    <div ref="divRef"></div>
<template>

<script setup lang="ts">
// 根据定义的变量名创建ref变量
const divRef = ref();

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

2、用一个变量获取多个组件实例

我有需求要实现批量操作同类型的组件完成一种行为时,发现文档正文没有对相关内容做出定义

所以我就用了官方不推荐的 getCurrentInstance 这个方法获取到当前组件实例,然后通过 instance.refs 来批量操作

但其实除了框架层面业务层面实际上是不建议使用 getCurrentInstance 这个API的

随后仔细查阅文档发现这个内容被写到了这里

如果有和我上面的需求一直的小伙伴可以看一下

Vue3 提供了一种骚操作

如果想要用一个变量绑定多个 ref,请将 ref 绑定到一个更灵活的函数上(这是一个新特性)

<div v-for="item in list" :ref="setItemRef"></div>

Options API:

export default {
  data() {
    return {
      itemRefs: []
    }
  },
  methods: {
    setItemRef(el) {
      if (el) {
        this.itemRefs.push(el)
      }
    }
  },
  beforeUpdate() {
    this.itemRefs = []
  },
  updated() {
    console.log(this.itemRefs)
  }
}

Composition API

import { onBeforeUpdate, onUpdated } from 'vue'

export default {
  setup() {
    let itemRefs = []
    const setItemRef = el => {
      if (el) {
        itemRefs.push(el)
      }
    }
    onBeforeUpdate(() => {
      itemRefs = []
    })
    onUpdated(() => {
      console.log(itemRefs)
    })
    return {
      setItemRef
    }
  }
}

而且 itemRefs 也不一定是数组,也可以是对象,其 ref 可以通过迭代 key 来设置

如果有需要 itemRefs 也可使以响应式的

Vue3 中同时使用 v-if 与 v-for 的注意事项

一般情况下我是不建议在同一个标签同时使用 v-ifv-for 的,或许某些情况真的需要这样做

我个人建议还是使用 computed 来对需要 v-for 的数据源进行过滤,从而达到上面的需求,至少从代码可读性上会好很多

下面讲一下 Vue2/3 两个版本中对于这两个同时使用的一些区别

1、Vue2

v-for 的优先级是高于 v-if 的

也就意味着,我们可以在 v-ifcondition 中使用循环出来的 item 进行判断

2、Vue3

v-if 的优先级高于 v-for

所以以前 Vue2 中的代码在升级之后要么改成 computed 的方式,要么就要注意 condition 无法访问到 v-for 中的 item

组件开发中 v-bind 合并覆盖问题

如果有这样一段代码

<div id="map" v-bind="{ ..., id: 'map1' }" />

# Vue2 结果
<div id="map" />
# Vue3 结果
<div id="map1" />

但如果上面是这样写

<div v-bind="{ ..., id: 'map1' }" id="map" />

# Vue2 结果
<div id="map" />
# Vue3 结果
<div id="map" />

结论是:

Vue2 中的 v-bind 永远是独立声明attr 优先级最高,不论顺序。而 Vue3 中的 attr 最终结果受到声明的前后顺序影响,后声明的永远覆盖先声明的

这点需要注意下

关于 template 的 key 声明

1、Vue2

由于不允许在 template 上定义 key,我们只能在子元素里面逐个定义 key,这很麻烦,但也没办法,谁叫用了 eslint,还是按标准来吧

<template v-for="item in list">
  <div :key="'element1-' + item.id">...</div>
  <div :key="'element2-' + item.id">...</div>
</template>

2、Vue3

Vue3 允许我们将 key 写到 template 上,这就很 nice

<template v-for="item in list" :key="item.id">
  <div>...</div>
  <div>...</div>
</template>