vue响应式API,ref和reactive的使用

什么是组合式API

        组合式 API(Composition API)是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件。它是一个概括性的术语,涵盖了以下方面的 API:

        在最新的vue中,vue采用了组合式API的风格来书写代码,vue官方展示了组合式API和选择式API的用法

选项式 API (Options API)​

        使用选项式 API,我们可以用包含多个选项的对象来描述组件的逻辑,例如 data、methods 和 mounted。选项所定义的属性都会暴露在函数内部的 this 上,它会指向当前的组件实例。




<script>
export default {
  // data() 返回的属性将会成为响应式的状态
  // 并且暴露在 `this` 上
  data() {
    return {
      count: 0
    }
  },

  // methods 是一些用来更改状态与触发更新的函数
  // 它们可以在模板中作为事件处理器绑定
  methods: {
    increment() {
      this.count++
    }
  },

  // 生命周期钩子会在组件生命周期的各个不同阶段被调用
  // 例如这个函数就会在组件挂载完成后被调用
  mounted() {
    console.log(`The initial count is ${this.count}.`)
  }
}
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

组合式 API (Composition API)

        通过组合式 API,我们可以使用导入的 API 函数来描述组件逻辑。在单文件组件中,组合式 API 通常会与 <script setup> 搭配使用。这个 setup attribute 是一个标识,告诉 Vue 需要在编译时进行一些处理,让我们可以更简洁地使用组合式 API。比如,<script setup> 中的导入和顶层变量/函数都能够在模板中直接使用。

下面是使用了组合式 API 与 <script setup> 改造后和上面的模板完全一样的组件:

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

// 响应式状态
const count = ref(0)

// 用来修改状态、触发更新的函数
function increment() {
  count.value++
}

// 生命周期钩子
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

         可以发现这两个代码书写方式的不同点在于组合式API的script标签多了一个setup属性,同时多了一个ref方法。

这里的setup属性其实是对setup函数的一个封装,它表示整个script标签的内容全部都属于setup函数,并自动返回响应式的值。

setup函数和script setup标签

setup函数

  • setup()函数返回值通常是一个对象,这个对象的所有属性会暴露给组件模板和组件实例
  • setup()函数中的this指向undefined
  • setup()函数会在所有生命周期函数beforeCreate之前被执行。
  • setup()函数内定义的变量默认为非响应式的,所以对外暴露该属性为非响应式
<script>
  export default {
    // setup函数是所有组合式API的入口(表演的舞台)
    setup() {
      // .....所有代码在此书写
    },
  };
</script>

        在setup函数中返回的对象属性,在整个组件中是直接可以被访问的,但是这些属性都是非响应性的,当改变属性的值时,页面并不会同步更新,非响应的值对组件来说相当于一个常量,无法改变 ,,那我们知道vue框架是一个动态可编辑的组件集合,这自然是需要能响应的值来保证其动态更新,这就需要使用响应式API来实现

什么是响应式API

在setup函数中,返回的值是不能够被改变的,通过响应式API(ref和reactive)的响应式代理,可以实现传递动态变化的值。

ref方法

        接受一个内部值,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的属性 .value

  • 可更改是指你可以为ref对象的value属性赋予新的值
  • 响应式是指所有对 .value 的操作都将被追踪,并且写操作会触发与之相关的副作用(DOM 更新)
<script>
  import { ref } from "vue";
  export default {
    setup() {
      // msg为一个ref对象,并且是响应式的
      const msg = ref("Hello Vue!!"); // {value: "Hello Vue!!"}

      // 修改ref对象value属性的值
      msg.value = "Hello ref!!";

      return {
        msg,
      };
    },
  };
</script>
<template> {{ msg }} </template>

使用setup的script标签 

<script setup>
import { ref } from "vue";
  
// msg为一个ref对象,并且是响应式的
const msg = ref("Hello Vue!!"); // {value: "Hello Vue!!"}
// 修改ref对象value属性的值
msg.value = "Hello ref!!";

</script>
<template> {{ msg }} </template>

        这里的msg其实就相当于一个对象他有一个属性value,值等于注入的值,例如,字符串,数字,对象,可以通过value属性来访问到这个值,

        但是我们注意到,既然这个值是在value属性中存放的,在template标签又直接使用msg却打印出了值,这里是响应式对象会自动解包 ref 属性。

        一个响应式对象的属性及嵌套属性的值如果为ref属性,在模板或setup()中使用时,会自动解包,同时保持响应性(msg = msg.value),但是,当访问到某个响应式数组或 Map 这样的原生集合类型中的 ref 元素时,不会执行 ref 的解包。同时,在script标签内是不会解包的,任需要通过value来访问值。

reactive方法

reactive()方法用来返回一个对象的响应式代理(对象)。

const objProxy = reactive(obj); // objProxy为obj对象的响应式代理
<script>
  // 导入reactive方法
  import { reactive } from "vue";
  export default {
    setup() {
      const obj = { a: 1, b: 2 };
      // Info为响应式代理对象
      const objProxy = reactive(obj);
      console.log(objProxy); // Proxy(Object) {a: 1, b: 2}

      function update() {
        // 修改对象属性的值
        objProxy.a = 10;
        objProxy.b = 20;
      }
      // 将属性暴露给组件实例
      return {
        objProxy,
        update,
      };
    },
  };
</script>
<template>
  <div>a的值:{{ objProxy.a }}</div>
  <div>b的值:{{ objProxy.b }}</div>
  <button @click="update">更新a,b的值</button>
</template>

 

点击按钮后a,b的值改变并渲染到了页面上,这表示objProxy代理对象具有响应性,所以objProxy为响应式代理对象。

但是要注意reactive() 无法转换基本数据类型,

const msg = reactive("Hello Vue!!");// error

        这种用法会直接报错,reactive()方法只能将一个对象转换为一个响应式对象,而不能将一个基本数据类型转换为响应式对象。因为reactive()方法的底层采用的是Proxy来实现的,而Proxy只能创建对象的代理。Proxy对象可以参考: Proxy - JavaScript | MDN

正确的方式是使用ref

const msg = ref("Hello Vue!!");// success

总结

响应式API可以让setup中的非响应数据,传递出来,并使其可以响应,从而实现页面的动态编辑,

我们可以把ref和reactive看成组件中对数据的特殊赋值,

const num = ref(0); => let num = 0;
const obj = reactive({age:10}); => let obj = {name:10};

更多相关内容可以参考:

Vue 组合式 API - setup、reactive 与 ref,响应式工具 | arry老师的博客-艾编程 (arryblog.com)

响应式基础 | Vue.js (vuejs.org)

  • 29
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值