1. 首页

那个忙了一夜的Vue3动画很好,就是太短了

插曲

最近准备给我们前端组起个名字,欢迎大家投票提建议,现在有两个提案

  1. 前端独立团,我真他娘的是个人才 但是域名还没想好
  2. 录视频战队 , lsp.team

配套代码github

最近我们组的大帅 * 同学写了个很好地composition 动画演示的文章, 大家直呼太短了,这个希望大家理解,他最近写文章是被我逼着写的, 后续文章会更完整一些,最近我给他的任务太多了,我帮他简单丰富一下这个文章的意义吧

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

回顾Option

 html
<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文件也会逐渐增大

那个忙了一夜的Vue3动画很好,就是太短了

Option的缺陷–反复横跳

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

动画演示 那个忙了一夜的Vue3动画很好,就是太短了

 html
<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


export default { data() { return { count:1 } }, computed: { double() { return this.count * 2 } }, methods:{ add(){ this.count++ } } }

在App.vue中


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


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个地方用到,他根本不知道会不会有人和他冲突,然后用一下


import Counter from './counter' import Mouse from './mouse' export default { mixins:[Counter,Mouse], ...... }

那个忙了一夜的Vue3动画很好,就是太短了 两个mixin里都有double这个数,尴尬,看效果 ,lsp的count被覆盖了 很尴尬,而且在App.vue这里,你完全不知道这个double到底是哪个,调试很痛苦

Composition

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

那个忙了一夜的Vue3动画很好,就是太短了 那个忙了一夜的Vue3动画很好,就是太短了

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

 html
<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



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} }

直接使用

 diff
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


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


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就全部是数据的来源,非常精简丝滑


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一次

 html
<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>

具体看这里sfc-script-setup.md

欢迎大家关注我和大帅*, 大家想让他写点啥文章,给我点赞留言可能速度更快 一起早起看书吧

那个忙了一夜的Vue3动画很好,就是太短了


那个忙了一夜的Vue3动画很好,就是太短了

  • 这是我们团队的开源项目 element3 欢迎试用和star
  • 一个支持 vue3 的前端组件库

作者:蜗牛老湿_大圣
链接:https://juejin.im/post/6891640356543627278

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

本文著作权归作者所有,如若转载,请注明出处

转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com

标题:那个忙了一夜的Vue3动画很好,就是太短了

链接:https://www.javascriptc.com/4550.html

« 2020天猫双11前端体系的建设与挑战
LeetCode 093. 复原IP地址»
Flutter 中文教程资源

相关推荐

QR code