小論組件的抽象和封裝

我們都知道函數(shù)的封裝和重用峭咒,將具有相同功能的抽象成函數(shù)方法税弃,在需要的時(shí)候直接傳遞不同的參數(shù)進(jìn)行調(diào)用即可。我們同時(shí)應(yīng)該也清楚一些無益的體力勞動(dòng)我們可以避免凑队,簡單的封裝可以使代碼量更少则果,在有助于性能優(yōu)化的同時(shí)還可以減少錯(cuò)誤的發(fā)生。我們毋庸置疑:代碼寫得越多漩氨,出現(xiàn)bug的幾率越大西壮。
當(dāng)然在我們開發(fā)頁面的時(shí)候,具有類似功能的我們可以抽象成公共組件叫惊,例如一個(gè)小彈窗款青,ip輸入......乃至整個(gè)頁面邏輯的封裝,這樣我們就能大容量的減輕代碼的耦合霍狰。
我理解的所謂公共組件其實(shí)就是這個(gè)組件在被引用的時(shí)候可能涉及到所有功能的并集抡草,也就是所有的功能點(diǎn),這樣我們會(huì)聯(lián)想到我們上學(xué)時(shí)候所學(xué)的交集和并集蔗坯。接下來我們就拿一個(gè)簡單的例子說明下康震,例如一個(gè)修改密碼的彈框,有這樣一個(gè)場景:我們在登錄的時(shí)候我們利用默認(rèn)密碼或者安全不太強(qiáng)的密碼登錄他會(huì)提示我們修改默認(rèn)密碼宾濒,如圖1腿短,它默認(rèn)有驗(yàn)證碼輸入:


圖1

還有一種情況我們登錄成功,在登錄的情況下,我們也有修改密碼的入口橘忱,這時(shí)候如圖2赴魁,他沒有要求輸入驗(yàn)證碼


圖2

這個(gè)例子很小但也可以利用來體現(xiàn)整個(gè)設(shè)計(jì)過程圖3
圖3

我們考慮這個(gè)功能的時(shí)候我們需要考慮這個(gè)功能的全面性,我們公共組件如果只是公共功能的話钝诚,整個(gè)組件我也就能實(shí)現(xiàn)類似于圖2的狀態(tài)尚粘,但我們需要驗(yàn)證碼的時(shí)候,調(diào)用公共組件的時(shí)候敲长,我無論如何也顯示不出來郎嫁,沒有集成在公共組件里怎么實(shí)現(xiàn)?所以公共組件是包含了你分析了在不同地方引用可能出現(xiàn)的所有功能點(diǎn)祈噪,他是所有功能點(diǎn)的并集泽铛。就像一個(gè)商店賣東西,每個(gè)人去買東西買的可能不一樣辑鲤,但每個(gè)人買的時(shí)候盔腔,你盡可能保證有每個(gè)人需要的那個(gè)東西,公共組件也是這樣月褥,我只要用這個(gè)功能你一定得有弛随。扯著扯著感覺好像再說框架一樣,每個(gè)框架引用的時(shí)候你可能只用一部分API宁赤,但他有很多API舀透,你不必?fù)?dān)心,總有人能用到决左。
這樣我們分析了這樣一個(gè)小小的組件愕够,接下來我們該考慮如何實(shí)現(xiàn)它:接下來我們用vue舉例,其實(shí)react等其它框架是一樣的:

驗(yàn)證碼顯示隱藏佛猛,我們肯定想到利用v-if或v-show去控制惑芭,這里我們因?yàn)闆]有頻繁的顯示隱藏,所以為了降低初始開銷继找,我們用v-if

 <div class="auth-code" v-if="authCodeShow">
            <p class="form-label">
              <span class="form-label-name">驗(yàn)證碼:</span>
            </p>
            <input type="text" v-model="confirmCode">
            <img id="img-rand-code" ref="codeImg" :src="codeUrl" @click="changeCode" alt="驗(yàn)證碼">
</div>

通過變量authCodeShow去控制遂跟,這時(shí)候我們考慮這個(gè)參數(shù)應(yīng)該由誰去控制?因?yàn)樵诟附M件引用公共組件的時(shí)候我們才會(huì)考慮他的顯隱婴渡,例如在登錄頁顯示驗(yàn)證碼幻锁,在登陸后不顯示,這樣我們明白他的顯隱是由父組件控制的缩搅,所以這個(gè)應(yīng)該是父組件利用props傳進(jìn)來的:

   props: {
      authCodeShow: {
        type: Boolean,
        default: false
      }
    }

