应用场景
老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)