tencent cloud

Feedback

Custom Component Extension

Last updated: 2024-03-04 23:14:39

    Post-extension impact

    // behavior.js
    module.exports = Behavior({
    definitionFilter(defFields) {
    defFields.data.from = 'behavior'
    },
    })
    
    // component.js
    Component({
    data: {
    from: 'component'
    },
    behaviors: [require('behavior.js')],
    ready() {
    console.log(this.data.from) // Here, one would observe that the output is 'behavior' rather than 'component'.
    }
    })
    Through the given example, it becomes evident that the extension of custom components essentially provides the capability to modify the definition section of these components. The aforementioned illustration demonstrates the modification of content within the data definition section of the custom component.

    Use extension

    The Behavior() constructor introduces a new definition section,definitionFilter, to facilitate the extension of custom components. definitionFilter is a function that, when invoked, injects two parameters. The first parameter is the definition object of the component/behavior employing this behavior, while the second parameter is the list of definitionFilter functions used by this behavior.
    Let's illustrate with an example:
    // behavior3.js
    module.exports = Behavior({
    definitionFilter(defFields, definitionFilterArr) {},
    })
    
    // behavior2.js
    module.exports = Behavior({
    behaviors: [require('behavior3.js')],
    definitionFilter(defFields, definitionFilterArr) {
    // definitionFilterArr[0](defFields)
    },
    })
    
    // behavior1.js
    module.exports = Behavior({
    behaviors: [require('behavior2.js')],
    definitionFilter(defFields, definitionFilterArr) {},
    })
    
    // component.js
    Component({
    behaviors: [require('behavior1.js')],
    })
    In the aforementioned code, one custom component and three behaviors are declared, each employing the definitionFilter definition section. Following the order of declaration, the ensuing events would occur:
    1. Upon the declaration of behavior2, the definitionFilter function of behavior3 is invoked. Here, the defFields parameter pertains to the definition section of behavior2, and the definitionFilterArr parameter is an empty array, given that behavior3 does not employ any other behavior.
    2. Upon the declaration of behavior1, the definitionFilter function of behavior2 is invoked. Here, the defFields parameter pertains to the definition section of behavior1, and the definitionFilterArr parameter is an array with a length of 1, where definitionFilterArr[0] is the definitionFilter function of behavior3, given that behavior2 employs behavior3. Users can decide whether to invoke the definitionFilter function of behavior3 during the declaration of behavior1. If invocation is required, supplementing the code with definitionFilterArr[0](defFields) will suffice, and the definitionFilterArr parameter will be supplemented and passed in by the base library.
    Similarly, upon the declaration of the component, the definitionFilter function of behavior1 is invoked.
    In summary, the definitionFilter function can be understood as follows: when A employs B, the declaration of A invokes the definitionFilter function of B, passing in the definition object of A for B to filter. If B also employs C and D, B can independently decide whether to invoke the definitionFilter functions of C and D to filter the definition object of A.

    Real-world Scenario

    The following demonstrates the implementation of a custom component's computed attribute functionality using extensions:
    // behavior.js
    module.exports = Behavior({
    lifetimes: {
    created() {
    this._originalSetData = this.setData // Original setData
    this.setData = this._setData // Encapsulated setData
    }
    },
    definitionFilter(defFields) {
    const computed = defFields.computed || {}
    const computedKeys = Object.keys(computed)
    const computedCache = {}
    
    // Compute "computed"
    const calcComputed = (scope, insertToData) => {
    const needUpdate = {}
    const data = defFields.data = defFields.data || {}
    
    for (const key of computedKeys) {
    const value = computed[key].call(scope) // Compute new value
    if (computedCache[key] !== value) needUpdate[key] = computedCache[key] = value
    if (insertToData) data[key] = needUpdate[key] // Direct insertion into data, an operation required only during initialization
    }
    
    return needUpdate
    }
    
    // Overwrite setData method
    defFields.methods = defFields.methods || {}
    defFields.methods._setData = function (data, callback) {
    const originalSetData = this._originalSetData // Original setData
    originalSetData.call(this, data, callback) // Perform setData on data
    const needUpdate = calcComputed(this) // Compute "computed"
    originalSetData.call(this, needUpdate) // Perform setData on "computed"
    }
    
    // Initialize "computed"
    calcComputed(defFields, true) // Compute "computed"
    }
    })
    Use in components:
    const beh = require('./behavior.js')
    Component({
    behaviors: [beh],
    data: {
    a: 0,
    },
    computed: {
    b() {
    return this.data.a + 100
    },
    },
    methods: {
    onTap() {
    this.setData({
    a: ++this.data.a,
    })
    }
    }
    })
    <view>data: {{a}}</view>
    <view>computed: {{b}}</view>
    <button bindtap="onTap">click</button>
    The implementation principle is straightforward. It involves a secondary encapsulation of the existing setData. Each time setData is invoked, the values of each field in computed are calculated and then set in data, thereby computing the attributes.
    Note:
    This implementation example is merely illustrative and should not be directly employed in a production environment.

    Official Extension Package

    For more information, see computed.
    
    Contact Us

    Contact our sales team or business advisors to help your business.

    Technical Support

    Open a ticket if you're looking for further assistance. Our Ticket is 7x24 avaliable.

    7x24 Phone Support