目录javascript
1、gitcss
一、git简介html
二、github简介前端
三、在github上建立项目vue
四、克隆代码java
五、提交代码node
六、git工做区mysql
七、分支react
八、对比分支ios
九、生成ssh key
十、安装git
十一、安装小乌龟
十二、忽略提交.gitignore
1三、git配置用户名和邮箱
1四、git免密
参考连接
2、MySql
一、安装mysql
二、安装Navicat
三、破解Navicat
四、Navicat链接mysql报错的解决办法
五、使mysql容许外部链接访问
六、Navicat创建MySql链接
七、sql语句简介
八、nodejs封装sql查询
九、不使用vue.config.js,单独使用node
十、封装api接口
十一、axios拦截器
十二、redis
1三、jwt-simple
1四、uuid
1五、node操纵mysql数据库进行增删查改以及登陆退出
3、vue
一、周考一
4、react
一、hook入门
5、微信小程序
一、书城
github源码
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
Git 与经常使用的版本控制工具 CVS, Subversion 等不一样,它采用了分布式版本库的方式,没必要服务器端软件支持。
章鱼猫:GitHub的吉祥物(Octocat)
GitHub是一个面向开源及私有软件项目的托管平台,由于只支持git 做为惟一的版本库格式进行托管,故名GitHub。
2018年6月4日,微软宣布,经过75亿美圆的股票交易收购代码托管平台GitHub。
git clone git@github.com:baweireact/m-app-test.git
添加要上传的文件:
git add README.md
提交到本地:
git commit -m "first commit"
提交到远程:
git push origin master
git add readme.txt git add readme.txt ant.txt git add *.html git add all git add . git add * git log git status
git add . 会把本地全部untrack的文件都加入暂存区,而且会根据.gitignore作过滤,可是git add * 会忽略.gitignore把任何文件都加入
使用 git add 命令将想要快照的内容写入缓存区, 而执行 git commit 将缓存区内容添加到本地仓库中。
::切换到develop分支 git checkout beta git pull origin beta ::把develop分支的代码合并到beta上 git merge develop git status ::push到远程beta git push origin beta ::切换到develop分支 git checkout develop echo. & pause
新建分支:
git branch feature_x
将分支提交到远程:
git push origin feature_x
切换分支:
git checkout master
查看有全部分支:
git branch -a
查看本地分支:
git branch
建立新分支并当即切换到该分支下:
git checkout -b feature_login
在github上查看有哪些分支:
删除本地分支:
git branch -d feature_x
删除远程分支:
git push origin -d feature_x
合并分支,合并后再提交到远程仓库(先切换到master分支,而后合并feature_login分支到master分支,而后再把合并后的代码提交到远程仓库):
git merge feature_login git push origin master
查看历史记录(按Q键退出历史记录):
git log
查看简洁历史记录:
git log --oneline
反顺序的历史记录:
git log --reverse
git diff master feature_login
git clone 时,能够所用不一样的协议,包括 ssh, git, https 等,其中最经常使用的是 ssh,由于速度较快,还能够配置公钥免输入密码
ssh-keygen -t rsa -C "1183391880@qq.com"
生成的key的位置:
github添加key:
点击setting:
新建ssh key :
把生成的key粘贴到github上:
确保启用 SSH 代理:
$ eval "$(ssh-agent -s)"
为 SSH key 启用 SSH 代理:
$ ssh-add ~/.ssh/id_rsa
配置ssh:
在使用Git的过程当中,咱们喜欢有的文件好比日志,临时文件,编译的中间文件等不要提交到代码仓库,这时就要设置相应的忽略规则,来忽略这些文件的提交。
/mtk 过滤整个文件夹
*.zip 过滤全部.zip文件
参考连接:
https://www.jianshu.com/p/74bd0ceb6182
全局配置用户名:
git config --global user.name "xutongbao"
全局配置邮箱:
git config --global user.email "1183391880@qq.com"
ssh配置失败的同窗,能够用https协议下载代码,并且也能够配置免密!
用git时,每次都须要输入密码会比较麻烦。
能够进行设置,这样在输入过一次密码以后,之后就不须要每次都输入密码了。
打开终端输入 :
touch ~/.git-credentials
再输入:
git config --global credential.helper store
git使用简易指南:
https://www.bootcss.com/p/git-guide/
加入到暂存区参考连接:
http://www.softwhy.com/article-8489-1.html
第一句:修改加密规则
第二句:更新用户密码
第三句:刷新权限
alter user 'root'@'localhost' identified by 'root' password expire never; alter user 'root'@'localhost' identified with mysql_native_password by 'root'; flush privileges;
参考连接:
https://www.jianshu.com/p/c8eb6d2471f8
update user set host='%' where user='root'; flush privileges;
经过sql语句实现增删查改:
-- 建表 create table user ( id varchar(100) primary key, username varchar(100), password varchar(100) ); -- 增 insert into user values ('001', 'admin', '123456'); insert into user values ('002', 'xu', '123456'); insert into user values ('003', 'xutongbao', '123456'); -- 删 delete from user; delete from user where id = '003'; -- 查 select * from user; select username from user; select * from user where id = '002'; -- 模糊搜索 select * from user where username like '%n%'; -- 降序 select * from user order by username desc; -- 升序 select * from user order by username asc; -- 分页 select * from user order by username asc limit 1,2; -- 数量 select count(*) from user; -- 改 update user set password = '123'; update user set password = '1234' where id = '001';
mysqlQuery.js:
const mysql = require('mysql') let connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'root', database: 'demo' }) connection.connect((error) => { if (error) { console.log('失败') } else { console.log('成功') } }) //使用回调函数返回查询结果 const query = (sql, callback) => { connection.query(sql, (error, results) => { if (error) { throw error } else { callback && callback(results) } }) } //使用promise封装sql查询 const queryPromise = (sql) => { return new Promise((resolve, reject) => { connection.query(sql, (error, results) => { if (error) { reject(error) } else { resolve(results) } }) }) } module.exports = { query, queryPromise }
vue.config.js:
const { query, queryPromise } = require('./mysqlQuery') module.exports = { devServer: { open: true, before(app) { app.get('/api/get_user_query', async (req, res) => { query(`select * from user`, (results) => { res.send({ code: 200, data: results, message: '用户列表' }) }) }) app.get('/api/get_user', async (req, res) => { let results = await queryPromise(`select * from user`) res.send({ code: 200, data: results, message: '用户列表' }) }) } } }
主要是为了可使用nodemon,后端代码改变时不须要重启
const express = require('express') const cors = require('cors') const { queryPromise } = require('./mysqlQuery') const app = express() app.use(cors()) app.get('/api/get_user', async (req, res) => { let users = await queryPromise('select * from user') res.send({ code: 200, data: users, message: '用户列表' }) }) app.listen(3000, () => { console.log('3000端口') })
参考连接:
跨域:
http://www.expressjs.com.cn/en/resources/middleware/cors.html
express:
http://www.expressjs.com.cn/starter/hello-world.html
nodemon:
https://www.npmjs.com/package/nodemon
index.js:
import axios from 'axios' import url from './url' axios.defaults.baseURL = 'http://localhost:3000' const common = async (config) => { const response = await axios(config) return response } export default { getUser: () => common({ url: url.getUser }) }
url.js:
export default { getUser: '/api/get_user' }
前端请求前添加token,请求后判断状态码:
import axios from 'axios' import url from './url' axios.defaults.baseURL = 'http://localhost:3000' axios.interceptors.request.use((config) => { config.headers.token = '666' return config }) axios.interceptors.response.use((res) => { if (res.data.code === 200) { return res } else if (res.data.code === 400) { alert(res.data.message) return res } else if (res.data.code === 403) { window.location.href = '/login' } }) const common = async (config) => { const response = await axios(config) return response } export default { getUser: () => common({ url: url.getUser }) }
后端接收token:
const express = require('express') const cors = require('cors') const { queryPromise } = require('./mysqlQuery') const app = express() app.use(cors()) app.get('/api/get_user', async (req, res) => { let token = req.headers.token console.log(token) let users = await queryPromise('select * from user') res.send({ code: 400, data: users, message: '用户列表' }) }) app.listen(3000, () => { console.log('3000端口') })
参考连接:
http://www.axios-js.com/docs/#Interceptors
用于保存token
安装:
启动:
在控制台使用:
//启动 redis-server.exe redis.windows.conf //访问 redis-cli.exe -h 127.0.0.1 -p 6379 //设置值 set a 1 //获取值 get a //删除key del a //设置一个值20秒后删除 set a 1 EX 20
参考连接:
https://www.npmjs.com/package/redis
用于生成token
参考连接:
https://www.npmjs.com/package/jwt-simple
用于生成用户id
参考连接:
https://www.npmjs.com/package/uuid
app.js:
const express = require('express') const cors = require('cors') const redis = require('redis') const bodyParser = require('body-parser') const jwt = require('jwt-simple') const uuidv1 = require('uuid/v1') const { queryPromise } = require('./mysqlQuery') const app = express() //跨域 app.use(cors()) app.use(bodyParser.json()) var secret = 'xxx'; //若是没有启动redis,会报错,启动redis方法,在cd到redis的安装目录,执行redis-server.exe redis.windows.conf const client = redis.createClient() client.on('error', (err) => { console.log('redis错误:' + err) }) //检查token是否存在,并更新token过时时间 const checkToken = async (token) => { let result = await new Promise((resolve) => { client.get(token, function (err, res) { return resolve(res); }); }); console.log(result) if (result) { client.set(token, token , 'EX', 600) return true } else { return false } } //增 app.post('/api/add_user', async (req, res) => { let token = req.headers.token let { username, password } = req.body let isLogin = await checkToken(token) if (isLogin) { let users = await queryPromise(`select * from user where username = '${username}'`) console.log(users) if (users.length > 0) { res.send({ code: 400, data: { username }, message: '用户名已存在' }) } else { let id = uuidv1() let user = await queryPromise(`insert into user values('${id}', '${username}', '${password}')`) if (user) { res.send({ code: 200, data: user, message: '添加成功' }) } } } else { res.send({ code: 403, message: '登陆过时' }) } }) //删 app.post('/api/delete_user', async (req, res) => { let token = req.headers.token let { ids } = req.body let isLogin = await checkToken(token) if (isLogin) { let idString = '' for (let i = 0; i < ids.length; i++) { if (i === ids.length - 1) { idString += ` id = '${ids[i]}' ` } else { idString += ` id = '${ids[i]}' or ` } } let result = await queryPromise(`delete from user where ${idString}`) res.send({ code: 200, data: result, message: '删除成功' }) } else { res.send({ code: 403, message: '登陆过时' }) } }) //查 app.get('/api/get_user', async (req, res) => { let token = req.headers.token let isLogin = await checkToken(token) if (isLogin) { let users = await queryPromise('select * from user') res.send({ code: 200, data: users, message: '用户列表' }) } else { res.send({ code: 403, message: '登陆过时' }) } }) //改 app.post('/api/update_user', async (req, res) => { let token = req.headers.token let { id, username, password } = req.body let isLogin = await checkToken(token) if (isLogin) { let result = await queryPromise(`update user set username = '${username}', password = '${password}' where id = '${id}' `) res.send({ code: 200, data: result, message: '更新成功' }) } else { res.send({ code: 403, message: '登陆过时' }) } }) //登陆 app.post('/api/login', async (req, res) => { let { username, password } = req.body let users = await queryPromise('select * from user') let user = users.find(item => item.username === username && item.password === password) if (user) { let token = jwt.encode(user.id, secret) client.set(token, token , 'EX', 600) //60秒后验证码过时知道 res.send({ code: 200, data: { username, token }, message: '登陆成功' }) } else { res.send({ code: 400, message: '登陆失败' }) } }) //退出 app.post('/api/login_out', (req, res) => { let token = req.headers.token client.del(token) res.send({ code: 200, message: '退出' }) }) app.listen(3000, () => { console.log('3000端口') })
mysqlQuery.js:
const mysql = require('mysql') let connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'root', database: 'demo' }) connection.connect((error) => { if (error) { console.log('失败') } else { console.log('成功') } }) //使用回调函数返回查询结果 const query = (sql, callback) => { connection.query(sql, (error, results) => { if (error) { throw error } else { callback && callback(results) } }) } //使用promise封装sql查询 const queryPromise = (sql) => { return new Promise((resolve, reject) => { connection.query(sql, (error, results) => { if (error) { reject(error) } else { resolve(results) } }) }) } module.exports = { query, queryPromise }
React的组件化给前端开发带来了史无前例的体验,咱们能够像玩乐高玩具同样将组件堆积拼接起来,组成完整的UI界面,在加快开发速度的同时又提升了代码的可维护性。
Hook 是 React 16.8 的新增特性。它可让你在不编写 class 的状况下使用 state 以及其余的 React 特性。
hook = 钩子
参考连接:
https://cloud.tencent.com/developer/article/1468196
https://react.docschina.org/docs/hooks-intro.html
useState、useEffect:
import React, { useState, useEffect } from 'react' const App = () => { const [ count, setCount ] = useState(0) const [ obj, setObj ] = useState({ name: 'xu', job: 'web' }) //初始化state可使用函数 const [ name, setName ] = useState(() => { return 'xu' }) //每次更新完都会执行 useEffect(() => { console.log(count) return () => { console.log('执行当前effect以前对上一个effect进行清除!' + count) } }) //只执行一次 useEffect(() => { console.log('只执行一次!') }, []) useEffect(() => { console.log('count更新时执行' + count) }, ['count']) return ( <div> { count } <div> <button onClick={() => { setCount(count - 1) }}>减</button> <button onClick={() => { setCount(count + 1) }}>加</button> <button onClick={() => { setCount(prevCount => { return prevCount + 1 }) }}>加</button> <button onClick={() => setCount(0)}>重置</button> </div> { obj.name }, { obj.job } <div> <button onClick={() => setObj({ name: '徐' })}>更名(删除了job字段)</button> <button onClick={() => setObj( prevObj => { return {...prevObj, name: '星河'} })}>更名(不会删除job字段)</button> </div> <div> {name} </div> </div> ) } export default App
useReducer:
import React, { useReducer } from 'react' const initalState = { count: 0 } const reducer = (state, action) => { switch (action.type) { case 'increment': return { count: state.count + 1 } case 'decrement': return { count: state.count - 1 } default: return state } } const App = () => { const [state, dispatch] = useReducer(reducer, initalState) return ( <div> {state.count} <div> <button onClick={() => { dispatch({ type: 'decrement' }) }}>减</button> <button onClick={() => { dispatch({ type: 'increment' }) }}>加</button> </div> </div> ) } export default App
使用函数初始化state:
import React, { useReducer } from 'react' const initalState = { count: 0 } const init = (a) => { return {count: a.count + 1} } const reducer = (state, action) => { switch (action.type) { case 'increment': return { count: state.count + 1 } case 'decrement': return { count: state.count - 1 } default: return state } } const App = () => { const [state, dispatch] = useReducer(reducer, initalState, init) return ( <div> {state.count} <div> <button onClick={() => { dispatch({ type: 'decrement' }) }}>减</button> <button onClick={() => { dispatch({ type: 'increment' }) }}>加</button> </div> </div> ) } export default App
useRef,输入框获取焦点:
import React, { useRef, useEffect } from 'react' const App = () => { const inputEl = useRef(null) const handleFocus = () => { inputEl.current.focus() } useEffect(() => { inputEl.current.focus() }, []) return ( <div> <input ref={inputEl}></input> <div> <button onClick={handleFocus}>获取焦点</button> </div> </div> ) } export default App
自定义hook,获取上一轮的state:
import React, { useState, useRef, useEffect } from 'react' //自定义hook,获取上一轮的state const usePrevious = (value) => { const ref = useRef() useEffect(() => { ref.current = value }) return ref.current } const App = () => { const [ count, setCount ] = useState(0) const prevCount = usePrevious(count) return ( <div> {count}, {prevCount} <div> <button onClick={() => setCount(count + 1)}>加</button> </div> </div> ) } export default App
获取数据:
function SearchResults() { const [data, setData] = useState({ hits: [] }); const [query, setQuery] = useState('react'); useEffect(() => { let ignore = false; async function fetchData() { const result = await axios('https://hn.algolia.com/api/v1/search?query=' + query); if (!ignore) setData(result.data); } fetchData(); return () => { ignore = true; } }, [query]); return ( <> <input value={query} onChange={e => setQuery(e.target.value)} /> <ul> {data.hits.map(item => ( <li key={item.objectID}> <a href={item.url}>{item.title}</a> </li> ))} </ul> </> ); }
参考连接:
https://zh-hans.reactjs.org/docs/react-api.html#reactsuspense
import React, { Component, Suspense, lazy } from 'react' import { Switch, Route, NavLink, Redirect } from 'react-router-dom' // import Home from './Home' // import MyBook from './MyBook' import Detail from './Detail' import Loading from '../components/Loading' const MyBook = lazy(() => import('./MyBook')) const Home = lazy(() => import('./Home')) class Index extends Component { render() { return ( <div> <div> <NavLink to="/index/home" className="m-nav-item">首页</NavLink> <NavLink to="/index/my_book" className="m-nav-item">书架</NavLink> </div> <Suspense fallback={<Loading></Loading>}> <Switch> <Route exact path="/index/home" component={Home}></Route> <Route path="/index/my_book" render={() => { if (localStorage.getItem('username')) { return <MyBook></MyBook> } else { return <Redirect to="/login"></Redirect> } }}></Route> <Route path="/index/home/detail/:id" component={Detail}></Route> </Switch> </Suspense> </div> ) } } export default Index
装包:
yarn add react-lazy-load
<LazyLoad height={300} onContentVisible={() => console.log(item.title)}> <img src={item.avatar} ></img> </LazyLoad>
参考连接:
https://www.npmjs.com/package/react-lazy-load
申请帐号:
https://mp.weixin.qq.com/wxopen/waregister?action=step1
安装开发者工具:
登陆帐号:
https://mp.weixin.qq.com/
<swiper indicator-dots="{{true}}" autoplay="{{true}}" interval="{{1000}}" style="height:{{height}}px"> <swiper-item wx:for="{{banner}}" wx:key="{{index}}"> <image src="{{item}}" mode="widthFix" class="m-item-img" bindload="handleImageLoad"></image> </swiper-item> </swiper>
"tabBar": { "list": [{ "text": "首页", "selectedIconPath": "./static/index-active.png", "iconPath": "./static/index.png", "pagePath": "pages/home/index" }, { "text": "书架", "selectedIconPath": "./static/cart-active.png", "iconPath": "./static/cart.png", "pagePath": "pages/mybook/mybook" }] }
https://developers.weixin.qq.com/community/develop/doc/d4b0566fcd760a529181f2d4b009341c?_at=1558693595388
$ npm i egg-init -g $ egg-init egg-example --type=simple $ cd egg-example $ npm i
egg官网:https://eggjs.org/zh-cn/intro/quickstart.html
https://github.com/baweireact/m-app-1705E