項目實戰【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

相關文章
相關標籤/搜索