1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        那個忙了一夜的Vue3動畫很好,就是太短了

        共 5157字,需瀏覽 11分鐘

         ·

        2021-01-30 23:47

        轉(zhuǎn)自:?蝸牛老濕_大圣

        這個文章其實很簡單, 只要能說明composition的好處,就是極好的,我們用一個非常簡單的萬金油場景,比如我們有一個非常簡單的to do list

        回顧Option

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

        需求復(fù)雜之后,就會多出watch,computed,inject,provide等配置,這個.vue文件也會逐漸增大

        ff7594db2233d681e9630b98409cec39.webp

        Option的缺陷--反復(fù)橫跳

        相信大部分同學(xué)都維護(hù)過超過200行的.vue組件,新增或者修改一個需求,就需要分別在data,methods,computed里修改 ,滾動條反復(fù)上下移動,我稱之為『反復(fù)橫跳』 比如我們簡單的加個拍腦門的需求 加個累加器 ,這種寫代碼上下反復(fù)橫條的感覺, 相信大家都懂的,?

        cb3e1faa4b484dd2af2d6fe0cb636f45.webp

        動畫演示28e339671073e8dd15985d62d38be843.webp

        <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

        反復(fù)橫跳的本質(zhì),在于功能的分塊組織,以及代碼量太大了,如果我們能把代碼控制在一屏,自然就解決了,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(){
        ?...
        ??},
        ...
        }

        這樣確實拆分了代碼,但是有一個賊嚴(yán)重的問題,就是不打開counter.js,App.vue里的this上,count,add這些屬性,是完全不知道從哪來的,你不知道是mixin,還是全局install,還是Vue.prototype.count設(shè)置的,數(shù)據(jù)來源完全模糊,調(diào)試爽死你,這也是option的一個大問題,this是個黑盒,template里寫的count和double,完全不知道從哪來的

        mixin命名沖突

        如果有兩個mixin,就更有意思了,比如我們又有一個需求,實時顯示鼠標(biāo)的坐標(biāo)位置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)
        ??}
        }

        這是是一個獨立維護(hù)的mixin,可能在N個地方用到,他根本不知道會不會有人和他沖突,然后用一下

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

        c00dd8904ebd152b5cc0d9e36843aec3.webp兩個mixin里都有double這個數(shù),尷尬,看效果 ,lsp的count被覆蓋了 很尷尬,而且在App.vue這里,你完全不知道這個double到底是哪個,調(diào)試很痛苦

        Composition

        composition就是為了解決這個問題存在的,通過組合的方式,把零散在各個data,methods的代碼,重新組合,一個功能的代碼都放在一起維護(hù),并且這些代碼可以單獨拆分成函數(shù) ,也就是大帥的這兩個gif

        b2938dcb34d860e16f598816de4ce6b1.webp6730089b3ba10e93bf1967f0ae3d67c6.webp

        我們用vue3演示一下功能,具體api就不解釋了 直接vue3文檔搞起就可以

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

        利用函數(shù)我們可以吧功能完整獨立的拆分成模塊或者函數(shù),方便組織代碼,并且解決了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}
        }


        直接使用

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

        再來一個鼠標(biāo)位置也不在話下,而且可以很好地利用解構(gòu)賦值的別名,解決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

        到這里應(yīng)該就把大帥的文章缺的代碼補了一下,不過有的同學(xué)可能,還有一個小小的吐槽,那就是setup函數(shù)最后的return也是集中的,如果行數(shù)太多,一樣會橫條一下下,這個好解決,因為本身我們可以吧todos也抽離成函數(shù),這樣setup就全部是數(shù)據(jù)的來源,非常精簡絲滑

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

        是不是賊爽呢,如果有些同學(xué)就是不想啥都抽離,還是覺得統(tǒng)一return很麻煩, 我們可以使用vue3的setup script功能,把setup這個配置也優(yōu)化掉 一個功能export一次

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

        具體看這里:

        https://github.com/vuejs/rfcs/blob/sfc-improvements/active-rfcs/0000-sfc-script-setup.md

        ebe0cc1ad0b123684a426e82e5f6081a.webp



        最后
        
                        
        瀏覽 70
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            一女两男三p吞精喝尿 | 老头边吃奶边弄进去呻 | 喝尿坐脸上h辣文 | 人与野鲁xxxx毛片十二寡妇 | 国产做爰又粗又大又硬又大视频 | 老师露出强行让男生揉小说 | 中文无码专区 | 公交车上荫蒂添的好舒服的电影 | 91蝌蚪91PORNY 国语 | 手机看一级片 |