@vue/composition-api功能介绍

前言

@vue/composition-api 是通过一个插件的方式,为 Vue2(2.7自带,2.6及以下可用) 提供类似 Vue3 composition API 的函数式编程能力。它的实现思路主要有:

1、提供组合式函数,在函数内部追踪响应性依赖。

2、将组合产生的响应式状态保存到组件实例上,并在渲染期间还原。

3、重写组件的生命周期钩子,在钩子函数中恢复组合函数的上下文环境。

通过 setup() 函数作为入口,在其执行期间运行各响应式 API 追踪依赖,形成响应式状态,然后保存到实例上;在生命周期钩子中变更执行上下文,再次执行组合函数来恢复响应式状态,从而达到类似 Vue3 的编程体验。

为什么需要CompositionAPI

传统的Vue2 OptionAPI

我们以todolist为例,看一个基于vue2的OptionAPI的案例:

<template><div class="hello"><h1>{{ msg }}</h1><inputclass="add-todo"v-focustype="text"placeholder="add something"v-model="newTodo"@keyup.enter="addTodo"/><div v-for="todo in todoList" :key="todo.id" class="todo-row"><input type="checkbox" v-model="todo.completed" /><div v-if="!todo.editing" @dblclick="editTodo(todo)">{{ todo.title }}</div><inputv-elsetype="text"v-model="todo.title"@blue="doneEdit(todo)"@keyup.enter="doneEdit(todo)"@keyup.esc="cancelEdit(todo)"/></div></div>
</template><script lang="ts">
import Vue from "vue";
import {reactive,ref,computed,onMounted,ComputedRef,
} from "@vue/composition-api";type Todo = {id: number;completed: boolean;editing: boolean;title: string;
};
export default Vue.extend({name: "HelloWorld",props: {msg: String,},mounted() {console.warn(`component mounted..`);},data() {return {todoList: [{id: 1,title: "hello",completed: false,editing: false,},{id: 2,title: "world",completed: false,editing: false,},],newTodo: undefined as undefined | string,};},computed: {getLatestTodoId(): number {const lastTodo: Todo = this.todoList[this.todoList.length - 1];return lastTodo.id;},},methods: {addTodo() {if (this.newTodo === undefined) return;this.todoList.push({id: this.getLatestTodoId + 1,title: this.newTodo,completed: false,editing: false,});},editTodo(todo: Todo) {todo.editing = !todo.editing;},cancelEdit(todo: Todo) {const editingTodo: Todo | undefined = this.todoList.find((todo: Todo) => todo.editing === true);if (editingTodo === undefined) return;editingTodo.editing = false;},doneEdit(todo: Todo) {const editingTodo: Todo | undefined = this.todoList.find((todo: Todo) => todo.editing === true);if (editingTodo === undefined) return;editingTodo.title = todo.title;editingTodo.editing = false;},},directives: {focus: {inserted(el) {el.focus();},},},
});
</script>

改良的Vue2 setup CompositionAPI

改造成用@vue/composition-api的案例:

<template><div class="hello"><section style="margin-bottom:32px;"><h1 v-if="show">{{ msg }}</h1><button @click="toggle">Toggle above to hide</button></section><inputclass="add-todo"v-focustype="text"placeholder="add something"v-model="state.newTodo"@keyup.enter="addTodo"/><div v-for="todo in state.todoList" :key="todo.id" class="todo-row"><input type="checkbox" v-model="todo.completed" /><div v-if="!todo.editing" @dblclick="editTodo(todo)">{{ todo.title }}</div><inputv-elsetype="text"v-model="todo.title"@blur="doneEdit(todo)"@keyup.enter="doneEdit(todo)"@keyup.esc="cancelEdit(todo)"v-focus/></div></div>
</template><script lang="ts">
import Vue from "vue";import { totoListLogic } from "@/compositions/todoListLogic";
import { toggleLogic } from "@/compositions/toggleLogic";export default Vue.extend({name: "HelloWorld",props: {msg: String,},setup() {// todo business logicconst {state,getLatestTodoId,addTodo,editTodo,cancelEdit,doneEdit,} = totoListLogic();// toggle business logicconst { show, toggle } = toggleLogic();return {state,addTodo,editTodo,doneEdit,cancelEdit,show,toggle,};},directives: {focus: {inserted(el) {el.focus();},},},
});
</script>

以及对应的compositions函数:

toggleLogic.ts

import { ref } from "@vue/composition-api";export const toggleLogic = () => {const show = ref(true);const toggle = () => {show.value = !show.value;};return { show, toggle };
};

todoListLogic.ts

import { reactive, computed, ComputedRef } from "@vue/composition-api";type Todo = {id: number;completed: boolean;editing: boolean;title: string;
};
export const totoListLogic = () => {const state = reactive({todoList: [{id: 1,title: "hello",completed: false,editing: false,},{id: 2,title: "world",completed: false,editing: false,},],newTodo: undefined as undefined | string,});const getLatestTodoId: ComputedRef<number> = computed((): number => {const lastTodo: Todo = state.todoList[state.todoList.length - 1];return lastTodo.id;});function addTodo() {if (state.newTodo === undefined) return;state.todoList.push({id: getLatestTodoId.value + 1,title: state.newTodo,completed: false,editing: false,});}function editTodo(todo: Todo) {todo.editing = !todo.editing;}function cancelEdit(todo: Todo) {todo.editing = false;}function doneEdit(todo: Todo) {const editingTodo: Todo | undefined = state.todoList.find((todo: Todo) => todo.editing === true);if (editingTodo === undefined) return;editingTodo.title = todo.title;editingTodo.editing = false;}return { state, getLatestTodoId, addTodo, editTodo, cancelEdit, doneEdit };
};

优势对比

Composition API 相比于 Options API 的优势主要有:

1. 更好的逻辑复用性- 通过组合函数抽取逻辑,更方便的在组件内外复用
- 更好地代码分割,按功能拆分成更小的逻辑块2. 更好的代码组织- 将同一功能的代码收敛在一个函数中,提高内聚性
- 减少组件中的选项混杂,提高可读性3. 更好的类型推导- 组合式函数可以利用 Typescript 进行更精确的类型定义
- 提高代码可读性和可维护性4. 更优雅的处理逻辑抽取- 将复杂逻辑抽取为可重用的函数,组件只关注业务级代码
- 避免复杂的 mixins 和 HOC 嵌套5. 更灵活的逻辑复用粒度- 可以将任意粒度的逻辑封装为组合函数进行复用
- 更灵活的逻辑 boundaries6. 更直观的响应式编程- 通过组合式函数内的响应式变量,更直观地表达响应性
- 避免模版和业务逻辑交织在一起7. 更优雅的增量采用- 可以与现有的 Options API 共存
- 逐步使用 Composition API 改造旧组件

总体来说,Composition API 对于大型复杂应用的维护和扩展有很大优势,能够设计出更清晰、灵活的代码结构。

怎么用@vue/composition-api

安装

vue2.7以上自带,不需要安装;vue2.7以下手动安装npm install @vue/composition-api,并安装插件:

import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'Vue.use(VueCompositionAPI)

后续文章会介绍其原理。

API介绍

下面介绍几个常见的API,后续文章会一一介绍其原理:

ref

ref函数可以把一个普通的值转成响应式的数据。它返回一个可变的ref对象,对象上挂载了一个.value属性,我们可以通过这个.value属性读取或者修改ref的值。

示例如下:

import { ref } from '@vue/composition-api'const count = ref(0)console.log(count.value) // 0count.value++ 
console.log(count.value) // 1

ref很像是一个容器,它把基本类型的数据像Number、String等"装箱",让其成为响应式的数据源。

reactive

reactive用来把一个对象转换成响应式的数据。它返回的是一个代理对象,原对象中的所有属性访问和变更,都会转化成响应式的。

示例如下:

import { reactive } from '@vue/composition-api'const obj = reactive({ count: 0 })obj.count++ // 响应式更新

reactive更适合组件的所有状态都定义在一个对象中的场景,它可以一次性把整个对象状态都转成响应式。

computed

computed函数用来创建一个计算属性,它根据依赖进行缓存和懒执行。

示例如下:

import { computed } from '@vue/composition-api'const count = ref(1)const doubled = computed(() => count.value * 2)console.log(doubled.value) // 懒执行得到 2count.value++ // 修改依赖console.log(doubled.value) // 缓存得到 4

computed避免了重复执行函数,也自动追踪了依赖关系。

watch

watch函数用于侦听特定的数据源,并在回调函数中执行副作用。

示例如下:

import { ref, watch } from '@vue/composition-api'const count = ref(0)watch(count, (newCount, oldCount) => {console.log(`count变化:${oldCount} -> ${newCount}`) 
})count.value++ // 触发watcher

它就像一个监听器,可以看到count的变化并作出反应。

toRefs

toRefs 可以把一个 reactive 对象的属性都转成 ref 形式。

示例如下:

import { reactive, toRefs } from '@vue/composition-api'const state = reactive({count: 0
})const { count } = toRefs(state)console.log(count.value) // 0count.value++ // 修改 ref 形式的值

这样可以方便地解构一个 reactive 对象,同时保持响应式特性。需要注意的是reactive对象,默认给template是不可用的,只有转为ref才行。

setup

setup 是组合式 API 的入口,所有的组合函数都在此执行。

示例如下:

import { ref, reactive } from '@vue/composition-api'export default {setup() {const count = ref(0)const obj = reactive({ foo: 'bar' })// ... 进行逻辑处理return {count,obj}}  
}

生命周期

组合式API提供了一系列与组件生命周期对应的钩子函数,用来注册生命周期钩子。

示例如下:

import { onMounted } from '@vue/composition-api'export default {setup() {onMounted(() => {console.log('组件挂载了!')})}
}

有如下钩子函数:

onBeforeMount - created()
onMounted - mounted()
onBeforeUpdate - beforeUpdate()
onUpdated - updated()
onBeforeUnmount - beforeDestroy()
onUnmounted - destroyed()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/78402.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue diff 前后缀+最长递增子序列算法

文章目录 查找相同前后缀通过前后缀位置信息新增节点通过前后缀位置信息删除节点 中间部份 diff判断节点是否需要移动删除节点删除未查找到的节点删除多余节点 移动和新增节点最长递增子序列 求解最长递增子序列位置信息 查找相同前后缀 如上图所示&#xff0c;新旧 children 拥…

2023年08月在线IDE流行度最新排名

点击查看最新在线IDE流行度最新排名&#xff08;每月更新&#xff09; 2023年08月在线IDE流行度最新排名 TOP 在线IDE排名是通过分析在线ide名称在谷歌上被搜索的频率而创建的 在线IDE被搜索的次数越多&#xff0c;人们就会认为它越受欢迎。原始数据来自谷歌Trends 如果您相…

LeetCode257. 二叉树的所有路径

257. 二叉树的所有路径 文章目录 257. 二叉树的所有路径一、题目二、题解方法一&#xff1a;深度优先搜索递归方法二&#xff1a;迭代 一、题目 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点…

【逗老师的PMP学习笔记】5、项目范围管理

目录 一、规划范围管理二、收集需求1、【关键工具】头脑风暴2、【关键工具】访谈3、【关键工具】问卷调查4、【关键工具】标杆对照&#xff08;对标&#xff09;5、【关键工具】亲和图和思维导图6、【关键工具】质量功能展开7、【关键工具】用户故事8、【关键工具】原型法9、【…

python制作小程序制作流程,用python编写一个小程序

这篇文章主要介绍了python制作小程序代码宠物运输&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 1 importtkinter2 importtkinter.messagebox3 importmath4 classJSQ:5 6 7 d…

Pytest简介及jenkins集成

一、pytest介绍 pytest介绍 - unittest\nose pytest&#xff1a;基于unittest之上的单元测试框架 自动发现测试模块和测试方法 断言使用assert表达式即可 可以设置测试会话级、模块级、类级、函数级的fixtures 数据准备 清理工作 unittest&#xff1a;setUp、teardown、…

6.6.tensorRT高级(1)-mmdetection框架下yolox模型导出并推理

目录 前言1. yolox导出2. yolox推理3. 补充知识3.1 知识点3.2 mmdetection 总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习…

从 GPU 到 ChatGPT,一文带你理清GPU/CPU/AI/NLP/GPT之间的千丝万缕【建议收藏】

目录 硬件 GPU 什么是 GPU&#xff1f; GPU 是如何工作的&#xff1f; GPU 和 CPU 的区别 GPU 厂商 海外头部 GPU 厂商&#xff1a; 国内 GPU 厂商&#xff1a; nvidia 的产品矩阵 AI 什么是人工智能 (Artificial Intelligence-AI)&#xff1f; 人工智能细分领域 …

ROS添加发布者和订阅者机制实现

一. ROS的节点和包 ✨Node&#xff1a; ROS的基本单位&#xff0c;实现某个功能的节点。比如实现超声波传感器就是一个节点&#xff0c;雷达传感器就可以是一个节点 ✨Package&#xff1a; 多个有联系的节点组成的单位&#xff0c;比如你要控制无人机姿态&#xff0c;可能需要…

Crowd-Robot Interaction 论文阅读

论文信息 题目&#xff1a;Crowd-Robot Interaction:Crowd-aware Robot Navigation with Attention-based Deep Reinforcement Learning 作者&#xff1a;Changan Chen, Y uejiang Liu 代码地址&#xff1a;https://github.com/vita-epfl/CrowdNav 来源&#xff1a;arXiv 时间…

ES新特性部分

文章目录 Symbol创建使用拓展对象的方法直接添加 控制对象控制类型检查控制是否展开 遍历迭代器自定义遍历 生成器函数&#xff08;实现异步编程&#xff09;解决回调地狱 Promise连续读文件 SetMap类静态属性继承ES5ES6 GET与SET 数值Object方法模块化导入另一种导入 babel ES…

2023华数杯数学建模竞赛选题建议

提示&#xff1a;DS C君认为的难度&#xff1a;C<B<A&#xff0c;开放度&#xff1a;B<A<C 。 A题&#xff1a;隔热材料的结构优化控制研究 A题是数模类赛事很常见的物理类赛题&#xff0c;需要学习不少相关知识。 其中第一问需要建立平纹织物整体热导率与单根纤…

力扣 -- 467. 环绕字符串中唯一的子字符串

一、题目 二、解题步骤 下面是用动态规划的思想解决这道题的过程&#xff0c;相信各位小伙伴都能看懂并且掌握这道经典的动规题目滴。 三、参考代码 class Solution { public:int findSubstringInWraproundString(string s) {int ns.size();vector<int> dp(n,1);int re…

Android 刷新与显示

目录 屏幕显示原理&#xff1a; 显示刷新的过程 VSYNC机制具体实现 小结&#xff1a; 屏幕显示原理&#xff1a; 过程描述&#xff1a; 应用向系统服务申请buffer 系统服务返回一个buffer给应用 应用开始绘制&#xff0c;绘制完成就提交buffer&#xff0c;系统服务把buffer数据…

移动开发最佳实践:为 Android 和 iOS 构建成功应用的策略

您可以将本文作为指南&#xff0c;确保您的应用程序符合可行的最重要标准。请注意&#xff0c;这份清单远非详尽无遗&#xff1b;您可以加以利用&#xff0c;并添加一些自己的见解。 了解您的目标受众 要制作一个成功的应用程序&#xff0c;你需要了解你是为谁制作的。从创建…

接口自动化测试Mock Get和Post请求

Mock可以模拟一个http接口的后台响应&#xff0c;可以模拟request&#xff0c;response 下载 moco-runner-0.11.0-standalone.jar 下载链接: https://pan.baidu.com/s/1bmFzvJPRnDlQ-cmuJ_3iRg 提取码: kpjv 确保安装了jdk,cmd下可以运行java -version 一、模拟不带参的get请求…

AQL品质抽样标准

AQL抽样标准 - 百度文库 Acceptance Quality Limit 接收质量限的缩写&#xff0c;即当一个连续系列批被提交验收时&#xff0c;可允许的最差过程平均质量水平。 AQL普遍应用于各行业产品的质量检验&#xff0c;不同的AQL标准应用于不同物质的检验上。在AQL 抽样时&#xff0c;…

VUE框架:vue2转vue3全面细节总结(3)路由组件传参

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人_python人工智能视觉&#xff08;opencv&#xff09;从入门到实战,前端,微信小程序-CSDN博客 最新的uniapp毕业设计专栏也放在下方了&#xff1a; https://blog.csdn.net/lbcy…

idea添加翻译插件并配置有道翻译

1、安装Translation插件 2、 创建有道云应用 有道智云控制台 3、设置idea 4、效果&#xff08;选中文本右键翻译&#xff0c;默认快捷键CtrlShiftY&#xff09;

图文演示:如何三分钟极速搭建一个元宇宙3D虚拟展厅

引言&#xff1a; 元宇宙3D虚拟展厅时代已经来临。元宇宙是一个虚拟的、立体的数字空间&#xff0c;可以让用户沉浸在其中进行交互操作&#xff0c;并体验无限可能。如何快速搭建一个属于自己的虚拟展厅则受到越来越多人的关注。 一&#xff0e;虚拟展厅类型 1.党建展馆 实现…