接下來我們還應(yīng)該考慮這個(gè)彈框的顯示隱藏越败,我們肯定是通過父組件中的修改密碼按鈕觸發(fā)的,所以我們控制整個(gè)組件顯示隱藏的也在父組件我們用isShow去控制硼瓣,

// 父組件中調(diào)用子組件
<changePassPop ref="changePass" v-if="popShow"></changePassPop>

我們根據(jù)圖4可以看出我們可以通過彈框中的X 和取消究飞,確定按鈕去關(guān)閉彈窗置谦,自己關(guān)閉自己但我們應(yīng)該仔細(xì)想想,控制子組件的顯示隱藏的參數(shù)在父組件亿傅,所以操作的時(shí)候我們需要同時(shí)改變父組件的值媒峡,所以同時(shí)我們還應(yīng)通過props傳進(jìn)一個(gè)值isShow用來控制彈框的顯示隱藏

<changePassPop ref="changePass" v-if="popShow" :isShow.sync="popShow"></changePassPop>

這里我用了sync修飾符,他的功能其實(shí)就是函數(shù)回調(diào)更改父組件的值葵擎,并不是數(shù)據(jù)的雙向綁定(單項(xiàng)數(shù)據(jù)流也不允許)谅阿,sync的用法這應(yīng)該都知道,不知道的可以穿越 sync修飾符的講解
因?yàn)樵诶永镂矣昧薳lement-ui中的dialog酬滤,所以他還需要一個(gè)show控制dialog的顯示隱藏签餐,模板是這樣

<template>
  <div>
    <div class="model">
      <el-dialog :visible.sync="show" :modal="false" size="tiny" top="20%">
        <div class="form">
          <div>
            <p class="form-label">
              <span class="form-label-name">用戶名:</span>
            </p>{{username ? username : userName}}</div>
          <div>
            <p class="form-label">
              <span class="form-label-name">舊密碼:</span>
            </p>
            <input type="password" v-model="oldPass">
          </div>
          <div>
            <p class="form-label">
              <span class="form-label-name">新密碼:</span>
            </p>
            <input type="password" v-model="newPass">
          </div>
          <div>
            <p class="form-label">
              <span class="form-label-name">確認(rèn)新密碼:</span>
            </p>
            <input type="password" v-model="confirmNewPass">
          </div>
          <div class="auth-code" v-if="authCodeShow">
            <p class="form-label">
              <span class="form-label-name">驗(yàn)證碼:</span>
            </p>
            <input type="text" v-model="confirmCode">
            <img id="img-rand-code" ref="codeImg" :src="codeUrl" @click="changeCode" alt="驗(yàn)證碼">
          </div>
          <div slot="footer" class="foot clearFix">
            <el-button @click="show=false">取 消</el-button>
            <el-button type="primary" @click="changeDefaultPsw">確 定</el-button>
          </div>
        </div>
      </el-dialog>
    </div>
  </div>
</template>

所以在控制show的時(shí)候同時(shí)改變父組件中的popShow的值,這里我們很容易聯(lián)想到watch方法

watch: {
      show() {
        this.$emit('update:isShow', false)
      }
    },

這樣我們子組件控制了自己的顯示隱藏盯串。
接下來我們繼續(xù)看功能氯檐,用戶名是智能添加不是自己輸入那種,其他的舊密碼和新密碼等都是自己輸入的体捏,存在于公共組件的自己的data對象里面冠摄,接下來我們可能很快想到Vuex狀態(tài)管理進(jìn)行數(shù)據(jù)共享,這樣是沒問題的几缭,初始化state河泳,然后通過狀態(tài)管理。這種方法可行年栓,但是單純的一個(gè)純父子組件的數(shù)據(jù)傳遞我感覺沒有必要用狀態(tài)管理拆挥,雖然我當(dāng)初也是利用vuex做的,但我們應(yīng)該明白我們利用Vuex我們是為了更好的追蹤共享數(shù)據(jù)的變化韵洋。講到這里有必要講講vuex了竿刁。有的人用了vuex黄锤,感覺還不錯(cuò)搪缨,就好像全局變量存儲(chǔ)庫,我不用認(rèn)真去考慮數(shù)據(jù)的流向props,這種想法是錯(cuò)的鸵熟!我們不能將vuex當(dāng)成localStorage和sessionStorage去使用副编,vuex是為了更好地去追蹤共享state的變化,為了避免更繁雜的數(shù)據(jù)流向向下圖這樣:


