VueMixins advanced components with high-order components VueHOC

14207565-3f9d85d584f810c1

In the project, we often use component library for rapid development, but in the process, they will inevitably encounter the transformation and expansion of the component library, how elegant and simple to reconstruct, let's explore a simple demand from clever but useless --Mixins components and HOC

Component library project needs met

Demand: the realization of all pages button click event throttle control

14207565-8958815b6a6d02d1

Just choose a component library, in this case, I chose iview development.

Button assembly iview use the official website of the following:

Default

exportdefault{

methods: {

click () {

console.log('yes')

}

}

}

Button source code is very simple, where I removed the irrelevant content:

exportdefault{

name:'Button',

components: { Icon },

props: {

},

data () {

},

computed: {

},

methods: {

handleClick (event) {

this.$emit('click', event);

}

},

mounted () {

}

};

The following information can be obtained from a source inside:

1.iview Button component encapsulates the native button assembly

2. button assembly native, is bound to click events

When 3.click event triggers, emit a click event to the component

How to achieve demand

Look at our needs to achieve all pages click event throttling control buttons, here are a few key points:

1. Click on the event, iview Button component already on the click button of the native is bound, we need to hijack this binding, throttling

2. throttle control, the throttle (Debounce) function, there are many online example, easy to implement

Incidentally, we recommend a skirt, it's in front of 537, the middle is 631, the last is 707. Want to learn the front of a small partner can join us to learn together and help each other. Group where big God every night for free live class, if not the junior partner want to learn, do not add it. (537-631-707)

So the difficulty is that demand, how to hijack click event? Here there are two options:

14207565-664ea0dd1e01bdc2

Mixins

 1. Mixin What is that?  

Mixins 在官方Vue文档中已经有了很详细的介绍,不熟悉的朋友们可以看看,用一句话来理解,即合并组件的组件.

官方介绍:https://cn.vuejs.org/v2/guide/mixins.html

用一张图来表示:

14207565-9293232690f8fce5

 2. 怎么解决需求?  

// 节流函数

functiondebounce(func, delay, context, event){

clearTimeout(func.timer)

func.timer = setTimeout(function(){

func.call(context, event)

}, delay)

}

// iview中click方法拷贝

function_handleClick(event){

this.$emit('click', event)

constopenInNewWindow = event.ctrlKey || event.metaKey

this.handleCheckClick(event, openInNewWindow)

}

// 导出新组件

exportdefault{

props: {

},

mixins: [Vue.options.components.Button],// iview 中Button组件

data () {

return{}

},

mounted () {

console.log('mixins succeed')

},

methods: {

handleClick (event) {

letthat =this

console.log('debounce')

debounce(_handleClickLink,300, that, event)

}

}

}

 3. 原理  

mixins的原理很容易理解,上列源码我们做了这些操作,来实现合并ivew Button组件,劫持click事件:

1.创建debounce节流函数

2.复制iview Button组件中handleClick方法为_handleClick

3.导出对象,methods里重写handleClick方法,进行节流控制

使用mixins 来实现我们需求很简单,但也因此会有许多问题:

1.需要知道Button源码结构

2.带来了隐式依赖,如果mixins嵌套,会很难理解

HOC

 1.什么是HOC?  

所谓高阶组件其实就是高阶函数,React 和 Vue 都证明了一件事儿:一个函数就是一个组件。所以组件是函数这个命题成立了,那高阶组件很自然的就是高阶函数,即一个返回函数的函数

HOC的详细介绍和实现,这篇文章探索Vue高阶组件有详细介绍,用一句话来理解,即包裹组件的组件

用一张图来表示:

14207565-6e66ca9f6fa4b41f

 2. 怎么解决需求?  

直接上源码:

// 节流函数

functiondebounce(func, delay, context, event){

clearTimeout(func.timer)

func.timer = setTimeout(function(){

func.call(context, event)

}, delay)

}

// 导出新组件

exportdefault{

props: {},

name:'ButtonHoc',

data () {

return{}

},

mounted () {

console.log('HOC succeed')

},

methods: {

handleClickLink (event) {

letthat =this

console.log('debounce')

// that.$listeners.click为绑定在新组件上的click函数

debounce(that.$listeners.click,300, that, event)

}

},

render (h) {

constslots =Object.keys(this.$slots)

.reduce((arr, key) =>arr.concat(this.$slots[key]), [])

.map(vnode=>{

vnode.context =this._self

returnvnode

})

returnh('Button', {

on: {

click:this.handleClickLink//新组件绑定click事件

},

props:this.$props,

// 透传 scopedSlots

scopedSlots:this.$scopedSlots,

attrs:this.$attrs

}, slots)

}

}

 3. 原理  

HOC的特点在于它的包裹性,上列源码我们做了这些操作,来实现包裹iview的Button组件,劫持click事件:

1.创建debounce节流函数

2.导出新的组件

3.render渲染出iview Button

4.Button 绑定debounce后的click方法

HOC的包裹性同时也会带来几个问题:

1.组件之间通信会被拦截,比如子组件访问父组件的方法(this.$parent.methods)

2.vue官方并没有推荐使用HOC :(

总结

Mixins 和 HOC 都能实现这个简单的需求,希望大家能理解这两种技巧,解决项目中的问题。

源码:https://github.com/warpcgd/mixinAndHoc

demo:https://warpcgd.github.io/mixinAndHoc/#/

Button:https://www.iviewui.com/components/button

Button源码:https://github.com/iview/iview/blob/3.x/src/components/button/button.vue

Vue explore higher-order components: http://hcysun.me/vue-design/more/vue-hoc.html

* Author: warpcgd

* Original title: clever but useless - Vue Mixins advanced components with high-order components Vue HOC practice

* Original Address: https://segmentfault.com/a/1190000017745603

* Disclaimer: reprint articles and pictures are from the public network, all belongs to the author himself. If the source is incorrect or infringe rights of the original author, please contact us to delete or authorized matters.

Guess you like

Origin blog.csdn.net/weixin_33756418/article/details/90991772