日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
10個Vue開發(fā)技巧

路由參數(shù)解耦

一般在組件內(nèi)使用路由參數(shù),大多數(shù)人會這樣做:

 
 
 
 
  1. export default {
  2.     methods: {
  3.         getParamsId() {
  4.             return this.$route.params.id
  5.         }
  6.     }
  7. }

在組件中使用 $route 會使之與其對應(yīng)路由形成高度耦合,從而使組件只能在某些特定的 URL 上使用,限制了其靈活性。

正確的做法是通過 props 解耦

 
 
 
 
  1. const router = new VueRouter({
  2.     routes: [{
  3.         path: '/user/:id',
  4.         component: User,
  5.         props: true
  6.     }]
  7. })

將路由的 props 屬性設(shè)置為 true 后,組件內(nèi)可通過 props 接收到 params 參數(shù)

 
 
 
 
  1. export default {
  2.     props: ['id'],
  3.     methods: {
  4.         getParamsId() {
  5.             return this.id
  6.         }
  7.     }
  8. }

另外你還可以通過函數(shù)模式來返回 props

 
 
 
 
  1. const router = new VueRouter({
  2.     routes: [{
  3.         path: '/user/:id',
  4.         component: User,
  5.         props: (route) => ({
  6.             id: route.query.id
  7.         })
  8.     }]
  9. })

文檔:router.vuejs.org/zh/guide/es…

函數(shù)式組件

函數(shù)式組件是無狀態(tài),它無法實例化,沒有任何的生命周期和方法。創(chuàng)建函數(shù)式組件也很簡單,只需要在模板添加 functional 聲明即可。一般適合只依賴于外部數(shù)據(jù)的變化而變化的組件,因其輕量,渲染性能也會有所提高。

組件需要的一切都是通過 context 參數(shù)傳遞。它是一個上下文對象,具體屬性查看文檔。這里 props 是一個包含所有綁定屬性的對象。

