Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >一张动图理解Vue3的Composition Api

一张动图理解Vue3的Composition Api

原创
作者头像
用户8983410
修改于 2021-09-19 12:29:19
修改于 2021-09-19 12:29:19
50800
代码可运行
举报
运行总次数:0
代码可运行

这个文章其实很简单, 只要能说明composition的好处,就是极好的,我们用一个非常简单的万金油场景,比如我们有一个非常简单的to do list

回顾Option

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <div id="app">
    <input type="text" v-model="val" @keyup.enter="addTodo">
    <ul>
      <li v-for="todo in todos" :key="todo.id">{{todo.title}}</li>
    </ul>
  </div>
</template>
<script>
export default {
  data(){
    return{
      val:'',
      todos:[ 
        {id:0, title:'吃饭', done:false},
        {id:1, title:'睡觉', done:false},
        {id:2, title:'lsp', done:false},
      ]
    }
  },
  methods:{
    addTodo(){
      this.todos.push({
        id:this.todos.length,
        title:this.val,
        done:false
      })
      this.val = ''
    }
  }
}
</script>

需求复杂之后,就会多出watch,computed,inject,provide等配置,这个.vue文件也会逐渐增大

Option的缺陷--反复横跳

相信大部分同学都维护过超过200行的.vue组件,新增或者修改一个需求,就需要分别在data,methods,computed里修改 ,滚动条反复上下移动,我称之为『反复横跳』 比如我们简单的加个拍脑门的需求 加个累加器 ,这种写代码上下反复横条的感觉, 相信大家都懂的, 

动画演示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <div id="app">
    <h1 @click="add">LSP {{count}}号 double is{{double}}</h1>
    <input type="text" v-model="val" @keyup.enter="addTodo">
    <ul>
      <li v-for="todo in todos" :key="todo.id">{{todo.title}}</li>
    </ul>
  </div>
</template>

<script>
import Counter from './counter'
export default {
  mixins:[Counter],
  data(){
    return{
      count:1,
      val:'',
      todos:[ 
        {id:0, title:'吃饭', done:false},
        {id:1, title:'睡觉', done:false},
        {id:2, title:'lsp', done:false},
      ]
    }
  },
  computed: {
    double() {
      return this.count * 2
    }
  },
  methods:{
    addTodo(){
      this.todos.push({
        id:this.todos.length,
        title:this.val,
        done:false
      })
      this.val = ''
    },
    add(){
      this.count++
    }
  }
}
</script>

Option的缺陷:mixin和this

反复横跳的本质,在于功能的分块组织,以及代码量太大了,如果我们能把代码控制在一屏,自然就解决了,vue2里的解决方案,是使用mixin来混合, 我们抽离一个counter.js

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export default {
  data() {
    return {
      count:1
    }
  },
  computed: {
    double() {
      return this.count * 2
    }
  },
  methods:{
    add(){
      this.count++
    }
  }
}

在App.vue中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import Counter from './counter'
export default {
  mixins:[Counter],
  data(){
 ...
  },
...
}

这样确实拆分了代码,但是有一个贼严重的问题,就是不打开counter.js,App.vue里的this上,count,add这些属性,是完全不知道从哪来的,你不知道是mixin,还是全局install,还是Vue.prototype.count设置的,数据来源完全模糊,调试爽死你,这也是option的一个大问题,this是个黑盒,template里写的count和double,完全不知道从哪来的

mixin命名冲突

如果有两个mixin,就更有意思了,比如我们又有一个需求,实时显示鼠标的坐标位置x,并且有一个乘以2的计算属性凑巧也叫double,再整一个mixin

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export default {
  data() {
    return {
      x:0
    }
  },
  methods:{
    update(e){
      this.x = e.pageX
    }
  },
  computed:{
    double(){
      return this.x*2
    }
  },
  mounted(){
    window.addEventListener('mousemove', this.update)
  },
  destroyed(){
    window.removeEventListener('mousemove', this.update)
  }
}

这是是一个独立维护的mixin,可能在N个地方用到,他根本不知道会不会有人和他冲突,然后用一下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import Counter from './counter'
import Mouse from './mouse'
export default {
  mixins:[Counter,Mouse],
  ...... 
}

两个mixin里都有double这个数,尴尬,看效果 ,lsp的count被覆盖了 很尴尬,而且在App.vue这里,你完全不知道这个double到底是哪个,调试很痛苦

Composition

composition就是为了解决这个问题存在的,通过组合的方式,把零散在各个data,methods的代码,重新组合,一个功能的代码都放在一起维护,并且这些代码可以单独拆分成函数 ,也就是大帅的这两个gif

我们用vue3演示一下功能,具体api就不解释了 直接vue3文档搞起就可以

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <div id="app">
    <input type="text" v-model="val" @keyup.enter="addTodo">
    <ul>
      <li v-for="todo in todos" :key="todo.id">{{todo.title}}</li>
    </ul>
  </div>