圖5

當(dāng)子組件1想想向組件2中進(jìn)行傳值流强,鑒于數(shù)據(jù)的單向流動(dòng)痹届,我們需要經(jīng)過父組件(當(dāng)然是通過函數(shù)回調(diào)傳的),然后在傳給組件2打月,當(dāng)然感覺這樣也還沒什么队腐,若果他們的父組件也是兄弟組件,他們有共同的爺爺奏篙,你需要傳給他的爺爺柴淘,再通過他們爺爺往父組件二進(jìn)行傳遞迫淹,如果再嵌套深一點(diǎn),這TM還不把自己傳亂


圖6

所以這時(shí)候vuex就能很好地解決我們的問題为严,共享state也能更好的進(jìn)行追蹤敛熬,同時(shí)更改state只能通過mutation進(jìn)行更改,這樣有了錯(cuò)誤也能更的追蹤第股,當(dāng)項(xiàng)目大的時(shí)候我們可以好好利用vuex的優(yōu)點(diǎn)应民,但是我們知道每次加載頁面的時(shí)候都要初始化store,若果數(shù)據(jù)太多的時(shí)候夕吻,初始化的時(shí)間就比較長诲锹,這樣就會(huì)給人造成一種加載速度慢的印象,所以我們說沒有必要放在vuex的數(shù)據(jù)就不要放涉馅,千萬不能把它當(dāng)成本地存儲(chǔ)辕狰,不要浪費(fèi)了作者的設(shè)計(jì)靈魂。
跑偏了控漠,趕緊回來蔓倍。剛才那個(gè)用戶名的我們其實(shí)存在父組件,接著我們再往下看盐捷,確定按鈕肯定把你的表單提交給后臺(tái)偶翅,但這時(shí)我們又有這樣的顧慮,其實(shí)也真的是顧慮碉渡。我們提交的后臺(tái)接口不一樣聚谁,擦!后臺(tái)這是腫么了滞诺,砍了他形导。哈哈!有時(shí)候這是一個(gè)假設(shè)习霹,但沒準(zhǔn)也可能遇到朵耕,所以確定按鈕綁定的方法我們不能寫死,因?yàn)榻涌诓灰粯勇锪芤叮∷晕覀兛梢赃@樣給公共組件開放個(gè)方法阎曹,confirmChangePsw,我們讓它綁定父組件的方法,提交的方法在父組件實(shí)現(xiàn)因?yàn)楦附M件是可控的煞檩,公共組件只是為了更大的兼容所有的功能要求处嫌,這樣我們在公共組件中這樣定義
// 公共組件
<el-button type="primary" @click="changeDefaultPsw">確 定</el-button>
  // 修改默認(rèn)密碼
      changeDefaultPsw() {
        this.result = this.checkInput('oldPass') && this.checkInput('newPass') && 
         this.checkInput('confirmNewPass')
        if (this.authCodeShow) {
          this.result = this.result && this.checkInput('confirmCode')
        }
        if (this.result) {
          this.show = false;
          this.$emit('confirmChangePsw')
        }
      }
// 父組件調(diào)用公共組件
<changePassPop ref="changePass" v-if="popShow" :isShow.sync="popShow" @confirmChangePsw="handleChangePsw"></changePassPop>

我們通過點(diǎn)擊確定按鈕觸發(fā)了changeDefaultPsw函數(shù),但是這個(gè)方法其實(shí)是為了觸發(fā)子組件綁定的自定義方法confirmChangePsw斟湃,自定義confirmChangePsw方法其實(shí)調(diào)用的是父組件的handleChangePsw方法
可能這時(shí)我們開始懷疑為啥這樣做熏迹?組件自定義方法什么鬼?接下來我們來說說組件的一些特質(zhì)凝赛,請?jiān)徫疫@個(gè)愛引申的毛病
組件與組件之間是相互獨(dú)立的注暗,組件中的方法只能在本組件調(diào)用厨剪,數(shù)據(jù)只能通過單項(xiàng)數(shù)據(jù)流傳遞公共組件在父組件調(diào)用的時(shí)候我們的公共組件訪問的數(shù)據(jù)和方法都是父組件里面的

// 父組件調(diào)用公共組件
<changePassPop ref="changePass" v-if="popShow" :isShow.sync="popShow" @confirmChangePsw="handleChangePsw"></changePassPop>

其實(shí)就類似于函數(shù)的私有作用域

