项目实战【vue,react,微信小程序】(1705E)

目录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源码


 

 

 

 

 

 

 

1、git

一、git简介

Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。

Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

Git 与经常使用的版本控制工具 CVS, Subversion 等不一样,它采用了分布式版本库的方式,没必要服务器端软件支持。

二、github简介

章鱼猫:GitHub的吉祥物(Octocat)

GitHub是一个面向开源及私有软件项目的托管平台,由于只支持git 做为惟一的版本库格式进行托管,故名GitHub。

2018年6月4日,微软宣布,经过75亿美圆的股票交易收购代码托管平台GitHub。

 

 

三、在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工做区

使用 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

 

九、生成ssh key

  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

十、安装git

十一、安装小乌龟

配置ssh:

 

十二、忽略提交.gitignore

在使用Git的过程当中,咱们喜欢有的文件好比日志,临时文件,编译的中间文件等不要提交到代码仓库,这时就要设置相应的忽略规则,来忽略这些文件的提交。

/mtk 过滤整个文件夹
*.zip 过滤全部.zip文件

参考连接:

https://www.jianshu.com/p/74bd0ceb6182

 

1三、git配置用户名和邮箱

   全局配置用户名:

git config --global user.name "xutongbao"

   全局配置邮箱:

git config --global user.email "1183391880@qq.com"

1四、git免密

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

 

 

2、MySql

一、安装mysql

二、安装Navicat

三、破解Navicat

 

四、Navicat链接mysql报错的解决办法

 

第一句:修改加密规则

第二句:更新用户密码

第三句:刷新权限

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

五、使mysql容许外部链接访问

update user set host='%' where user='root';

flush privileges;

六、Navicat创建MySql链接

七、sql语句简介

 经过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';

八、nodejs封装sql查询

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: '用户列表'
        })
      })
    }
  }
}

九、不使用vue.config.js,单独使用node

主要是为了可使用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

 

十、封装api接口

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'
}

十一、axios拦截器

前端请求前添加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

十二、redis

用于保存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

1三、jwt-simple

用于生成token

参考连接:

https://www.npmjs.com/package/jwt-simple

1四、uuid

用于生成用户id

参考连接:

https://www.npmjs.com/package/uuid

1五、node操纵mysql数据库进行增删查改以及登陆退出

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
}

 

3、vue

一、周考一

 

4、react

一、hook入门

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

 

5、微信小程序

一、购物车

 

二、入门

申请帐号:

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

"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

6、node 

1.koa,egg

$ 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

 

 

 

 

 

 

github源码

https://github.com/baweireact/m-app-1705E

相关文章
相关标签/搜索