npm发布自己组件(滑动解锁)

1、创建账号、项目初始化、推包

第一次发布自己的npm包

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"
//       >
//         &gt;&gt;
//       </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)}
        >
          &gt;&gt;
        </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>
5、效果展示

效果展示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值