Vue 3中的数据选项(reactive、computed、method、watch、props、provide/inject)

本文主要介绍Vue 3中的数据选项,包括data、computed、method、watch、props、provide/inject等。

什么是数据选项?

在Vue3中,数据选项指的是用于定义Vue实例中数据的属性。数据选项可以包括响应式数据、计算属性、方法和侦听等,用于定义Vue实例的数据模型。
下面介绍几种常见的数据选项:

1. reactive data(响应式数据)

在Vue3中,响应式数据使用refreactive包装。ref用于包装简单数据类型,比如数字、字符串、布尔值等,而reactive用于包装对象和数组等复杂数据类型。这样包装之后,这些数据就可以被Vue3追踪,并在数据发生变化时自动更新相关的视图。

在我之前写的文章《Vue 3 的响应式数据》有详细介绍。

2. computed(计算属性)

计算属性是指根据已有属性计算出新的属性,通常用于简化模板中的表达式。在Vue3中,计算属性可以使用computed函数来定义,与Vue2中类似。

下面举一个例子,在<script setup>中定义计算属性,可以直接在模板中使用,而不需要像Vue 2.x版本一样必须将计算属性添加到computed选项中。下面是一个在<script setup>中定义计算属性的例子:

<template>
  <div>
    <p>{{ fullName }}</p>
  </div>
</template>

<script setup>
  const firstName = 'John'
  const lastName = 'Doe'

  const fullName = () => {
    return `${firstName} ${lastName}`
  }
</script>

在这个例子中,我们在<script setup>块中定义了firstNamelastNamefullNamefullName是一个箭头函数,它返回拼接后的完整名字。在模板中,我们可以直接访问计算属性fullName并渲染结果,就像在Vue 2.x版本中那样。

注意,在使用<script setup>时,不需要使用computed选项来定义计算属性。

3. method(方法)

方法是指在Vue实例中定义的函数,可以在模板中通过指令调用。在Vue3中,方法和计算属性一样,可以使用普通函数来定义。不过也可以使用methods对象来定义多个方法,与Vue2中类似。

<script setup> 中定义方法很简单,只需要直接在代码块中定义即可。下面是一个使用 <script setup> 定义方法的例子:

```html
<template>
  <div>
    <button @click="incrementCounter">点击增加</button>
    <p>计数器值:{{ counter }}</p>
  </div>
</template>

<script setup>
  let counter = 0

  const incrementCounter = () => {
    counter++
  }
</script>
```

在这个例子中,我们在 <script setup> 块中定义了 counter 数据选项和 incrementCounter 方法。当按钮被点击时,incrementCounter 方法将计数器值加 1,而模板中的计数器值则会自动更新。

需要注意的是,在使用 <script setup> 时,需要使用 letconst关键字来声明数据选项。此外,需要将方法定义为一个函数,而不是使用对象语法。

4. watch(侦听)

在Vue3中,侦听(watch)是处理数据变化的一种方式,类似于Vue2中的watch选项。但是,在Vue3中,侦听的用法和实现方式都有所变化。

Vue3中通过watchEffectwatch两个API实现侦听。其中,watchEffect用于响应式监听数据变化,自动执行其内部的处理函数;而watch则更加灵活,可以监听多个数据源并执行回调函数,支持深度监听、立即执行等高级选项。

下面分别介绍watchEffectwatch的使用方法:

(1) watchEffect的使用方法:

import { watchEffect, reactive } from 'vue'
const state = reactive({ count: 0 })

watchEffect(() => {
  console.log(state.count)  // 自动响应式监听数据变化
})

上面代码中,watchEffect会自动侦听state.count的变化,并在变化时执行其内部的处理函数(即控制台输出state.count的值)。

(2) watch的使用方法:

import { watch, reactive } from 'vue'
const state = reactive({ count: 0, name: 'Vue3' })

watch([  
  () => state.count,  // 监听state.count的变化
  () => state.name    // 监听state.name的变化
], ([count, name], [prevCount, prevName]) => {  
  console.log(`count: ${count}, name: ${name}`)  // 执行回调函数
}, {
  deep: true,          // 深度监听
  immediate: true      // 立即执行
})

上面代码中,watch可以同时监听多个数据源(即state.countstate.name),并在变化时执行其回调函数。回调函数的第一个参数为新值,第二个参数为旧值。在选项对象中,可以配置deepimmediate等高级选项。

Vue3中的侦听相比于Vue2更加灵活和高效,可以更好地处理数据变化和业务逻辑。

5. props

用于父组件向子组件传递数据的属性列表,通过props选项将其声明为子组件的属性,子组件通过props来接收这些属性。
下面是一个使用<script setup>编写的父子组件,其中父组件向子组件传递一个message属性:

<!-- Parent.vue (父组件)-->
<template>
  <Child :message="parentMessage" />
</template>

<script setup>
  import Child from './Child.vue'
  const parentMessage = 'Hello from parent'
</script>

<script>
  export default {
    components: { Child },
    data() {
      return {
        parentMessage
      }
    }
  }
</script>
<!-- Child.vue (子组件)-->
<template>
  <div>{{ message }}</div>
</template>

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

  const props = defineProps({
    message: {
      type: String,
      default: 'Hello from child'
    }
  })
</script>

在上面的代码中,父组件Parent.vue通过<Child :message="parentMessage" />向子组件Child.vue传递了一个message属性。子组件通过defineProps函数来定义了一个props对象,其中包含了一个名为message的属性,它的类型为String,默认值为Hello from child。在模板中,子组件通过props.message来获取message属性的值。

6. provide/inject

用于祖先组件向后代组件传递数据的高级选项。通过provide选项将一个数据对象提供给子组件,子组件通过inject选项来接收这个数据对象。
假设我们有一个父组件和一个子组件,我们希望在父组件中提供一些数据给子组件使用。我们可以使用 provide 在父组件中提供数据,然后使用 inject 在子组件中注入这些数据。

<template>
  <div>
    <p>父组件:</p>
    <p>name: {{name}}</p>
    <p>age: {{age}}</p>
    <hr>
    <Child />
  </div>
</template>

<script setup>
import Child from './Child.vue'
const name = '张三'
const age = 18
provide('personInfo', { name, age })
</script>

在父组件中,我们使用了 provide 提供了一个名为 personInfo 的数据,它是一个对象,包含了 nameage 两个属性。

<template>
  <div>
    <p>子组件:</p>
    <p>name: {{name}}</p>
    <p>age: {{age}}</p>
  </div>
</template>

<script setup>
import { inject } from 'vue'
const { name, age } = inject('personInfo', {
  name: '未知',
  age: 0
})
</script>

在子组件中,我们使用了 inject 注入了在父组件中提供的 personInfo 数据,并将它们解构为 nameage 两个变量使用。在 inject 中,我们还可以传入一个默认值对象,在没有注入到数据时使用。这里我们传入了一个默认的名为 未知,年龄为 0 的数据。

这样,在子组件中,我们就可以通过 nameage 两个变量访问在父组件中提供的数据了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

专业研究祖传Bug编写术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值