1. 程式人生 > >Vue專案實戰優化:已有元件優化系列(一)

Vue專案實戰優化:已有元件優化系列(一)

一_原有元件效果

其中,核取方塊為一個元件,根據資料庫中的值,進行是否勾選,並且核取方塊只能是禁用的

二_原有元件程式碼

<template>
    <input v-if="gearboxtype === 'A'" checked type="checkbox" id="examEditGearboxTypeCheckbox" true-value="A" false-value="M" disabled="disabled" style="margin-top: 11px;">
    <input v-else type="checkbox" id="examEditGearboxTypeCheckbox" true-value="A" false-value="M" disabled="disabled" style="margin-top: 11px;">
</template>

<script>
    define(['jquery','Vue'], function ($,Vue) {
        var gearboxTypeCheck = Vue.extend({
            template: template,
            props: {
                gearboxtype: {
                    type:String,
                    default:'M'
                }
            }
        });
        Vue.component('exl-gearbox-type-check',gearboxTypeCheck);
    });

</script>

<style scoped>

</style>

專案前端使用 RequireJs 實現對依賴的管理,使用 *.vue格式編寫vue的元件

其中<template></template>請參考Vue元件基礎

props 為 父元件 傳入值,參考 Vue Prop

<template></template>中 <input>控制元件為效果展示的控制元件

三_原有元件問題

1)程式碼重複

<input v-if="gearboxtype === 'A'" checked type="checkbox" id="examEditGearboxTypeCheckbox" true-value="A" false-value="M" disabled="disabled" style="margin-top: 11px;">
<input v-else type="checkbox" id="examEditGearboxTypeCheckbox" true-value="A" false-value="M" disabled="disabled" style="margin-top: 11px;">

根據變數的值判斷 控制元件是否該被選中,重複程式碼使控制元件理解起來更復雜

2)元件具有ID屬性

元件中加入 id="examEditGearboxTypeCheckbox" 項,父元件可能會使用DOM元素去對此Vue元件進行修改,

這不符合Vue的設計習慣(使用值控制元素而不是使用DOM操作,Vue使用虛擬的DOM技術)

四_修改元件原因

1) 根據場景去除 元件的禁用選項

disabled="disabled"  項需要根據情況變更,但不影響已經使用此元件的頁面

2)元件回傳改變值給父元件

父元件需儲存此元件的勾選狀態,即 true-value="A" false-value="M"

, 但Vue中,父元件傳入的屬性會影響子元件,而子元件改變傳入的屬性並不會改變父元件,需做些處理

五_更新元件展示

A/M屬性僅作更新父元件展示用

六_更新元件程式碼

<template>
    <input type="checkbox" :checked = "isChecked" ref = "editGearboxTypeCheckbox" 
        true-value="A" false-value="M" :disabled="isDisabled" :style="typeStyle" v-model="gearboxtype">
</template>

<script>
    define(['jquery','Vue'], function ($,Vue) {
        var gearboxTypeCheck = Vue.extend({
            template: template,
            props: {
                // 變速箱型別 預設為手動‘M’
                gearboxtype: {
                    type : String,
                    default : 'M'
                },
                // 是否禁用控制元件
                isDisabled : {
                    type : Boolean,
                    default : true
                }
            },
            watch : {
                // 當勾選時,gearboxtype 會改變,更新 父元件的值
                'gearboxtype' : function(val,oldval){
                    this.$emit('update:gearboxtype', val);
                }
            },
            data : function(){
                return {
                    // 核取方塊樣式
                    typeStyle : {
                        marginTop : '10px'
                    },
                }
            },
            // 計算屬性
            computed : {
                // 是否選中
                'isChecked' : function(){
                    return this.gearboxtype === 'A';
                }
            }
        });
        Vue.component('exl-gearbox-type-check',gearboxTypeCheck);
    });

</script>

<style scoped>

</style>

去除ID屬性,如需獲取控制元件,改為ref屬性,ref = "editGearboxTypeCheckbox"

使用 計算屬性 獲取 程式碼中需要業務處理的地方,邏輯和業務解耦,例子中使用‘isChecked‘屬性控制複選框是否被選中

傳入屬性prop中加入 isDisabled : { type : Boolean, default : true} ,預設為true 相容之前使用此元件的頁面

監視 prop gearboxtype 屬性,發生改變時,回傳父元件改變其值

呼叫介面程式碼如下

<exl-gearbox-type-check :gearboxtype="examDetail.initGearboxType" :is-disabled = "false" v-bind:gearboxtype.sync = "examDetail.initGearboxType"></exl-gearbox-type-check>

再說一點

prop接收及呼叫方式

子元件回撥 this.$emit('myEvent') 在父元件中中接收方式為 kebab-case 版本<my-component v-on:my-event="doSomething"></my-component>,其中myEvent為方法,例子中isDisabled為屬性

雙向繫結關鍵點

如上程式碼,子元件呼叫 this.$emit('update:gearboxtype', val); 父頁面中 v-bind:gearboxtype.sync = "examDetail.initGearboxType" 同步其值