</template>

<script>
import {reactive, ref, toRefs} from 'vue'

export default {
  setup(){
    let val = ref('')
    let todos = reactive([ 
        {id:0, title:'吃饭', done:false},
        {id:1, title:'睡觉', done:false},
        {id:2, title:'lsp', done:false},
    ])
    function addTodo(){
      todos.push({
        id:todos.length,
        title:val.value,
        done:false
      })
      val.value = ''
    }
    return {val, todos, addTodo}
  }
}
</script>

利用函数我们可以吧功能完整独立的拆分成模块或者函数,方便组织代码,并且解决了mixin混乱的问题

比如我们的累加器 ,抽离一个counter.js

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import {ref, computed} from 'vue'

export default function useCounter(){
    let count = ref(1)
    function add(){
        count.value++
    }
    let double = computed(()=>count.value*2)
    return {count, double, add}
}

直接使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import {reactive, ref, toRefs} from 'vue'
+ import useCounter from './counter'
export default {
  setup(){
    let val = ref('')
 ...
+     let {count,double,add} = useCounter() 
    return {
      val, todos, addTodo,
+     count,double,add
    }
  }
}

再来一个鼠标位置也不在话下,而且可以很好地利用解构赋值的别名,解决mixin的命名冲突问题 mouse.js

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import {ref, onMounted, onUnmounted, computed} from 'vue'

export default function useMouse(){
  let x = ref(0)
  function update(e){
    x.value = e.pageX
  }
  let double = computed(()=>x.value*2)
  onMounted(()=>{
    window.addEventListener('mousemove', update)
  })
  onUnmounted(()=>{
    window.removeEventListener('mousemove', update)
  })
  return {x, double}
  
}

模板里直接用doubelX

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let {count,double,add} = useCounter() 
let {x, double:doubleX} = useMouse()
return {
  val, todos, addTodo,
  count,double,add,
  x,doubleX
}

script setup

到这里应该就把大帅的文章缺的代码补了一下,不过有的同学可能,还有一个小小的吐槽,那就是setup函数最后的return也是集中的,如果行数太多,一样会横条一下下,这个好解决,因为本身我们可以吧todos也抽离成函数,这样setup就全部是数据的来源,非常精简丝滑

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import useCounter from './counter'
import useMouse from './mouse'
import useTodo from './todos'
export default {
  setup(){
    let { val, todos, addTodo } = useTodo()
    let {count,double,add} = useCounter() 
    let {x, double:doubleX} = useMouse()
    return {
      val, todos, addTodo,
      count,double,add,
      x,doubleX
    }
  }
}

是不是贼爽呢,如果有些同学就是不想啥都抽离,还是觉得统一return很麻烦, 我们可以使用vue3的setup script功能,把setup这个配置也优化掉 一个功能export一次

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script setup>
import useCounter from './counter'
import useMouse from './mouse'
import useTodo from './todos'

let { val, todos, addTodo } = useTodo()
export {val, todos, addTodo}

let {count,double,add} = useCounter()
export {count,double,add}

let {x, double:doubleX} = useMouse()
export {x,doubleX}