函數(shù)式組件:

 
 
 
 
  1.     
  2.         
  3.             

    {{item.title}}

  4.             

    {{item.content}}

  5.         
  •     
  • 父組件使用:

     
     
     
     
     
     
     
     
    1. import List from '@/components/List.vue'
    2. export default {
    3.     components: {
    4.         List
    5.     },
    6.     data() {
    7.         return {
    8.             list: [{
    9.                 title: 'title',
    10.                 content: 'content'
    11.             }],
    12.             currentItem: ''
    13.         }
    14.     }
    15. }

    文檔:cn.vuejs.org/v2/guide/re…

    樣式穿透

    在開發(fā)中修改第三方組件樣式是很常見,但由于 scoped 屬性的樣式隔離,可能需要去除 scoped 或是另起一個 style 。這些做法都會帶來副作用(組件樣式污染、不夠優(yōu)雅),樣式穿透在css預(yù)處理器中使用才生效。

    我們可以使用 >>> 或 /deep/ 解決這一問題:

     
     
     
     
    1. 外層 >>> .el-checkbox {
    2.   display: block;
    3.   font-size: 26px;
    4.   .el-checkbox__label {
    5.     font-size: 16px;
    6.   }
    7. }
     
     
     
     
    1. /deep/ .el-checkbox {
    2.   display: block;
    3.   font-size: 26px;
    4.   .el-checkbox__label {
    5.     font-size: 16px;
    6.   }
    7. }

    watch高階使用

    1. 立即執(zhí)行

    watch 是在監(jiān)聽屬性改變時才會觸發(fā),有些時候,我們希望在組件創(chuàng)建后 watch 能夠立即執(zhí)行。

    可能想到的的方法就是在 create 生命周期中調(diào)用一次,但這樣的寫法不優(yōu)雅,或許我們可以使用這樣的方法:

     
     
     
     
    1. export default {
    2.     data() {
    3.         return {
    4.             name: 'Joe'
    5.         }
    6.     },
    7.     watch: {
    8.         name: {
    9.             handler: 'sayName',
    10.             immediate: true
    11.         }
    12.     },
    13.     methods: {
    14.         sayName() {
    15.             console.log(this.name)
    16.         }
    17.     }
    18. }

    深度監(jiān)聽在監(jiān)聽對象時,對象內(nèi)部的屬性被改變時無法觸發(fā) watch ,我們可以為其設(shè)置深度監(jiān)聽:

     
     
     
     
    1. export default {
    2.     data: {
    3.         studen: {
    4.             name: 'Joe',
    5.             skill: {
    6.                 run: {
    7.                     speed: 'fast'
    8.                 }
    9.             }
    10.         }
    11.     },
    12.     watch: {
    13.         studen: {
    14.             handler: 'sayName',
    15.             deep: true
    16.         }
    17.     },
    18.     methods: {
    19.         sayName() {
    20.             console.log(this.studen)
    21.         }
    22.     }
    23. }

    2. 觸發(fā)監(jiān)聽

    執(zhí)行多個方法使用數(shù)組可以設(shè)置多項,形式包括字符串、函數(shù)、對象:

     
     
     
     
    1. export default {
    2.     data: {
    3.         name: 'Joe'
    4.     },
    5.     watch: {
    6.         name: [
    7.             'sayName1',
    8.             function(newVal, oldVal) {
    9.                 this.sayName2()
    10.             },
    11.             {
    12.                 handler: 'sayName3',
    13.                 immaediate: true
    14.             }
    15.         ]
    16.     },
    17.     methods: {
    18.         sayName1() {
    19.             console.log('sayName1==>', this.name)
    20.         },
    21.         sayName2() {
    22.             console.log('sayName2==>', this.name)
    23.         },
    24.         sayName3() {
    25.             console.log('sayName3==>', this.name)
    26.         }
    27.     }
    28. }

    文檔:cn.vuejs.org/v2/api/#wat…

    watch監(jiān)聽多個變量

    watch本身無法監(jiān)聽多個變量。但我們可以將需要監(jiān)聽的多個變量通過計算屬性返回對象,再監(jiān)聽這個對象來實現(xiàn)“監(jiān)聽多個變量”

     
     
     
     
    1. export default {
    2.     data() {
    3.         return {
    4.             msg1: 'apple',
    5.             msg2: 'banana'
    6.         }
    7.     },
    8.     compouted: {
    9.         msgObj() {
    10.             const { msg1, msg2 } = this
    11.             return {
    12.                 msg1,
    13.                 msg2
    14.             }
    15.         }
    16.     },
    17.     watch: {
    18.         msgObj: {
    19.             handler(newVal, oldVal) {
    20.                 if (newVal.msg1 != oldVal.msg1) {
    21.                     console.log('msg1 is change')
    22.                 }
    23.                 if (newVal.msg2 != oldVal.msg2) {
    24.                     console.log('msg2 is change')
    25.                 }
    26.             },
    27.             deep: true
    28.         }
    29.     }
    30. }

    事件參數(shù)$event

    $event 是事件對象的特殊變量,在一些場景能給我們實現(xiàn)復(fù)雜功能提供更多可用的參數(shù)

    1. 原生事件

    在原生事件中表現(xiàn)和默認(rèn)的事件對象相同:

     
     
     
     
     
     
     
     
    1. export default {
    2.     methods: {
    3.         inputHandler(msg, e) {
    4.             console.log(e.target.value)
    5.         }
    6.     }
    7. }

    2. 自定義事件

    在自定義事件中表現(xiàn)為捕獲從子組件拋出的值

    my-item.vue:

     
     
     
     
    1. export default {
    2.     methods: {
    3.         customEvent() {
    4.             this.$emit('custom-event', 'some value')
    5.         }
    6.     }
    7. }
    8. 復(fù)制代碼

    App.vue:

     
     
     
     
     
     
     
     
    1. export default {
    2.     methods: {
    3.         customEvent(index, e) {
    4.             console.log(e) // 'some value'
    5.         }
    6.     }
    7. }

    文檔:

    • cn.vuejs.org/v2/guide/ev…
    • cn.vuejs.org/v2/guide/co…

    自定義組件雙向綁定

    組件 model 選項:

    允許一個自定義組件在使用 v-model 時定制 prop 和 event。默認(rèn)情況下,一個組件上的 v-model 會把 value 用作 prop 且把 input 用作 event,但是一些輸入類型比如單選框和復(fù)選框按鈕可能想使用 value prop 來達到不同的目的。使用 model 選項可以回避這些情況產(chǎn)生的沖突。

    input 默認(rèn)作為雙向綁定的更新事件,通過 $emit 可以更新綁定的值

     
     
     
     
     
     
     
     
    1. export default {
    2.     props: {
    3.         value: {
    4.             type: Boolean,
    5.             default: false
    6.         }
    7.     },
    8.     methods: {
    9.         switchChange(val) {
    10.             this.$emit('input', val)
    11.         }
    12.     }
    13. }

    修改組件的 model 選項,自定義綁定的變量和事件

     
     
     
     
     
     
     
     
    1. export default {
    2.     model: {
    3.         prop: 'num',
    4.         event: 'update'
    5.     },
    6.     props: {
    7.         value: {
    8.             type: String,
    9.             default: ''
    10.         },
    11.         num: {
    12.             type: Number,
    13.             default: 0
    14.         }
    15.     },
    16.     methods: {
    17.         numChange() {
    18.             this.$emit('update', this.num++)
    19.         }
    20.     }
    21. }

    文檔:cn.vuejs.org/v2/api/#mod…

    監(jiān)聽組件生命周期

    通常我們監(jiān)聽組件生命周期會使用 $emit ,父組件接收事件來進行通知

    子組件:

     
     
     
     
    1. export default {
    2.     mounted() {
    3.         this.$emit('listenMounted')
    4.     }
    5. }

    父組件:

     
     
     
     

    其實還有一種簡潔的方法,使用 @hook 即可監(jiān)聽組件生命周期,組件內(nèi)無需做任何改變。同樣的, created 、 updated 等也可以使用此方法。

     
     
     
     

    程序化的事件偵聽器

    比如,在頁面掛載時定義計時器,需要在頁面銷毀時清除定時器。這看起來沒什么問題。但仔細一看 this.timer 唯一的作用只是為了能夠在 beforeDestroy 內(nèi)取到計時器序號,除此之外沒有任何用處。

     
     
     
     
    1. export default {
    2.     mounted() {
    3.         this.timer = setInterval(() => {
    4.             console.log(Date.now())
    5.         }, 1000)
    6.     },
    7.     beforeDestroy() {
    8.         clearInterval(this.timer)
    9.     }
    10. }

    如果可以的話最好只有生命周期鉤子可以訪問到它。這并不算嚴(yán)重的問題,但是它可以被視為雜物。

    我們可以通過 $on 或 $once 監(jiān)聽頁面生命周期銷毀來解決這個問題:

     
     
     
     
    1. export default {
    2.     mounted() {
    3.         this.creatInterval('hello')
    4.         this.creatInterval('world')
    5.     },
    6.     creatInterval(msg) {
    7.         let timer = setInterval(() => {
    8.             console.log(msg)
    9.         }, 1000)
    10.         this.$once('hook:beforeDestroy', function() {
    11.             clearInterval(timer)
    12.         })
    13.     }
    14. }

    使用這個方法后,即使我們同時創(chuàng)建多個計時器,也不影響效果。因為它們會在頁面銷毀后程序化的自主清除。

    文檔:cn.vuejs.org/v2/guide/co…

    手動掛載組件

    在一些需求中,手動掛載組件能夠讓我們實現(xiàn)起來更加優(yōu)雅。比如一個彈窗組件,最理想的用法是通過命令式調(diào)用,就像 elementUI 的 this.$message 。而不是在模板中通過狀態(tài)切換,這種實現(xiàn)真的很糟糕。

    先來個最簡單的例子:

     
     
     
     
    1. import Vue from 'vue'
    2. import Message from './Message.vue'
    3. // 構(gòu)造子類
    4. let MessageConstructor = Vue.extend(Message)
    5. // 實例化組件
    6. let messageInstance = new MessageConstructor()
    7. // $mount可以傳入選擇器字符串,表示掛載到該選擇器
    8. // 如果不傳入選擇器,將渲染為文檔之外的的元素,你可以想象成 document.createElement()在內(nèi)存中生成dom
    9. messageInstance.$mount()
    10. // messageInstance.$el獲取的是dom元素
    11. document.body.appendChild(messageInstance.$el)

    下面實現(xiàn)一個簡易的 message 彈窗組件

    Message/index.vue:

     
     
     
     
     
     
     
     
    1. // 默認(rèn)選項
    2. const DefaultOptions = {
    3.     duration: 1500,
    4.     type: 'info',
    5.     content: '這是一條提示信息!',
    6. }
    7. let mid = 0
    8. export default {
    9.     data() {
    10.         return {
    11.             notices: []
    12.         }
    13.     },
    14.     methods: {
    15.         add(notice = {}) {
    16.             // name標(biāo)識 用于移除彈窗
    17.             let _name = this.getName()
    18.             // 合并選項
    19.             notice = Object.assign({
    20.                 _name
    21.             }, DefaultOptions, notice)
    22.             this.notices.push(notice)
    23.             setTimeout(() => {
    24.                 this.removeNotice(_name)
    25.             }, notice.duration)
    26.         },
    27.         getName() {
    28.             return 'msg_' + (mid++)
    29.         },
    30.         removeNotice(_name) {
    31.             let index = this.notices.findIndex(item => item._name === _name)
    32.             this.notices.splice(index, 1)
    33.         }
    34.     }
    35. }
     
     
     
     
    1. .wrap {
    2.     position: fixed;
    3.     top: 50px;
    4.     left: 50%;
    5.     display: flex;
    6.     flex-direction: column;
    7.     align-items: center;
    8.     transform: translateX(-50%);
    9. }
    10. .message {
    11.     --borderWidth: 3px;
    12.     min-width: 240px;
    13.     max-width: 500px;
    14.     margin-bottom: 10px;
    15.     border-radius: 3px;
    16.     box-shadow: 0 0 8px #ddd;
    17.     overflow: hidden;
    18. }
    19. .content {
    20.     padding: 8px;
    21.     line-height: 1.3;
    22. }
    23. .message.info {
    24.     border-left: var(--borderWidth) solid #909399;
    25.     background: #F4F4F5;
    26. }
    27. .message.success {
    28.     border-left: var(--borderWidth) solid #67C23A;
    29.     background: #F0F9EB;
    30. }
    31. .message.error {
    32.     border-left: var(--borderWidth) solid #F56C6C;
    33.     background: #FEF0F0;
    34. }
    35. .message.warning {
    36.     border-left: var(--borderWidth) solid #E6A23C;
    37.     background: #FDF6EC;
    38. }

    Message/index.js:

     
     
     
     
    1. import Vue from 'vue'
    2. import Index from './index.vue'
    3. let messageInstance = null
    4. let MessageConstructor = Vue.extend(Index)
    5. let init = () => {
    6.     messageInstance = new MessageConstructor()
    7.     messageInstance.$mount()
    8.     document.body.appendChild(messageInstance.$el)
    9. }
    10. let caller = (options) => {
    11.     if (!messageInstance) {
    12.         init(options)
    13.     }
    14.     messageInstance.add(options)
    15. }
    16. export default {
    17.     // 返回 install 函數(shù) 用于 Vue.use 注冊
    18.     install(vue) {
    19.         vue.prototype.$message = caller
    20.     }
    21. }

    main.js:

     
     
     
     
    1. import Message from '@/components/Message/index.js'
    2. Vue.use(Message)

    使用:

     
     
     
     
    1. this.$message({
    2.     type: 'success',
    3.     content: '成功信息提示',
    4.     duration: 3000
    5. })

    文檔:cn.vuejs.org/v2/api/#vm-…


    文章標(biāo)題:10個Vue開發(fā)技巧
    URL網(wǎng)址:http://www.5511xx.com/article/ccssdgs.html