function father(params) {
  function son1(params) {
    var a = 1
  }
  function son2(params) {
    console.log(a); // 調(diào)用的時(shí)候會(huì)報(bào)錯(cuò)
  }
}

因?yàn)楹瘮?shù)會(huì)形成一個(gè)私有作用域不允許其他無關(guān)函數(shù)訪問,有人可能會(huì)說這樣不就行了

function father(params) {
  var a = 1
  function son1(params) {
  }
  function son2(params) {
    console.log(a); // 1
  }
}

對呀友存!像上面這樣是沒問題的祷膳!所以剛才我說的是組件就類似于函數(shù)的私有作用域,類似屡立,類似V背俊!但不完全一樣膨俐,組件有著更嚴(yán)格的權(quán)限勇皇,子組件也不能共享父組件的數(shù)據(jù),如果你需要父組件的某個(gè)數(shù)據(jù)只能通過props傳遞過來
繼續(xù)回來焚刺。敛摘。。乳愉。
我們相當(dāng)于給確定按鈕一個(gè)開放的權(quán)限兄淫,我給你暴露的方法,但如何定義由你自己控制蔓姚。
當(dāng)然還有一些ref拿值的方法捕虽!自己看代碼去體會(huì)吧!
我貼下代碼

<template>
  <div>
    <div class="model">
      <el-dialog :visible.sync="show" :modal="false" size="tiny" top="20%">
        <div class="form">
          <div>
            <p class="form-label">
              <span class="form-label-name">用戶名:</span>
            </p>{{username ? username : userName}}</div>
          <div>
            <p class="form-label">
              <span class="form-label-name">舊密碼:</span>
            </p>
            <input type="password" v-model="oldPass">
          </div>
          <div>
            <p class="form-label">
              <span class="form-label-name">新密碼:</span>
            </p>
            <input type="password" v-model="newPass">
          </div>
          <div>
            <p class="form-label">
              <span class="form-label-name">確認(rèn)新密碼:</span>
            </p>
            <input type="password" v-model="confirmNewPass">
          </div>
          <div class="auth-code" v-if="authCodeShow">
            <p class="form-label">
              <span class="form-label-name">驗(yàn)證碼:</span>
            </p>
            <input type="text" v-model="confirmCode">
            <img id="img-rand-code" ref="codeImg" :src="codeUrl" @click="changeCode" alt="驗(yàn)證碼">
          </div>
          <div slot="footer" class="foot clearFix">
            <el-button @click="show=false">取 消</el-button>
            <el-button type="primary" @click="changeDefaultPsw">確 定</el-button>
          </div>
        </div>
      </el-dialog>
    </div>
  </div>
</template>

<script>
  import {
    mapState
  } from 'vuex'
  import {
    STI_AJAX_BASEURL
  } from 'commons/constant'
  const CODE_URL = `${STI_AJAX_BASEURL}/login/vcode`
  export default {
    props: {
      isShow: {
        type: Boolean,
        default: false
      },
      authCodeShow: {
        type: Boolean,
        default: false
      },
      userName: {
        type: String
      }
    },
    computed: {
      ...mapState({
        username: state => state.userInfo.username,
        userId: state => state.userInfo.userId
      })
    },
    watch: {
      show() {
        this.$emit('update:isShow', false)
      }
    },
    mounted() {
      if (this.authCodeShow) {
        this.changeCode()
      }
    },
    data() {
      return {
        result: null,
        show: true,
        oldPass: '',
        newPass: '',
        confirmNewPass: '',
        confirmCode: '',
        codeUrl: CODE_URL,
        tips: {
          oldPass: '請輸入舊密碼',
          newPass: '新密碼不能為空',
          confirmNewPass: '兩次輸入的密碼不一致',
          authcode: '請輸入驗(yàn)證碼'
        }
      };
    },
    methods: {
      // 檢查輸入內(nèi)容
      checkInput(param) {
        if (this.$data[param]) {
          if (param === 'confirmNewPass') {
            if (this.confirmNewPass !== this.newPass) {
              alert('兩次輸入的密碼不一致')
            }
          }
          return true
        } else {
          alert(this.tips[param])
          return false
        }
      },
      // 更換驗(yàn)證碼
      changeCode() {
        this.codeUrl = CODE_URL + '?' + new Date().getTime()
      },
      // 修改默認(rèn)密碼
      changeDefaultPsw() {
        this.result = this.checkInput('oldPass') && this.checkInput('newPass') && this.checkInput('confirmNewPass')
        if (this.authCodeShow) {
          this.result = this.result && this.checkInput('confirmCode')
        }
        if (this.result) {
          this.show = false;
          this.$emit('confirmChangePsw')
        }
      }
    }
  }

