<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【Vuejs】1058- 盤點 Vue3 那些有趣的 API

          共 11506字,需瀏覽 24分鐘

           ·

          2021-08-25 10:15

          從開始的Vue到Vue2再到現(xiàn)在的Vue3,前端開發(fā)人員一直被迫營業(yè),永遠也追不上尤大大寫代碼的腳步?? 。

          今天我們放慢追趕的腳步,一起來看看尤大大在Vue3書寫了哪些有趣的API,有些可能說不上哪里有趣,但是看起來就是比之前舒服一些(強迫癥在線發(fā)作...)。文末有尤大大連夜寫的新需求

          data選項哪去了?

          回想我們在Vue2中創(chuàng)建響應(yīng)式數(shù)據(jù)是這樣的:

          ...
          data() {
            return {
              num:1  
            }
          }
          ...

          而Vue3會 setup 組合式API這個選項了,為此引入了ref、reactive等響應(yīng)式API,來看看怎么寫的吧:

          <template>
            <div>num:{{num}}</div>
            <div>refNum:{{refNum}}</div>
            <div>state對象:名字:{{state.name}},年齡:{{state.age}}</div>
          </template>

          <script>
          import { defineComponent, reactive, ref } from "vue"
          export default defineComponent({
            setup() {
              const num = 1  /
          /不具備響應(yīng)式
              const refNum = ref(2)
              const state = reactive({
                name: '小黃',
                age: 18
              })
              return {
                num,
                refNum,
                state
              }
            }
          })
          </
          script>

          你可以看到Vue2的data選項已經(jīng)被ref、reactive這樣的API給替換了。

          那么在setup如何對ref、reactive聲明的數(shù)據(jù)修改操作呢?

          ...
          setup() {
            const count = ref(1)
            console.log(count.value) // => 1
            count.value++
            console.log(count.value) // => 2

            const str = ref('小黃')
            console.log(str.value) // => 小黃
          }
          ...

          可以看到使用 ref 聲明的數(shù)據(jù)可以直接使用 .value 這種形式更新數(shù)據(jù)。但是你也許會疑問為什么在<tempalte></template>視圖中為什么不需要 .value ,其實是vue內(nèi)部做了操作。另外,打印一下可以看到ref聲明數(shù)據(jù):

          reactive 也是響應(yīng)式的聲明,它是返回對象的響應(yīng)式副本

          ...
          setup() {
            const state = reactive({
              name'小黃',
              age18
            })
            console.log(state) // =>
          }
          ...

          我們直接打印下state對象,它其實是一個Proxy對象:

          ...
          setup() {
            console.log(state.name) // => 小黃
            console.log(state.age) // => 18
            //對數(shù)據(jù)更改
            setTimeout(() => {
              state.age = 20
              console.log(state.age) // => 20
            }, 1000)
          }
          ...

          也許你已經(jīng)注意到了開頭舉的例子——所有聲明的變量都被 return 出去了,這看起來有什么好處呢?

          • 可以更加清晰得知道,數(shù)據(jù)與視圖之前的關(guān)系。setup里對數(shù)據(jù)操作,視圖渲染return出來的數(shù)據(jù)
          • 更好的保護組件獨有的數(shù)據(jù),不需要暴露給視圖的數(shù)據(jù)我就不寫在return里中

          再者,你可能會討厭為什么通過 reactive 聲明的數(shù)據(jù)在視圖中使用的時候又要 xx.屬性名 的方式才行,有辦法不寫嗎?有!尤大大滿足開發(fā)者的一切便捷編碼習慣。toRefs 就出來了,在結(jié)合ES9的擴展運算符 ... 就可以滿足要求了??????

          <template>
            //這里不再需要state包裹了,屬性已經(jīng)被展開return出來了
            <div>state對象:名字:{{name}},年齡:{{age}}</div>
          </template>

          <script>
          import {defineComponent, reactive, toRefs } from "vue"
          export default defineComponent({
            setup() {
              const state = reactive({
                name: '小黃',
                age: 18
              })
              return {
                ...toRefs(state)
              }
            }
          })
          </
          script>

          computed計算屬性更好看了?

          計算屬性在使用上好像變得更加令人愉快了,先來看Vue2的寫法吧

          ...
          data(){
            return {
              str:'小黃'
            }
          },
          computed: {
            newStr() { // 對data的數(shù)據(jù)重新處理
              return this.str + 'hha'
            },
            list() { // 獲取Vuex中的數(shù)據(jù)(經(jīng)常用到)
              return this.$store.state.btnMenu.btnPowerList
            }
          },
          mounted(){}
          ...

          中規(guī)中矩沒得說,這里computed是當作分段式的組件內(nèi)部方法

          重點看看Vue3中computed如何實現(xiàn)。

          ...
          setup() {
            const count = ref(3)
            console.log(count.value) // => 3
            const newCount = computed(() => count.value + 1)
            console.log(newCount.value) // => 4
          }
          ...

          倘若需要在計算屬性中獲取Vuex的數(shù)據(jù)的話,那么可以使用Vuex提供的 useStore 模塊獲取到store的實例

          import { computed, defineComponent } from "vue"
          import { useStore } from 'vuex'
          export default defineComponent({
            setup() {
              const store = useStore()
              const list = computed(() => store.state.list)
              return {
                list
              }
            }
          })

          watch與watchEffect監(jiān)聽?

          watch監(jiān)聽在Vue使用的場景也是比較多的。老規(guī)矩,先來看看Vue2是怎么寫的,有對比才有傷害?? ??

          ...
          watch: {
            bankName(newValue,oldValue) {
              consoel.log(newValue,oldValue)
            }
          },
          methods:{}
          ...

          來看看Vue3怎么寫吧

          <template>
            <div>count:{{count}}</div>
          </template>

          <script>
          import { defineComponent, ref, watch } from "vue"
          export default defineComponent({
            setup() {
              const count = ref(10)
              setTimeout(() => {
                count.value = 20
              }, 2000)
              watch(count, (newValue, oldValue) => {
                console.log(oldValue)
                console.log(newValue)
              })
              return {
                count
              }
            }
          })
          </
          script>

          然后watch監(jiān)聽到count變化,預(yù)期地打印

          當我們想定義一個響應(yīng)式對象怎么辦呢?這里通常選用 reactive ,當然ref也可以定義一個對象。

          <template>
            <div>person對象:名字:{{person.name}},年齡:{{person.age}}</div>
          </template>

          <script>
          import { defineComponent, reactive, watch } from "vue"
          export default defineComponent({
            setup() {
              const person = reactive({
                name: '前端發(fā)現(xiàn)',
                age: 18
              })
              setTimeout(() => {
                person.name = '我是reactive定義的name屬性更改后的數(shù)據(jù)'
              }, 2000)

              watch(() => person.name, (newValue, oldValue) => {
                console.log(oldValue)
                console.log(newValue)
              })
              return {
                person
              }
            }
          })
          </
          script>
          ...

          可以看到,這里問采用了函數(shù)的形式返回了需要監(jiān)聽的數(shù)據(jù).() => person.name。來看看案例的效果:

          以上都是監(jiān)聽單一的數(shù)據(jù),多個屬性怎么監(jiān)聽呢?直接上??

          <template>
            <div>count:{{count}}</div>
            <div>person對象:名字:{{person.name}},年齡:{{person.age}}</div>
          </template>

          <script>
          import { defineComponent, reactive, ref, watch } from "vue"
          export default defineComponent({
            setup() {
              const count = ref(10)
              const person = reactive({
                name: '前端發(fā)現(xiàn)',
                age: 18
              })
              setTimeout(() => {
                count.value = 20
                person.name = '我是reactive定義的name屬性更改后的數(shù)據(jù)'
                person.age = 22
              }, 2000)

              watch([count, () => person.name, () => person.age], ([newCount, newName, newAge], [oldCount, oldName, oldAge
              ]) => {
                console.log(oldCount, oldName, oldAge)
                console.log(newCount, newName, newAge)
              })
              return {
                count,
                person
              }
            }
          })
          </
          script>

          直接數(shù)組的形式監(jiān)聽多個數(shù)據(jù)

          除了watch之外,Vue3還誕生出了 watchEffect ,看起來像是watch Plus(我暫且這樣理解吧),官方是怎么定義這個API的呢?

          在響應(yīng)式地跟蹤其依賴項時立即運行一個函數(shù),并在更改依賴項時重新運行它。

          //當然這里是需要從vue導入模塊滴
          import { watchEffect } from "vue"
          ...
          const count = ref(10)
          watchEffect(() => console.log(count.value)) // => 10

          setTimeout(() => {
            count.value = 20 立即執(zhí)行watchEffect方法,調(diào)出打印 // => 20
          }, 1000)

          先看效果:

          可以看到使用 watchEffect 并沒有之前 watch 的更改前數(shù)據(jù),也不需要傳入監(jiān)聽的數(shù)據(jù)源 ,而是直接執(zhí)行一個函數(shù),可以獲取到更新后的數(shù)據(jù)。

          同樣的,監(jiān)聽多個的話也是可以的

          ...
          watchEffect(() => {
            console.log(count.value)
            console.log(person.name)
          })
          ...

          總結(jié):watch ??  watchEffect

          • watchEffect 不需要指定監(jiān)聽的屬性,他會自動的收集依賴,只要在回調(diào)函數(shù)中引用到了響應(yīng)式的屬性,那么當這些屬性變動的時候,這個回調(diào)都會執(zhí)行,而 watch 只能監(jiān)聽指定的屬性而作出變動(v3開始能夠同時指定多個)
          • watch 能夠獲取到新值與舊值(更新前的值),而 watchEffect 是拿不到的
          • watchEffect 在組件初始化的時候就會執(zhí)行一次用以收集依賴,收集到的依賴發(fā)生變化時再執(zhí)行。而 watch 則是直接指定依賴項

          片段是啥?

          在 Vue 3 中,組件現(xiàn)在正式支持多根節(jié)點組件,即片段!

          <template>
            <div>我是其中一個div</div>
            <header>...</header>
            <footer>...</footer>
          </template>

          組件狀態(tài)驅(qū)動的 CSS 變量真香?

          聽起來就感覺非常逼格,它其實就是將css用到的屬性值在組件內(nèi)定義一個變量去替換。目前這個API目前還在試驗性階段!

          <template>
            <div class="myClass">我是SFC style CSS variable injection</div>
          </template>

          <script>
          import { reactive, ref, toRefs } from "vue"
          export default {
            setup() {
              const minColor = ref('red')
              const styleJs = reactive({
                color: 'blue',
                fontSize: '20px',
                fontWeight: '700',
                textDecoration: 'underline'
              })
              return { /
          / 這里不能忘記return出去
                minColor,
                ...toRefs(styleJs),
              }
            }
          }
          </
          script>

          <style lang="scss" scoped>
          .myClass {
            text-decorationv-bind(textDecoration);
            font-weightv-bind(fontWeight);
            colorv-bind(minColor);
            font-sizev-bind(fontSize);
          }
          </style>

          來看看效果:

          可以看到 myClass 類名加上我們使用 v-bind 綁定的CSS屬性值

          值得說明的是,在return中,我使用了 ...toRefs() API,不使用的話那么在寫綁定styleJs對象的屬性值時就需要注意一下

          .myClass {
            text-decorationv-bind('styleJs.textDecoration');
            font-weightv-bind('styleJs.fontWeight');
            colorv-bind(minColor);
            font-sizev-bind('styleJs.fontSize');
          }

          現(xiàn)在看到的樣式綁定上的屬性名上會有一點點的變化:

          有興趣的朋友可以看看咱們尤大大對 組件狀態(tài)驅(qū)動的 CSS 變量 的提案

          1. JavaScript 重溫系列(22篇全)
          2. ECMAScript 重溫系列(10篇全)
          3. JavaScript設(shè)計模式 重溫系列(9篇全)
          4. 正則 / 框架 / 算法等 重溫系列(16篇全)
          5. Webpack4 入門(上)|| Webpack4 入門(下)
          6. MobX 入門(上) ||  MobX 入門(下)
          7. 120+篇原創(chuàng)系列匯總

          回復“加群”與大佬們一起交流學習~

          點擊“閱讀原文”查看 120+ 篇原創(chuàng)文章

          瀏覽 66
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩乱轮小说与视频 | 四虎黄色网 | 久久国产操B视频 | 午夜综合在线 | 三级无码在线观看视频 |