</script>

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
做了一夜动画,就为让大家更好的理解Vue3的Composition Api
这个文章其实很简单, 只要能说明composition的好处,就是极好的,我们用一个非常简单的万金油场景,比如我们有一个非常简单的to do list
前端达人
2021/01/27
3530
做了一夜动画,就为让大家更好的理解Vue3的Composition Api
vue3-Composition-API实操
我们都知道composition api是可以和options api一起使用、友好相处的,比如下面的示例:
刘嘿哈
2022/10/25
4710
学习 Vue 3 全家桶 - Vite 和 Composition API
如果在一个页面里有多个功能,那就需要在 data 和 methods 里分别进行配置。但这样的话,数据和方法相关的代码会写在一起,在组件代码行数多了后就不好维护。可以使用 Composition API 的逻辑来拆分代码,把一个功能相关的数据和方法都维护在一起。
Cellinlab
2023/05/17
4290
学习 Vue 3 全家桶 - Vite 和 Composition API
Vue3 TypeScript 使用教程 - 实战 Vue3 element-plus 开发「待办清单」
本文完整版:《Vue3 TypeScript 使用教程 - 实战 Vue3 element-plus 开发「待办清单」》
蒋川@卡拉云
2022/05/27
2.1K0
Vue3 TypeScript 使用教程 - 实战 Vue3 element-plus 开发「待办清单」
使用 Vue 3 与 TypeScript 构建 Web 应用: Todo
引言 界面: Vue.js 3 JavaScript 超集: TypeScript 包管理器: pnpm 前端工程化/打包: Vite 路由: Vue Router 状态管理: Pinia CSS 预处理器: Less 代码格式化: Prettier 代码质量: ESLint 预览
yiyun
2023/07/17
1.2K0
使用 Vue 3 与 TypeScript 构建 Web 应用: Todo
Vue3实战系列:结合 Ant-Design-of-Vue 实践 Composition API
但是事物总有它的两面性,前端知识更新的很快,利好勤奋好学的同学。计算机行业的迭代速度很快,前端在计算机领域里,算是前浪被拍在沙滩上比较快的。
程序员十三
2020/10/23
1.3K0
Vue3 Composition API 之 setup 函数
在说 Vue3 之前,我们先看看 Vue2 项目中是如何编写逻辑代码的, 新建一个组件
青年码农
2022/12/13
4690
Vue3 Composition API 之 setup 函数
Vue3.0 七大亮点是什么??
在vue3中,增加了静态标记PatchFlag。在创建vnode的时候,会根据vnode的内容是否可以变化,为其添加静态标记PatchFlag。diff的时候,只会比较有PatchFlag的节点。PatchFlag是有类型的,比如一个可变化文本节点,会将其添加PatchFlag枚举值为TEXT的静态标记。这样在diff的时候,只需比对文本内容。需要比对的内容更少了。PatchFlag还有动态class、动态style、动态属性、动态key属性等枚举值。
逆锋起笔
2021/06/11
1K0
译文:Vue3 Composition API 是如何取代 Vue Mixins 的?
原文:https://css-tricks.com/how-the-Vue-composition-api-replaces-vue-mixins/
前端开发博客
2020/11/04
3.5K0
将Ts往Vue3中再整合一下
以上内容整理自“Young村长”的B站视频,单单去学习Ts语法总是没有在实践中用用学的快,推荐你们多像Young村长学习呀,老铁们。
前端小鑫同学
2022/12/26
4440
将Ts往Vue3中再整合一下
Vue3 Composition API教程及示例
Vue引入了Composition API(基于功能的API)作为当前基于Option的API的补充。该API将随Vue 3一起发布,但是现在您可以通过将Vue 3 Composition API添加到您的Vue 2应用程序中来进行尝试。
前端知否
2020/03/23
4.9K0
Vue3 Composition API教程及示例
Vue 3中令人激动的新功能:Composition API
在上一篇文章中,我们了解了Vue 3将带来的性能提升。我们已经知道在Vue新的主要版本中编写的应用程序会有很好的性能,但性能并不是最重要的部分。对我们开发者来说,最重要的是新版本将如何影响我们编写代码的方式。
前端开发博客
2020/11/04
7310
Vue3开发最佳实践和实用技巧(上)
上面我们发现 number 类型竟然书写了两次,我们可以单独抽离成一个类型方便复用
PHP开发工程师
2022/08/20
1.5K0
打包 Composition API、Vue3
到目前为止 Vue 为我们提供了两种开发组件的 API 风格,选项式 API 和组合式 API。组合式 API 可以由我们导入不同的 API 函数来描述组件的逻辑,在 SFC 组件中通常还会在 script 标签显示标注setup来使用。
前端小鑫同学
2022/12/26
6150
Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?
Composition API 可以说是Vue3最大的特点,那么为什么要推出Composition Api,解决了什么问题?
@超人
2021/03/18
1K0
Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?
vue 随记(3):“新时代”的姿势
•性能上:最多比vue2 快2倍•静态标记提升•proxy取代defineProperty•tree shaking:按需编译打包代码•composition api :类似hook的编码风格•支持typescript:面向未来目前的代码 98% 以上使用 TypeScript 编写。如果你还没有学习 TypeScript,请尽快学习,否则可能看不懂源码。另外有件事情说出来可能会让你非常惊讶,Vue 3 的源代码完全没有使用 class 关键字!(只在测试代码和示例代码里用到了 class 关键字)•custom renderer api:自定义渲染
一粒小麦
2020/07/21
6840
vue2.0教程
或者使用CDN <script src="https://unpkg.com/vue/dist/vue.js"></script>
lilugirl
2019/05/28
8690
vue2.0教程
关于 vue3 + typescript 项目中常用的知识点汇总
在实际项目开发中,常常会遇到这么一个场景,某一个路由是不需要渲染到侧边栏导航上的,此时我们可以给该路由添加一个hidden属性来实现。
前端达人
2021/07/19
1.6K0
关于 vue3 + typescript 项目中常用的知识点汇总
Vue3.0 不畏惧祖传代码的 Composition API
昨晚写这篇文章的时候,隔壁在聚餐,几位女生欢聚一堂,整个楼层充满了欢声笑语的味道,就好像早上刷牙刷一半就跑去吃了个鸡蛋。
用户1890129
2020/12/16
5560
Vue3.x相对于Vue2.x的变化
ps: 上图中,一种颜色代表一个功能,我们可以看到Options API的功能代码比较分散;Composition API则可以将同一个功能的逻辑,组织在一个函数内部,利于维护。
conanma
2021/11/03
8930
相关推荐
做了一夜动画,就为让大家更好的理解Vue3的Composition Api
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验