1、回顾

2、react项目的配置

react默认创建的项目配置文件在 node_modules/react-scripts 文件夹内部

2.1 抽离配置文件

cnpm run eject

cnpm run start

2.2 配置@符号

打开config/webpack.config.js,ctrl + f 搜索 alias,添加配置

alias: {
'react-native': 'react-native-web',
// ++++++++++++++++++++++++++++++++++++++++++++++++++
'@': path.join(__dirname, '../', 'src'),
...(isEnvProductionProfile && {
'react-dom$': 'react-dom/profiling',
'scheduler/tracing': 'scheduler/tracing-profiling',
}),
...(modules.webpackAliases || {}),
},

2.3 调整src文件夹---配置scss

src

lib

App.js

index.js

logo.svg

serviceWorker.js

main.scss

  • index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './main.scss'; // +++++++++++++++++++++++++++++++
import App from '@/App';
import * as serviceWorker from '@/serviceWorker'; ReactDOM.render(<App />, document.getElementById('root')); // If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
  • App.js
import React from 'react';

function App() {
return (
<div className="App"> </div>
);
} export default App;
  • main.scss
@import '@/lib/reset.scss';

html {
@include background-color(#f66);
}

3、编写项目的页面结构

jsx中的class需要写成className

App.js

import React from 'react';

function App() {
return (
<div className="container">
<div className="box">
<header className="header"></header>
<div className="content"></div>
</div>
<footer className="footer"></footer>
</div>
);
} export default App;

编写样式

@import '@/lib/reset.scss';

html, body, #root, .container {
@include rect(100%, 100%);
} .container {
@include flexbox();
@include flex-direction(column);
.box {
@include flex();
@include rect(100%, auto);
@include flexbox();
@include flex-direction(column);
.header {
@include rect(100%, 0.44rem);
@include background-color(#f66);
}
.content {
@include flex();
@include rect(100%, auto);
@include overflow();
}
}
.footer {
@include rect(100%, 0.5rem);
@include background-color(#efefef);
}
}

4、创建各个页面 src/views

views/home/index.jsx

views/kind/index.jsx

views/cart/index.jsx

views/user/index.jsx

以首页为例

import React from 'react';

class Com extends React.Component {
render () {
return (
<div className="box">
<header className="header">首页头部</header>
<div className="content">首页内容</div>
</div>
)
}
} export default Com;
  • 测试页面模块 App.js
import React from 'react';
import Home from '@/views/home'; // +++++++++++++++++
function App() {
return (
<div className="container">
{
// +++++++++++++++++
}
<Home />
<footer className="footer"></footer>
</div>
);
} export default App;

5、开始路由

入口找布局,布局找页面,页面找组件

https://reacttraining.com/react-router/web/guides/quick-start

cnpm i react-router-dom -S

**以前 react-router **

5.1 入口文件处修改代码

import React from 'react';
import ReactDOM from 'react-dom';
import './main.scss';
import App from '@/App';
import * as serviceWorker from '@/serviceWorker';
// HashRouter ---- vue中的hash /#/home
// BrowserRouter ---- vue中的history /home
// BrowserRouter as Router 把BrowserRouter起名为Router
// Route 路由
// Switch多个只能选中一个 ------ BrowserRouter 只能有一个子元素
// 一个应用有很多布局 --- Switch
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'; // 入口找布局,布局找页面,页面找组件
// App 就是一个布局文件
ReactDOM.render(
<Router>
<Switch>
<Route path="/">
<App />
</Route>
</Switch>
</Router>
, document.getElementById('root')); // If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

5.2 修改App.js布局文件

import React from 'react';
import Home from '@/views/home';
import Kind from '@/views/kind';
import Cart from '@/views/cart';
import User from '@/views/user';
// 一种布局有很多的页面 --- Switch
import { Switch, Route } from 'react-router-dom';
// 布局找页面
function App() {
return (
<div className="container">
<Switch>
<Route path = "/home"><Home /></Route>
<Route path = "/kind"><Kind /></Route>
<Route path = "/cart"><Cart /></Route>
<Route path = "/user" component = { User }/ >
{
//<Route path = "/user"><User /></Route>
}
</Switch>
<footer className="footer"></footer>
</div>
);
} export default App;

6、添加底部的导航布局

<footer className="footer">
<ul>
<li>
<span className="iconfont icon-fonts-shouye"></span>
<p>首页</p>
</li>
<li>
<span className="iconfont icon-icon"></span>
<p>分类</p>
</li>
<li>
<span className="iconfont icon-gouwuche"></span>
<p>购物车</p>
</li>
<li>
<span className="iconfont icon-wode"></span>
<p>我的</p>
</li>
</ul>
</footer>

main.scss

.footer {
@include rect(100%, 0.5rem);
@include background-color(#efefef);
ul {
@include rect(100%, 100%);
@include flexbox();
li {
@include flex();
@include rect(auto, 100%);
@include flexbox();
@include flex-direction(column);
@include justify-content();
@include align-items();
span {
@include font-size(0.24rem);
}
p {
@include font-size(0.12rem);
}
}
}
}

7、声明式跳转路由

Link / NavLink

App.js ---- NavLink标签会自动解析为 a标签,需要更改样式表,

通过activeClassName给选中的路由添加样式

// NavLink 必须导入
import { Switch, Route, NavLink } from 'react-router-dom'; <footer className="footer">
<ul>
<NavLink to="/home" activeClassName="active">
<span className="iconfont icon-fonts-shouye"></span>
<p>首页</p>
</NavLink>
<NavLink to="/kind" activeClassName="active">
<span className="iconfont icon-icon"></span>
<p>分类</p>
</NavLink>
<NavLink to="/cart" activeClassName="active">
<span className="iconfont icon-gouwuche"></span>
<p>购物车</p>
</NavLink>
<NavLink to="/user" activeClassName="active">
<span className="iconfont icon-wode"></span>
<p>我的</p>
</NavLink>
</ul>
</footer>

main.scss

.footer {
@include rect(100%, 0.5rem);
@include background-color(#efefef);
ul {
@include rect(100%, 100%);
@include flexbox();
a { // +++++++++++++++++++++++++
@include color(#666);
@include flex();
@include rect(auto, 100%);
@include flexbox();
@include flex-direction(column);
@include justify-content();
@include align-items();
span {
@include font-size(0.24rem);
}
p {
@include font-size(0.12rem);
}
&.active { // ++++++++++++++++++++++++++
@include color(#f66);
}
}
}
}

8、使用React UI库

PC: element-ui 、 ant design (antd)

移动端: ant design mobile (antd-mobile)

https://mobile.ant.design/index-cn

https://mobile.ant.design/docs/react/use-with-create-react-app-cn

8.1 修改public/index.html

引入 FastClick 并且设置 html meta (更多参考 #576)

引入 Promise 的 fallback 支持 (部分安卓手机不支持 Promise)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
<script src="https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js"></script>
<script>
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
if(!window.Promise) {
document.writeln('<script src="https://as.alipayobjects.com/g/component/es6-promise/3.2.2/es6-promise.min.js"'+'>'+'<'+'/'+'script>');
}
</script>
<link rel="apple-touch-icon" href="logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
<link rel="stylesheet" href="//at.alicdn.com/t/font_1476238_uph8zgimp3.css">
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

8.2 安装模块

cnpm i antd-mobile -S

cnpm i babel-plugin-import -D

8.3 修改package.json文件中的babel选项

"babel": {
"presets": [
"react-app"
],
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"plugins": [
["import", { "libraryName": "antd-mobile", "style": "css" }]
]
},

9、请求渲染首页数据

9.1 解决跨域问题

cnpm i http-proxy-middleware -D

src/setupProxy.js

const proxy = require('http-proxy-middleware');

module.exports = function (app) {
app.use(proxy('/api', {
target: 'http://47.92.152.70', // 代理哪一个服务器
changeOrigin: true, // 代理
pathRewrite: {
'^/api': '' // 以 /api 开头的请求,认为就是请求的代理
// /api/pro ===> http://47.92.152.70/pro
}
}))
// 纯属凑数
app.use(proxy('/test', {
target: 'https://www.baidu.com', // 代理哪一个服务器
changeOrigin: true, // 代理
pathRewrite: {
'^/test': ''
}
}))
}

9.2 封装数据请求模块

cnpm i axios -S

utils/request.js + utils/api.js

9.3 首页使用UI库的 走马灯 ---- 轮播图

https://mobile.ant.design/components/carousel-cn/

import React from 'react';
// ++++++++++++++++++++++++++++++++++++++++++++
import { Carousel } from 'antd-mobile';
// +++++++++++++++++++++++++++++++++++++++++++++++++
import { getBannerlist, getProlist } from '@/utils/api';
class Com extends React.Component {
constructor (props) {
super(props);
this.state = { // +++++++++++++++++++++++++++++++++++++++++
bannerlist: [{ bannerid: 1, img: 'images/1.jpg'}],
prolist: []
}
} componentDidMount () { // +++++++++++++++++++++++++++++++++++
getBannerlist().then(data => {
console.log(data.data)
this.setState({
bannerlist: data.data
})
})
getProlist().then(data => {
this.setState({
prolist: data.data
})
})
} render () {
return (
<div className="box">
<header className="header">首页头部</header>
<div className="content">
{
// +++++++++++++++++++++++++++
}
<Carousel
autoplay={ true }
infinite
beforeChange={(from, to) => console.log(`slide from ${from} to ${to}`)}
afterChange={index => console.log('slide to', index)}
>
{this.state.bannerlist.map(item => (
<a
key={ item.bannerid }
href="https://www.baidu.com"
style={{ display: 'inline-block', width: '100%', height: '176px' }}
>
<img
src={`http://47.92.152.70/${item.img}`}
alt=""
style={{ width: '100%', verticalAlign: 'top' }}
onLoad={() => {
// fire window resize event to change height
window.dispatchEvent(new Event('resize'));
this.setState({ imgHeight: 'auto' });
}}
/>
</a>
))}
</Carousel>
</div>
</div>
)
}
} export default Com;

main.scss中添加

* { touch-action: none; }

9.4 封装Prolist.jsx组件,首页列表的渲染

  • components/Prolist/index.jsx
import React from 'react';
import './style.scss';
// class组件获取数据 使用 this.props
// 函数式组件含有默认的参数 props ----- 等同与 class 组件中的this.props
const Com = (props) => {
return (
<ul className="prolist">
<li className="proitem">
<div className="proimg">
<img src="" alt="" />
</div>
<div className="proinfo">
111111111
</div>
</li>
</ul>
)
} export default Com;
  • components/Prolist/style.scss
@import '@/lib/reset.scss';
.prolist {
@include rect(100%, auto);
.proitem {
@include rect(100%, 1rem);
@include border(0 0 1px 0, #efefef, solid); // 设定的是一个物理像素
@include flexbox();
.itemimg {
@include rect(1rem, 1rem);
img {
@include rect(0.9rem, 0.9rem);
@include border(1px, #f66, solid);
@include margin(0.05rem);
@include display(block);
}
}
.iteminfo {
@include flex();
}
}
}
  • 首页面引入 Prolist 组件
import Prolist from '@/components/Prolist';
<Prolist />
  • 首页传值给列表
<Prolist prolist = { this.state.prolist }/>
  • 列表组件渲染数据
import React from 'react';
import './style.scss';
// class组件获取数据 使用 this.props
// 函数式组件含有默认的参数 props ----- 等同与 class 组件中的this.props
const Com = (props) => {
return (
<ul className="prolist">
{
props.prolist.map(item => {
return (
<li className="proitem" key = { item.proid }>
<div className="proimg">
<img src={ item.proimg } alt="" />
</div>
<div className="proinfo">
{ item.proname }
</div>
</li>
)
})
}
</ul>
)
} export default Com;

10、构建个人中心

// 设置变量,使用三木运算符判定 用户是不是登陆状态
import React from 'react'; class Com extends React.Component {
constructor (props) {
super(props)
this.state = {
flag: false
}
}
render () {
return (
<div className="box">
<header className="header">个人中心头部</header>
<div className="content">
{
this.state.flag ?
<div>
欢迎您......
</div>
:
<div>
<button>登陆</button>
<button>注册</button>
</div>
}
</div>
</div>
)
}
} export default Com;
  • 判定用户有没有登陆
componentDidMount () {
// if (localStorage.getItem('isLogin') === 'ok') {
// this.setState({
// flag: true
// })
// } else {
// this.setState({
// flag: false
// })
// }
let flag = localStorage.getItem('isLogin') === 'ok' ? true : false
this.setState({
flag
})
}
  • 给登陆按钮设置点击事件,跳转到登陆页面

11、构建登陆页面

views/login/index.jsx

import React from 'react';

class Com extends React.Component {
render () {
return (
<div className="box">
<header className="header">登陆</header>
<div className="content">登陆</div>
</div>
)
}
} export default Com;

入口找布局,布局找页面,页面找组件 --- 登陆没有底部的页面布局

  • 添加新的布局文件

src/Other.js

import React from 'react';
import Login from '@/views/login';
import { Switch, Route } from 'react-router-dom';
// 布局找页面 /o/login --- 自定义 o 表示新的布局
function Other () {
return (
<div className="container">
<Switch>
<Route path="/o/login"><Login /></Route>
</Switch>
</div>
);
} export default Other;
  • 入口添加新的布局 / 所对应的布局在最下面
import React from 'react';
import ReactDOM from 'react-dom';
import './main.scss';
import App from '@/App';
import Other from '@/Other'; // 新的布局文件 +++++++++++++++++++++++++++++++
import * as serviceWorker from '@/serviceWorker';
import { HashRouter as Router, Switch, Route } from 'react-router-dom'; // 入口找布局,布局找页面,页面找组件
// App 就是一个布局文件
/**
<Route path="/o">
<Other />
</Route>
*/ ReactDOM.render(
<Router>
<Switch>
<Route path="/o">
<Other />
</Route>
<Route path="/">
<App />
</Route>
</Switch>
</Router>
, document.getElementById('root')); // If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
  • 点击登陆 使用编程式跳转 到 登陆页面

this.props.history.push() / replace() / goBack()

// views/user/index.js
<button onClick = { () => {
// console.log(this.props)
this.props.history.push('/o/login')
}}>登陆</button>

12 编辑登陆的表单

views/login/index.js

import React from 'react';
import './style.scss'
class Com extends React.Component {
render () {
return (
<div className="box">
<header className="header">登陆</header>
<div className="content">
<input type="text" placeholder="手机号码"/>
<p className="tip"></p>
<input type="password" placeholder="密码" />
<p className="tip"></p>
<button className="userBtn" >登陆</button>
<p className="tip"></p>
</div>
</div>
)
}
} export default Com;

views/login/style.scss

input {
outline: none;
border: 0;
display: block;
width: 96%;
margin: 5px 2%;
border-bottom: 1px solid #efefef;
line-height: 36px;
text-indent: 10px;
}
.tip {
color: #f66;
text-align: center;
height: 20px;
}
.userBtn {
outline: none;
border: 0;
display: block;
background-color:#f66;
width: 96%;
margin: 15px 2%;
line-height: 40px;
font-size: 18px;
color: #fff;
}
  • 检验表单信息 --- 手机号

this.state = {
tel: '18813007814',
telTip: ''
} <input type="text" placeholder="手机号码" value={ this.state.tel } onChange={ (event) => {
// 输入框绑定value值
console.log(event.currentTarget.value)
// 通过事件对象获取输入框的值
let val = event.currentTarget.value
// 提示标识变量
let tip = ''
// 输入时,如果输入的值为空,标识为空
// 如果输入的语法错误,标识为手机号码格式错误
// 否则 标识为ok
tip = val === '' ? '' : val.length !== 11 ? '手机号码格式错误' : 'ok'
// 修改状态 --- 视图二次渲染
this.setState({
tel: val,
telTip: tip
})
} }/>
<p className="tip">{ this.state.telTip }</p>
  • 校验表单信息 --- 密码
this.state = {
tel: '18813007814',
telTip: '',
password: '123456',
passwordTip: ''
} <input type="password" placeholder="密码" value= { this.state.password } onChange = { this.validPassword.bind(this)}/>
<p className="tip">{ this.state.passwordTip }</p> validPassword (event) {
// console.log(event)
let val = event.currentTarget.value;
let tip = ''
tip = val === '' ? '' : val.length < 6 ? '密码格式错误' : ''
this.setState({
password: val,
passwordTip: tip
})
}
  • 登陆功能
<button className="userBtn" onClick= { this.login.bind(this) }>登陆</button>
  • 封装登陆的接口

utils/api.js

/**
* 登陆接口
* @param {tel} String
* @param {password} String
*/
const login = (tel, password) => {
return new Promise(resolve => {
request.post('/users/login', { tel, password }).then(res => {
resolve(res.data)
})
})
} // 3、暴露接口
export {
getProlist,
getBannerlist,
getCartlist,
login // ++++++++++++++++++++++++
}
  • 实现登陆功能
login () {
// 点击登陆验证手机号码输入是否正确
if (this.state.tel === '' || this.state.telTip === '手机号码格式错误') {
this.setState({
tip: '请输入合法的电话号码'
})
return
}
// 点击登陆验证密码输入是否正确
if (this.state.password === '' || this.state.passwordTip === '密码格式错误') {
this.setState({
tip: '请输入合法的密码'
})
return
}
// 请求接口
login(this.state.tel, this.state.password).then(data => {
console.log(data)
let tip = '' // 显示的是 后端返回的数据的标识
if (data.code === '10086') {
tip = '用户未注册,请先注册'
} else if (data.code === '10100') {
tip = '密码错误'
} else {
tip = '登陆成功'
localStorage.setItem('token', data.token)
localStorage.setItem('userid', data.userid)
localStorage.setItem('username', data.username)
localStorage.setItem('isLogin', 'ok')
this.props.history.goBack()
}
this.setState({
tip
})
})
}

13、发送短信验证码

1、申请签名和短信模板

2、获取用户标识

id: LTAIZQoVVoPuBjU9

secret: GfJuI2dLsCQh7Q56TmFxPTniXjkVnB

3、编写代码

cnpm i @alicloud/pop-core -S

react抽离配置文件、配置@符号、调整src文件夹---配置scss、编写项目的页面结构、创建各个页面 src/views、开始路由、入口文件处修改代码、修改App.js布局文件、添加底部的导航布局、构建个人中心。。。声明式跳转路由、使用React UI库请求渲染首页数据、的更多相关文章

  1. TOMCATserver不写port号、不写项目名訪问项目、虚拟文件夹配置

    一.不写port. 这个问题都被问烂了.由于TOMCAT默认的訪问port为8080.而TCP/IP协议默认80port訪问,大家之所以看到别的站点都不写port号是由于人家用的的80port訪问的, ...

  2. MyEclipse部署项目到Tomcat上,但是classes文件夹下没有编译项目

    在MyEclipse中把项目部署到Tomcat上,但是Tomcat下的classes文件夹下没有编译项目解决方法:1-直接在点击菜单栏的Project--clean,对项目进行clean2-查看菜单栏 ...

  3. .net网站上传图片换电脑不显示 当不用网站的IP地址访问图片,只用相对路径访问时,在发布网站的时候,将上传图片的目标文件夹,包含在项目中再发布即可。

    .net网站上传图片换电脑不显示 当不用网站的IP地址访问图片,只用相对路径访问时,在发布网站的时候,将上传图片的目标文件夹,包含在项目中再发布即可.

  4. Jenkins publish over ssh 上传 文件夹 配置方式

    需要把编译后 目录下的 lib文件夹下的jar包都上传到服务器上 1.配置 2.完成截图 3.服务器截图 注意:  真实脚本 建议写 全路径 注意:多条命令时  添加 英文分号

  5. [原创]关于在VS解决方案下使用文件夹管理多个项目层次关系的说明

    由于所创建的应用项目或类库项目较多,于是将这些类库放到一个文件夹下.在VS解决方案下确实能看到一个文件夹下多个类库项目这种层次关系.如下图所示: 但打开“我的电脑”,看到的只有类库,并未看到维护层次关 ...

  6. 用Node.JS+MongoDB搭建个人博客(app.js接口文件)(二)

    app.js的GitHub地址:用力戳我然后点个star 说个题外话,THINKPHP是通过一个index.php来引入文件,所以被称为接口文件. 而NodeJS也有这样的接口文件,通常也会放在根目录 ...

  7. Python3基础 os mkdir 创建一层文件夹 在有父目录的情况下创建子目录

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  8. Python读取不同文件夹下的图片并且分类放到新创建的训练文件夹和标签文件夹

    在深度学习的训练时,经常会碰到训练的样本数据集和标签数据集是在一个文件夹中,这个时候我们就不得不进行一些数据的预处理和文件的分类,例如将训练(training data)数据集和标签数据集(label ...

  9. eclipse如何把多个项目放在文件夹下,用文件夹分开不同的项目

    在Package Explorer顶部的右侧有有机表图标按钮,点击倒三角 Top Level Elements->Working Set.此时就会发现,很多项目会自动纳入一个文件夹,这个文件夹的 ...

  10. 19 Flutter仿京东商城项目 商品详情 底部浮动导航布局 商品页面布局

    效果: widget/JdButton.dart import 'package:flutter/material.dart'; import '../services/ScreenAdaper.da ...

随机推荐

  1. svg矢量二维码加盖在PDF文件中

    正常行驶的bitmap类型的二维码格式,加载到PDF中,将会导致二维码失真,无法扫描. 矢量图可根据尺寸大小进行调节,不会出现失真模糊情况 所用依赖 <PackageReference Incl ...

  2. LeetCode LCP 2. 分式化简

    从最后一项依次叠加 1 class Solution(object): 2 def fraction(self, cont): 3 """ 4 :type cont: L ...

  3. Android studio Internet跳转活动

    <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=" ...

  4. mitudesk的pytorch基础

    pytorch定义张量的方法和Numpy差不多 2. 标量才能对张量求导,代表其在各个方向上的偏导数,结果是一个张量 3. 在pyt中张量可以对张量求导,前提条件是求导时传一个1,1,1,1,进去,其 ...

  5. C输入输出

    由于刚开始学的是cin和cout进行输入和输出,好多时候就不会写printf和scanf,所以导致有时候程序运行超时也不会改正,所以今天先说一说scanf和printf. 这是cin和cout的格式: ...

  6. 位置式PID和增量式PID

    PID介绍 PID 是 Proportional(比例).Integral(积分).Differential(微分)的首字母缩写:是一种结合比例.积分和微分三种环节于一体的闭环控制算法.PID 控制的 ...

  7. MMDetection中模型的Checkpoints下载

    mmdetection中的模型checkpoints是需要自己手动下载的,下载步骤如下: 打开mmdetection, 进入configs目录,可以看到这里面有很多以目标检测模型命名的文件夹,选择你想 ...

  8. Jquery ajax参数设置(转)

    参数名 类型 描述 url String (默认: 当前页地址) 发送请求的地址. type String (默认: "GET") 请求方式 ("POST" 或 ...

  9. ASP.NET WEBAPI 获取微信Access token

    /// <summary> /// 获取Access token /// </summary> /// <param name="appid"> ...

  10. Eclipse导入第四版《算法》algs4库

    最近在研究<算法>,遇到algs4库导入eclipse问题,查了很多网站,都不适用,最终解决,特此记录一下.第一次写博客,有什么不足之处望各位大神纠正. 1. 首先打开eclipse软件, ...