高次成分と高度なコンポーネントをVueMixins VueHOC

14207565-3f9d85d584f810c1

プロジェクトでは、我々は多くの場合、迅速な開発のためのコンポーネントライブラリを使用しますが、プロセスでは、彼らは必然的に転換し、コンポーネントライブラリの拡張が発生します、再構築するためにどのようにエレガントでシンプルな、のがより簡単な需要を開拓しましょう賢いしかし役に立たない--MixinsコンポーネントとHOC

コンポーネントライブラリプロジェクトのニーズが満たさ

需要:すべてのページのボタンクリックイベントスロットル制御の実現

14207565-8958815b6a6d02d1

ただ、この場合には、私はiViewの開発を選んだ、コンポーネントライブラリを選択します。

ボタンアセンブリのiViewでは、以下の公式ウェブサイトを使用します。

デフォルト

exportdefault {

方法:{

{クリックしてください()

console.log( 'はい')

}

}

}

私は無関係なコンテンツを削除した場合、ボタンのソースコードは、非常に簡単です:

exportdefault {

名前:「ボタン」、

成分:{アイコン}

小道具:{

}、

データ(){

}、

計算:{

}、

方法:{

handleClick(イベント){

この$(「クリック」、イベント)を発します。

}

}、

{)(マウント

}

}。

次の情報は、内部ソースから得ることができます。

1.iview Buttonコンポーネントは、ネイティブのボタンアセンブリをカプセル化

2.ボタンアセンブリのネイティブ、イベントをクリックしてバインドされています

3.clickイベントがトリガされたとき、コンポーネントにクリックイベントを発します

需要を達成する方法

ここでは、すべてのページがイベントスロットルコントロールボタンをクリックして達成するために我々のニーズを見ていくつかの重要なポイントです。

ネイティブのクリックボタン1.イベントをクリックし、iViewのButtonコンポーネント、既にがバインドされ、我々は、この結合、スロットルをハイジャックする必要があります

2.スロットル制御、スロットル(デバウンス)関数は、多くのオンラインの例では、実装が容易、があります

ちなみに、私たちはスカートをお勧めします、それは537の前でだ、真ん中、最後は707で、631です。一緒に学び、お互いを助けるために私たちに参加することができ、小さなパートナーの前を学びたいと思っています。ジュニアパートナーが勉強したくない場合は、大きな神無料のライブクラスのすべての夜は、それを追加しないグループ。(537-631-707)

だから、難易度は、イベントをクリックしてハイジャックする方法、その需要のですか?ここでは2つのオプションがあります。

14207565-664ea0dd1e01bdc2

ミックスイン

 1. MIXINそれは何ですか?  

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のは、高次成分を探る:http://hcysun.me/vue-design/more/vue-hoc.html

*著者:warpcgd

*原題:賢いが、役に立たない - 高次成分のVue HOCの練習とVueのミックスインの高度なコンポーネント

*オリジナル住所:https://segmentfault.com/a/1190000017745603

*免責事項:転載記事と写真は、パブリックネットワークからのもの、すべては作者自身に属します。ソースが間違っているか、原作者の権利を侵害した場合は、削除または許可事項にご連絡ください。

おすすめ

転載: blog.csdn.net/weixin_33756418/article/details/90991772