</script>

<style lang="less" scoped>
  .clearFix:after {
    display: block;
    height: 0;
    content: '';
    clear: both;
    overflow: hidden;
  }

  .form {
    >div {
      height: 40px;
      margin-bottom: 6px;
      >input {
        height: 36px;
        width: 60%;
        line-height: 36px;
        padding-left: 8px;
      }
      .form-label {
        float: left;
        width: 100px;
        height: 38px;
        margin-right: 20px;
        .form-label-name {
          float: right;
        }
      }
    }
    .foot {
      width: 100%;
      margin-top: 20px;
      padding-left: 56%;
    }
  }

</style>

通過上面的分析我們可以歸納到公共組件的抽象方法

  1. 先分析我可能涵蓋的功能需求
  2. 需要傳哪些值進(jìn)來
  3. 需要開放哪些方法便于調(diào)用該組件的組件自己定義靈活控制
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末坡脐,一起剝皮案震驚了整個(gè)濱河市泄私,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌备闲,老刑警劉巖晌端,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異恬砂,居然都是意外死亡咧纠,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門觉既,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惧盹,“玉大人,你說我怎么就攤上這事瞪讼。” “怎么了粹断?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵符欠,是天一觀的道長。 經(jīng)常有香客問我瓶埋,道長希柿,這世上最難降的妖魔是什么诊沪? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮曾撤,結(jié)果婚禮上端姚,老公的妹妹穿的比我還像新娘。我一直安慰自己挤悉,他們只是感情好渐裸,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著装悲,像睡著了一般昏鹃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诀诊,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天洞渤,我揣著相機(jī)與錄音,去河邊找鬼属瓣。 笑死载迄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抡蛙。 我是一名探鬼主播宪巨,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼溜畅!你這毒婦竟也來了捏卓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤慈格,失蹤者是張志新(化名)和其女友劉穎怠晴,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浴捆,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蒜田,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了选泻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冲粤。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖页眯,靈堂內(nèi)的尸體忽然破棺而出梯捕,到底是詐尸還是另有隱情,我是刑警寧澤窝撵,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布傀顾,位于F島的核電站,受9級(jí)特大地震影響碌奉,放射性物質(zhì)發(fā)生泄漏短曾。R本人自食惡果不足惜寒砖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嫉拐。 院中可真熱鬧哩都,春花似錦、人聲如沸婉徘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽判哥。三九已至献雅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間塌计,已是汗流浹背挺身。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锌仅,地道東北人章钾。 一個(gè)月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓抖拦,卻偏偏與公主長得像还蹲,于是被迫代替她去往敵國和親翘鸭。 傳聞我的和親對象是個(gè)殘疾皇子箱蟆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 序 今年大前端的概念一而再再而三的被提及,那么大前端時(shí)代究竟是什么呢导犹?大前端這個(gè)詞最早是因?yàn)樵诎⒗飪?nèi)部有很多前端開...
    一縷殤流化隱半邊冰霜閱讀 11,214評論 19 92
  • 無奈地翻著日歷凤优,再一次感嘆:“時(shí)間不多了啊伤提,但我還有希望报腔!” 高中篇 如愿以償?shù)乜邕M(jìn)了重點(diǎn)高中的大門株搔,躊躇滿志,信...
    竹隱君閱讀 204評論 0 1
  • 姓名:姚柳~公司:成都和創(chuàng)服飾有限公司 【日精進(jìn)打卡第29天】 【知~學(xué)習(xí)】 《六項(xiàng)精進(jìn)》0遍共12遍 《大學(xué)》0...
    柳_94de閱讀 93評論 0 0
  • 變天了 明明是朗日晴空 轉(zhuǎn)瞬就電閃雷鳴 別人都有傘 或有躲避的屋檐 唯獨(dú)我 措手不及一臉茫然 如生命的殘篇
    行走的撒哈拉閱讀 178評論 0 1
  • dva 官網(wǎng)使用的網(wǎng)絡(luò)請求庫是 dva/fetch纯蛾,個(gè)人比較喜歡 axios纤房,因?yàn)榭梢钥缬颍鞣N攔截使用起來也很舒...
    dkvirus閱讀 12,448評論 8 20