1、创建账号、项目初始化、推包
2、改造项目支持react
发布 react 组件到 npm 上
注意:编译jsx文件时注意项目要创建 .babelrc 配置,下面是babel7的编译
npx babel src --out-dir lib
下面是babel6的编译
babel app.js -d lib
如果没安装babel-cli使用下面指令
Babel6:编译 React jsx + ES6 简单入门
npm install -g babel-cli
如果mac环境下安装过程中出现错误内容如下
gyp: No Xcode or CLT version detected!
则执行命令,后面路径修改为你当前xcode地址
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
package.json文件中添加babel命令
"scripts": {
"wbbabel": "babel src -d dest",
"build": "webpack",
"start": "webpack-dev-server --open"
}
如果报错内容如下,则执行命令cnpm install --save-dev babel-cli
You have mistakenly installed the babel package, which is a no-op in Babel 6.Babel's CLI commands have been moved from the babel package to the babel-cli package.
本地测试npm包项目可以使用 npm link
3、源码展示
JavaScript实现拖动滑块验证
(1)目录结构
(2)源码展示
package.json
{
"name": "zzuwbin",
"version": "3.0.3",
"description": "wangbin",
"main": "lib/app.js",
"scripts": {
"build": "webpack",
"start": "webpack-dev-server --open"
},
"author": "wangbin",
"license": "ISC",
"devDependencies": {
"babel": "^6.23.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-plugin-import": "^1.8.0",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.11",
"file-loader": "^2.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.21.0",
"webpack": "^4.12.2",
"webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.4"
},
"dependencies": {
"react": "^16.4.1",
"react-dom": "^16.4.1"
}
}
webpack.config.js
var webpack = require("webpack");
module.exports = {
entry: __dirname + "/index.js",
output: {
path: __dirname + "/public",
filename: "index.js"
},
devServer: {
contentBase: "./public",
historyApiFallback: true,
inline: true,
host: "0.0.0.0", // 解决只能用localhost无法用本机IP访问项目,注意访问要用本机ip
port: 8080,
disableHostCheck: true,
useLocalIp: true //是否使用ip打开页面
},
devtool: "inline-source-map",
module: {
rules: [{
test: /(\.js|\.jsx)$/,
use: {
loader: "babel-loader",
options: {
// presets: ["react", "env"], // presets字段设定转码规则
// plugins: [
// // 插件
// ["import", { libraryName: "antd-mobile", style: "css" }]
// ]
}
},
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader"
}
]
},
{
test: /\.scss$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader"
},
{
loader: "sass-loader"
}
]
},
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: "file-loader",
options: {
name: "[path][name].[ext]"
}
}
]
}]
}
};
index.js
import React from "react";
import { render } from "react-dom";
// import Wbsliding from "./app.js"
import Wbsliding from "./lib/app.js"
class Welcome extends React.Component {
render() {
return <Wbsliding success={() => {
alert("解锁成功!")
}}></Wbsliding> ;
}
}
render(<Welcome />, document.getElementById("root"))
export {Wbsliding}
app.js
import React from "react";
import "./assets/app.css";
// function Wbsliding(props) {
// return (
// <div className="drag">
// <div className="bg"></div>
// <div className="text">请拖动滑块解锁</div>
// <div
// className="btn"
// >
// >>
// </div>
// </div>
// );
// }
// export default Wbsliding;
let box, //容器
bg, //背景
text, //文字
btn, //滑块
success, //是否通过验证的标志
distance, //滑动成功的宽度(距离
downX;
function $(selector) {
return document.querySelector(selector);
}
class Wbsliding extends React.Component {
componentDidMount() {
distance = 0;
(box = $(".drag")), //容器
(bg = $(".bg")), //背景
(text = $(".text")), //文字
(btn = $(".btn")), //滑块
(success = false), //是否通过验证的标志
(distance = box.offsetWidth - btn.offsetWidth); //滑动成功的宽度(距离)
}
start(param) {
let e = param.touches[0];
console.log("start", e);
//1.鼠标按下之前必须清除掉后面设置的过渡属性
btn.style.transition = "";
bg.style.transition = "";
//说明:clientX 事件属性会返回当事件被触发时,鼠标指针向对于浏览器页面(或客户区)的水平坐标。
//2.当滑块位于初始位置时,得到鼠标按下时的水平位置
e = e || window.event;
downX = e.clientX;
}
move(param) {
let e = param.touches[0];
e = e || window.event;
//1.获取鼠标移动后的水平位置
let moveX = e.clientX;
//2.得到鼠标水平位置的偏移量(鼠标移动时的位置 - 鼠标按下时的位置)
let offsetX = moveX - downX;
//3.在这里判断一下:鼠标水平移动的距离 与 滑动成功的距离 之间的关系
if (offsetX > distance) {
offsetX = distance; //如果滑过了终点,就将它停留在终点位置
} else if (offsetX < 0) {
offsetX = 0; //如果滑到了起点的左侧,就将它重置为起点位置
}
//4.根据鼠标移动的距离来动态设置滑块的偏移量和背景颜色的宽度
btn.style.left = offsetX + "px";
bg.style.width = offsetX + "px";
//如果鼠标的水平移动距离 = 滑动成功的宽度
if (offsetX == distance && !success) {
//1.设置滑动成功后的样式
text.innerHTML = "验证通过";
text.style.color = "#fff";
btn.style.color = "green";
bg.style.backgroundColor = "lightgreen";
//2.设置滑动成功后的状态
success = true;
//成功后,清除掉鼠标按下事件和移动事件(因为移动时并不会涉及到鼠标松开事件)
btn.onmousedown = null;
document.onmousemove = null;
setTimeout(() => {
this.props.success();
}, 100);
}
}
end(param) {
let e = param.touches[0];
//如果鼠标松开时,滑到了终点,则验证通过
if(success){
return;
}else{
//反之,则将滑块复位(设置了1s的属性过渡效果)
btn.style.left = 0;
bg.style.width = 0;
btn.style.transition = "left 1s ease";
bg.style.transition = "width 1s ease";
}
//只要鼠标松开了,说明此时不需要拖动滑块了,那么就清除鼠标移动和松开事件。
document.onmousemove = null;
document.onmouseup = null;
}
render() {
return (
<div className="drag">
<div className="bg"></div>
<div className="text">请拖动滑块解锁</div>
<div
className="btn"
onTouchStartCapture={e => {
this.start(e);
}}
onTouchMoveCapture={e => {
this.move(e);
}}
onTouchEndCapture={e => this.end(e)}
>
>>
</div>
</div>
);
}
}
export default Wbsliding;
.babelrc
{
"presets": ["react", "env"]
}
public/index.html
<html>
<head>
<title>ZZUWBIN</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport"content="width=device-width, initial-scale=1, maximum-scale=1.0,user-scalable=no;" />
</head>
<body>
<div id="root"></div>
<script src="./index.js"></script>
</body>
</html>
4、组件使用
npm i zzuwbin@3.0.3
import Wbsliding from "zzuwbin"
<Wbsliding success={() => {console.log("解锁成功")}}></Wbsliding>