首页 > 其他分享 >Vue3使用Composition API实现响应式

Vue3使用Composition API实现响应式

时间:2024-05-29 20:32:26浏览次数:14  
标签:count const 响应 API increment Vue3 import ref Composition


title: Vue3使用Composition API实现响应式
date: 2024/5/29 下午8:10:24
updated: 2024/5/29 下午8:10:24
categories:

  • 前端开发

tags:

  • Vue3
  • Composition
  • Refs
  • Reactive
  • Watch
  • Lifecycle
  • Debugging

在这里插入图片描述

1. 介绍

Composition API是Vue.js 3中新增的一组API,用于在组件中组合逻辑和功能。它可以让你更好地组织和重用代码,使组件更易于理解和维护。在使用Composition
API时,你可以使用<script setup>语法或setup()函数,两种方式都可以使用Composition API中的响应式API、生命周期钩子、模板引用和自定义渲染函数等特性。

2. 基本响应式

在Vue.js 3中,Composition API提供了几种创建响应式数据的方法,包括refreactivereadonlyshallowReactive
shallowReadonly

2.1 ref

ref函数用于创建一个响应式的ref对象,其值可以通过.value
属性获取或设置。当ref对象的值发生变化时,Vue.js会自动更新视图。AD:首页 | 一个覆盖广泛主题工具的高效在线平台

