初学vue3时应该注意的几个问题

初学vue3时应该注意的几个问题

声明响应式

响应式数据的声明在vue2的时候很简单,在data中声明就行了。但现在可以使用多个方式。

reactive用于声明Object, Array, Map, Set;
ref用于声明String, Number, Boolean

使用reactive来声明基础数据类型(String, Number, Boolean)将导致警告,并且该值不会变为响应式。

<script setup>
import { reactive } from "vue";

const count = reactive(0);
script>

在这里插入图片描述

但是反过来,使用ref来声明复杂数据类型(Object, Array, Map, Set等)是生效的,因为ref内部对于复杂数据类型会调用reactive来声明。

解构reactive值

假设我们有一个带有计数器和增加计数器的按钮的响应式对象。

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

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

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

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

当使用es6进行解构时就会出问题。

<template>
  <div>Counter: {{ count }}div>
  <button @click="add">Increasebutton>
template>

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

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

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

初学vue3时应该注意的几个问题_第1张图片

代码看起来是一样的,根据我们之前的经验,应该是没问题的,但事实上,Vue 的反应性跟踪是通过属性访问来工作的。这意味着我们无法分配或解构响应式对象,因为与第一个引用的反应性连接丢失了。这是使用响应式的限制之一。

.value

ref接受一个值并返回一个响应式对象。可以通过.value来访问对象。

const count = ref(0)

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

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

refs 在模板中使用时会被解开,不需要写.value.

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

const count = ref(0)

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

<template>
  <button @click="increment">
    {{ count }}
     
  button>
template>

不过要小心!只有顶级属性才能通过.访问。下面的代码片段将产生[object Object]

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

const object = { foo: ref(1) }

script>

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

emit事件

vue中,子组件可以通过$emit来与父组件进行通信,只需要添加一个自定义侦听器来侦听事件。

父组件:

<my-component @my-event="doSomething" />

子组件

this.$emit('my-event')

现在emit事件需要使用defineEmits来声明。

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

另一件要记住的事情是,defineEmits或者(defineProps用于声明 props)在script setup.都不需要导入。使用时它们会自动可用。

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

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

.native修饰符已被移除

声明附加选项

选项式 API 方法中的一些属性在script setup并不被支持:

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

解决方案是在script setup RFC中定义的同一组件中使用 2 个不同的script标签。

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

<script setup>
  // script setup logic
script>

定义异步组件

异步组件以前是通过将它们包含在函数中来声明的

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

Vue 3 开始,异步组件需要使用defineAsyncComponent方法显式定义。

import { defineAsyncComponent } from 'vue'

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

在模板中使用不必要的包装元素

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

<template>
  <div>
    <header>...header>
    <main>...main>
    <footer>...footer>
  div>
template>

vue3支持多个根元素

<template>
  <header>...header>
  <main v-bind="$attrs">...main>
  <footer>...footer>
template>

使用错误的生命周期事件

所有组件生命周期事件都通过添加on前缀或完全更改名称来重命名。

初学vue3时应该注意的几个问题_第2张图片

你可能感兴趣的:(vue3,vue.js,javascript,前端)