react经验10:与jquery配合使用

应用场景

老web项目进行react改造,为了节省时间,部分jquery组件仍然保留。

案例1

使用bootstrapTable组件。

node_modules准备

jquery、bootstrap、bootstrap-table

如果需要typescript,则额外追加

@types/bootstrap、@types/jquery

以上都直接npm安装。

实施步骤:

1.在src的index中挂载jquery到全局变量

import $ from 'jquery'
window.jQuery = $

2.在需要使用bootstrap-table的组件中引入插件

import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap-table/dist/bootstrap-table.min.css'
import $ from 'jquery'
import 'bootstrap'
import 'bootstrap-table'

接下来就能在合适的时机调用插件

//例如组件初始化的时候
useEffect(()=>{
	$(dom).bootstrapTable(option)
},[])

案例2

jquery与react混用,比如某段html是由jquery动态生成的,此时又想插入一段react组件。

实施步骤:
1.准备好普通的react组件;

const DemoComponent=(props:{})=>{
	return (
		<label>啊手动阀示范点</label>
	)
}

2.混合使用

//这是由jquery生成的dom
$('<div id="demo">').appendTo('body')
//准备react组件的容器
let root=ReactDOM.createRoot(document.getElementById('demo') as HTMLElement)
//渲染react组件
root.render(<DemoComponent />)

案例3

比较古老的jq插件不在npm上面,也没有类型声明。
例如有个绘制进度条的插件叫"jQMeter",简单重构之。

步骤1:类型声明

declare interface JQueryStatic {
    jQMeter: (element: HTMLElement | JQuery, option: any) => void
}
declare interface JQuery {
    jQMeter: (option: any) => void
}

步骤2:重构

/*

Title:		jQMeter: a jQuery Progress Meter Plugin
Author:		Gerardo Larios
Version:	0.1.2
Website:	http://www.gerardolarios.com/plugins-and-tools/jqmeter
License: 	Dual licensed under the MIT and GPL licenses.

*/
import $ from 'jquery'

//Set plugin defaults
const defaultsOption = {

    width: '100%',
    height: '50px',
    bgColor: '#444',
    barColor: '#bfd255',
    meterOrientation: 'horizontal',
    animationSpeed: 2000,
    counterSpeed: 2000,
    displayTotal: true

}

//Extend the jQuery prototype

$.fn.extend({
    jQMeter(options: any) {
        if (options && typeof (options) === 'object') {
            options = $.extend({}, defaultsOption, options)
        }
        const _this: any = this
        _this.each(function (i: number, domEle: any) {
            $.jQMeter(domEle, options)
        })
        return
    }
})

$.jQMeter = function (elem, options) {
    //Define plugin options
    let goal = parseInt((options.goal).replace(/\D/g, ''))
    let raised = parseInt((options.raised).replace(/\D/g, ''))
    let width = options.width
    let height = options.height
    let bgColor = options.bgColor
    let barColor = options.barColor
    let meterOrientation = options.meterOrientation
    let animationSpeed = options.animationSpeed
    let counterSpeed = options.counterSpeed
    let displayTotal = options.displayTotal
    let total = (raised / goal) * 100

    /*
     * Since the thermometer width/height is set based off of
     * the total, we force the total to 100% if the goal has
     * been exceeded.
     */
    if (total >= 100) {
        total = 100
    }

    //Create the thermometer layout based on orientation option
    if (meterOrientation === 'vertical') {

        $(elem).html('<div class="therm outer-therm vertical"><div class="therm inner-therm vertical"><span style="display:none;">' + total + '</span></div></div>')
        $(elem).children('.outer-therm').attr('style', 'width:' + width + ';height:' + height + ';background-color:' + bgColor)
        $(elem).children('.outer-therm').children('.inner-therm').attr('style', 'background-color:' + barColor + ';height:0;width:100%')
        $(elem).children('.outer-therm').children('.inner-therm').animate({ height: total + '%' }, animationSpeed)

    } else {

        $(elem).html('<div class="therm outer-therm"><div class="therm inner-therm"><span style="display:none;">' + total + '</span></div></div>')
        $(elem).children('.outer-therm').attr('style', 'width:' + width + ';height:' + height + ';background-color:' + bgColor)
        $(elem).children('.outer-therm').children('.inner-therm').attr('style', 'background-color:' + barColor + ';height:' + height + ';width:0')
        $(elem).children('.outer-therm').children('.inner-therm').animate({ width: total + '%' }, animationSpeed)

    }

    //If the user wants the total percentage to be displayed in the thermometer
    if (displayTotal) {

        //Accomodate the padding of the thermometer to include the total percentage text
        var formatted_height = parseInt(height)
        var padding = (formatted_height / 2) - 13 + 'px 10px'

        if (meterOrientation !== 'horizontal') {
            padding = '10px 0'
        }

        $(elem).children('.outer-therm').children('.inner-therm').children().show()
        $(elem).children('.outer-therm').children('.inner-therm').children().css('padding', padding)

        //Animate the percentage total. Borrowed from: http://stackoverflow.com/questions/23006516/jquery-animated-number-counter-from-zero-to-value
        $({ Counter: 0 }).animate({ Counter: $(elem).children('.outer-therm').children('.inner-therm').children().text() }, {
            duration: counterSpeed,
            easing: 'swing',
            step: function () {
                $(elem).children('.outer-therm').children('.inner-therm').children().text(Math.ceil(this.Counter) + '%')
            }
        })
    }

    //Add CSS
    $(elem).append('<style>.therm{height:30px;border-radius:5px;}.outer-therm{margin:20px 0;}.inner-therm span {color: #fff;display: inline-block;float: right;font-family: Trebuchet MS;font-size: 20px;font-weight: bold;}.vertical.inner-therm span{width:100%;text-align:center;}.vertical.outer-therm{position:relative;}.vertical.inner-therm{position:absolute;bottom:0;}</style>')

}

调用方法

import './assets/libs/jqmeter'
import $ from 'jquery'

$(element).jQMeter(options)
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值