<template>
  <div>
    <p>count: {{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

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

const count = ref(0);

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

2.2 reactive

reactive函数用于创建一个响应式的对象,其所有属性都是响应式的。当对象的属性发生变化时,Vue.js会自动更新视图。

<template>
  <div>
    <p>name: {{ user.name }}</p>
    <p>age: {{ user.age }}</p>
    <button @click="incrementAge">+1</button>
  </div>
</template>

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

const user = reactive({
  name: 'Alice',
  age: 20
});

function incrementAge() {
  user.age++;
}
</script>

2.3 readonly

readonly函数用于创建一个只读的响应式对象,其所有属性都是只读的。当试图修改只读对象的属性时,会抛出一个错误。

<template>
  <div>
    <p>name: {{ user.name }}</p>
    <p>age: {{ user.age }}</p>
  </div>
</template>

<script setup>
import { reactive, readonly } from 'vue';

const user = reactive({
  name: 'Alice',
  age: 20
});

const readonlyUser = readonly(user);

// 会抛出一个错误
readonlyUser.age = 21;
</script>

2.4 shallowReactive

shallowReactive函数用于创建一个浅响应式的对象,其所有属性都是响应式的,但其子对象的属性不是响应式的。
AD:专业搜索引擎

<template>
  <div>
    <p>name: {{ user.name }}</p>
    <p>age: {{ user.age }}</p>
    <p>address: {{ user.address }}</p>
    <button @click="incrementAge">+1</button>
    <button @click="changeAddress">改变地址</button>
  </div>
</template>

<script setup>
import { shallowReactive } from 'vue';

const user = shallowReactive({
  name: 'Alice',
  age: 20,
  address: {
    province: 'Beijing',
    city: 'Beijing'
  }
});

function incrementAge() {
  user.age++;
}

function changeAddress() {
  user.address = {
    province: 'Shanghai',
    city: 'Shanghai'
  };
}
</script>

2.5 shallowReadonly

shallowReadonly函数用于创建一个浅只读的响应式对象,其所有属性都是只读的,但其子对象的属性不是只读的。

<template>
  <div>
    <p>name: {{ user.name }}</p>
    <p>age: {{ user.age }}</p>
    <p>address: {{ user.address }}</p>
    <!-- 会抛出一个错误 -->
    <button @click="changeAddress">改变地址</button>
  </div>
</template>

<script setup>
import { shallowReactive, shallowReadonly } from 'vue';

const user = shallowReactive({
  name: 'Alice',
  age: 20,
  address: {
    province: 'Beijing',
    city: 'Beijing'
  }
});

const readonlyUser = shallowReadonly(user);

// 会抛出一个错误
readonlyUser.age = 21;
</script>

3. 响应式API

Composition API提供了几种响应式API,包括watchEffectwatchcomputedprovide/inject

3.1 watchEffect

watchEffect函数用于创建一个响应式的副作用函数,当响应式数据发生变化时,副作用函数会自动重新执行。

<template>
  <div>
    <p>count: {{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

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

const count = ref(0);

watchEffect(() => {
  console.log(`count is ${count.value}`);
});

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

3.2 watch

watch函数用于创建一个响应式的监听器,当响应式数据发生变化时,监听器会自动执行。

<template>
  <div>
    <p>count: {{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

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

const count = ref(0);

watch(count, (newValue, oldValue) => {
  console.log(`count changed from ${oldValue} to ${newValue}`);
});

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

3.3 computed

computed函数用于创建一个响应式的计算属性,其值是根据响应式数据计算得出的。当响应式数据发生变化时,计算属性会自动重新计算。
AD:漫画首页

<template>
  <div>
    <p>count: {{ count }}</p>
    <p>doubleCount: {{ doubleCount }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

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

const count = ref(0);

const doubleCount = computed(() => {
  return count.value * 2;
});

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

3.4 provide/inject

provideinject函数用于在组件树中传递数据。provide函数用于在父组件中提供数据,inject函数用于在子组件中注入数据。

<template>
  <div>
    <ChildComponent />
  </div>
</template>

<script setup>
import { provide } from 'vue';
import ChildComponent from './ChildComponent.vue';

provide('message', 'Hello, world!');
</script>
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script setup>
import { inject } from 'vue';

const message = inject('message');
</script>

4. 生命周期钩子

Composition
API提供了几种生命周期钩子,包括setup()onBeforeMount()onMounted()onBeforeUpdate()onUpdated()onBeforeUnmount()onUnmounted()onErrorCaptured()onRenderTracked()
onRenderTriggered()

4.1 setup()

setup()函数是Composition API的入口点,用于在组件创建之前执行一些初始化操作。

<template>
  <div>
    <p>count: {{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

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

export default {
  setup() {
    const count = ref(0);

    function increment() {
      count.value++;
    }

    return {
      count,
      increment
    };
  }
};
</script>

4.2 onBeforeMount()

onBeforeMount()函数在组件挂载之前执行。

<template>
  <div>
    <p>count: {{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

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

export default {
  setup() {
    const count = ref(0);

    function increment() {
      count.value++;
    }

    onBeforeMount(() => {
      console.log('before mount');
    });

    return {
      count,
      increment
    };
  }
};
</script>

4.3 onMounted()

onMounted()函数在组件挂载之后执行。

<template>
  <div>
    <p>count: {{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

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

export default {
  setup() {
    const count = ref(0);

    function increment() {
      count.value++;
    }

    onMounted(() => {
      console.log('mounted');
    });

    return {
      count,
      increment
    };
  }
};
</script>

4.4 onBeforeUpdate()

onBeforeUpdate()函数在组件更新之前执行。

<template>
  <div>
    <p>count: {{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

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

export default {
  setup() {
    const count = ref(0);

    function increment() {
      count.value++;
    }

    onBeforeUpdate(() => {
      console.log('before update');
    });

    return {
      count,
      increment
    };
  }
};
</script>

4.5 onUpdated()

onUpdated()函数在组件更新之后执行。

<template>
  <div>
    <p>count: {{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

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

export default {
  setup() {
    const count = ref(0);

    function increment() {
      count.value++;
    }

    onUpdated(() => {
      console.log('updated');
    });

    return {
      count,
      increment
    };
  }
};
</script>

4.6 onBeforeUnmount()

onBeforeUnmount()函数在组件卸载之前执行。

<template>
  <div>
    <p>count: {{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

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

export default {
  setup() {
    const count = ref(0);

    function increment() {
      count.value++;
    }

    onBeforeUnmount(() => {
      console.log('before unmount');
    });

    return {
      count,
      increment
    };
  }
};
</script>

4.7 onUnmounted()

onUnmounted()函数在组件卸载之后执行。

<template>
  <div>
    <p>count: {{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

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

export default {
  setup() {
    const count = ref(0);

    function increment() {
      count.value++;
    }

    onUnmounted(() => {
      console.log('unmounted');
    });

    return {
      count,
      increment
    };
  }
};
</script>

4.8 one rrorCaptured()

onErrorCaptured()函数在组件捕获到错误时执行。

<template>
  <div>
    <p>count: {{ count }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

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

export default {
  setup() {
    const count = ref(0);

    function increment() {
      count.value++;
    }

    one rrorCaptured((error, instance, info) => {
      console.error(error);
      return false;
    });

    return {
      count,
      increment
    };
  }
};
</script>

4.9 onRenderTrackedonRenderTriggered

onRenderTrackedonRenderTriggered是两个生命周期钩子,它们与Vue的响应式系统和编译器有关。这两个钩子是在Vue
3.x版本中引入的,主要用于调试目的,帮助开发者了解组件渲染过程中的跟踪和触发情况。

  1. onRenderTracked钩子:

    • 当组件的响应式依赖项被追踪时,即响应式系统开始跟踪一个依赖项时,这个钩子会被调用。
    • 它主要用于调试,可以帮助开发者了解何时响应式系统开始关注某个依赖项。
    • onRenderTracked钩子接收两个参数:depcontextdep是依赖项对象,context是当前组件的上下文对象。
  2. onRenderTriggered钩子:

    • 当组件的响应式依赖项被触发时,即响应式系统因为某个依赖项的变化而触发了重新渲染时,这个钩子会被调用。
    • 它主要用于调试,可以帮助开发者了解何时响应式系统因为某个依赖项的变化而重新渲染组件。
    • onRenderTriggered钩子也接收两个参数:depcontext,含义与onRenderTracked相同。

示例代码:

export default {
    setup() {
        // 定义一个响应式数据
        const count = ref(0);

        // 监听 count 的变化
        watch(count, (newValue, oldValue) => {
            console.log(`count changed from ${oldValue} to ${newValue}`);
        });

        // 使用 onRenderTracked 和 onRenderTriggered 进行调试
        onRenderTracked((dep, context) => {
            console.log(`onRenderTracked: ${dep}`);
        });

        onRenderTriggered((dep, context) => {
            console.log(`onRenderTriggered: ${dep}`);
        });

        return {
            count
        };
    }
};

在这个示例中,我们定义了一个响应式数据count,并使用了watch来监听它的变化。同时,我们使用了onRenderTracked
onRenderTriggered来打印调试信息。当响应式系统开始跟踪或触发重新渲染时,我们会得到相应的提示。这些钩子可以帮助开发者更好地理解Vue组件的渲染过程和响应式系统的运作。

标签:count,const,响应,API,increment,Vue3,import,ref,Composition
From: https://blog.csdn.net/qq_42210428/article/details/139305042

相关文章

  • 升鲜宝供应链管理系统重构版发布(技术点:Java8、mysql8.0 uniapp、vue、android、web 框
    升鲜宝供应链管理系统重构版发布(技术点:Java8、mysql8.0uniapp、vue、android、web框架:Vue3+SpringBoot3),界面功能(三) 主要功能要点:     权限管理(组织机构、用户管理、角色管理、岗位管理)     系统设置(菜单管理、参数管理、数据字典、定时任务、文件管......
  • apifox脚本编写
    前言在apifox中,我们可以通过脚本实现很多方便的操作,例如可以通过前置脚本来实现自动登录(校验token过期自动在脚本中调用登录重新获取token),在后置脚本中实现对返回结果的校验和参数的提取(利用脚本提取的临时变量不拘泥于某个测试场景,可以在不同的场景间重复使用)。下面是我平时常......
  • 学习VUE3——模板引用ref
    在某些情况下,我们仍然需要直接访问底层DOM元素。要实现这一点,我们可以使用特殊的refattribute:<inputref="input">ref是一个特殊的attribute,和v-for章节中提到的key类似。它允许我们在一个特定的DOM元素或子组件实例被挂载后,获得对它的直接引用。这可能很有用,比......
  • vue3项目使用pinia状态管理器----通俗易懂
    1、首先安装piniayarnaddpinia#或使用npmnpminstallpinia2、在项目的src目录下新建store文件夹,然后store目录下新建index.js/index.ts:我这里是index,jsimport{createPinia}from"pinia"//创建Pinia实例constpinia=createPinia()//导出Pinia......
  • vue3 组件的动态渲染 <component :is=“componentTag“ />
    1、动态渲染组件        <component:is=""></component>        通过isShow来切换显示A、B组件首先创建父组件.vue文件和两个子组件A、B文件,并引入。template:<div><h3>我是父组件dynamicComp.vue</h3><button@click="isShow=!isShow">切换......
  • 通过接口拿到api拿到ip代理
    defget_api_iplist():f_ua=fake.user_agent()#url="https://www.baidu.com/"#测试网站url地址url="http://api.89ip.cn/tqdl.html?api=1&num=600&port=&address=&isp="#测试网站url地址headers={'User-Agent�......
  • vue3 表单输入绑定
    表单输入绑定在前端处理表单时,我们常常需要将表单输入框的内容同步给JavaScript中相应的变量。手动连接值绑定和更改事件监听器可能会很麻烦:<input:value="text"@input="event=>text=event.target.value">v-model指令帮我们简化了这一步骤:<inputv-model=......
  • vue3响应式基础
    声明响应式状态​ref()​在组合式API中,推荐使用ref()函数来声明响应式状态:import{ref}from"vue";constmsg=ref("helloworld");ref()接收参数,并将其包裹在一个带有.value属性的ref对象中返回:<template><div>{{msg}}</div></template><scri......
  • 解决Vue3项目使用多个根标签提示[vue/no-multiple-template-root]The template root r
    报错截图检查原因第一步:检查是否安装了 Vetur 插件 第二步:左下角设置图标 ==》设置第三步:进入设置页面搜索eslint把Vetur的验证模板,取消勾选 Validatevue-htmlinusingeslint-plugin-vue第四步:将错误提示页面关掉然后重新打开,即可正常显示......
  • vue3项目中 路由elementPlus当中的标签页结合封装
    在项目当中大家应该都有看到过,像标签页一样的面包屑吧,接下来我为大家介绍一下,主要组成部分:路由+组件库的标签页。ok就这么easy!!!它实现的方法也不难哦请看效果图ok,在中间实现思路与大家分享一下:主要是使用watch监听我们的route路由的变化,然后根据传递过来的路由信息,进行标签页......