官網:https://router.vuejs.org/zh/javascript
用 Vue.js + Vue Router 建立單頁應用,是很是簡單的。使用 Vue.js ,咱們已經能夠經過組合組件來組成應用程序,當你要把 Vue Router 添加進來,咱們須要作的是,將組件 (components) 映射到路由 (routes),而後告訴 Vue Router 在哪裏渲染它們。css
安裝vue路由:html
npm install vue-router --save
在main.js使用vue路由:前端
import Vue from 'vue'; import App from './App.vue'; import VueRouter from 'vue-router'; Vue.use(VueRouter); //一、定義 (路由) 組件,引入路由頁面 import music from "./views/music/index.vue"; import movie from "./views/movie/index.vue"; //二、建立路由數組(路由表) const routes = [ { path: '/music', component: music }, { path: '/movie', component: movie }, //重定向路由(當路由地址不在路由數組中的時候,默認跳到music) { path: "*", redirect : "/music" } ] //三、建立router實例,而後傳routes配置(這裏帶有路由的配置參數) const router = new VueRouter({ routes // 至關於 routes: routes }) new Vue({ el: "#app", router, //注入到全局,會被注入到每一個組件中,能夠利用$router進行一些信息的獲取 render: (h) => h(App) })
而後新建一個views視圖文件夾,放兩個路由頁面:vue
movie文件夾中的index.vuejava
<template> <div> <h1>電影首頁</h1> </div> </template>
經過注入路由器,咱們能夠在任何組件內經過 this.$router 訪問路由器,也能夠經過 this.$route 訪問當前路由: jquery
最後在App.vue中放路由標籤便可顯示全部路由表中的組件:ios
<template> <div> <router-view></router-view> </div> </template>
http://127.0.0.1:8080/#/musicgit
添加兩個按鈕,作選項卡切換頁面:github
<template> <div class="app"> <header> <ul> <li v-for="item in tabNav" :class="{cur:item.url == $route.path}" @click="routerGo(item.url)" > {{item.title}} </li> </ul> <span>{{$route}}</span> </header> <router-view></router-view> </div> </template> <script> export default { data(){ return { tabNav : [ {title:"電影", url:"/movie"}, {title:"音樂", url:"/music"}, ] } }, methods: { routerGo(url){ this.$router.push({path:url}) } } }; </script> <style scoped> ul{list-style:none;overflow: hidden;} ul li{width:50%;height:40px;line-height:40px;text-align:center;float: left;} ul li.cur{background: red;color:#fff;} </style>
$route是路由圓信息,裏面包含了:路由名稱、頁面路徑、hash、params等。
引用路由有3種方式:
第一種:在app.js中用import引入文件
import music from "./views/music/index.vue"; import movie from "./views/movie/index.vue"; // 建立一個路由表(數組) const routes = [ { path: '/music', name: "音樂", component: music }, { path: '/movie', name: "電影", component: movie }, //路由重定向(當路由地址不在路由數組的時候,默認跳轉music) { path: '*', redirect: '/music' } ]
第二種:不用import引包,用require,但require()不是ES6的語法,不推薦使用
const routes = [ { path: '/music', name: "音樂", component: require("./views/music/index.vue").default }, { path: '/movie', name: "電影", component: require("./views/movie/index.vue").default }, //路由重定向(當路由地址不存在的時候,默認跳轉music) { path: '*', redirect: '/music' } ]
第三種:
const routes = [ { path: '/music', name: "音樂", component(){ return System.import("./views/music/index.vue") } }, { path: '/movie', name: "電影", component(){ return System.import("./views/movie/index.vue") } }, //路由重定向(當路由地址不在路由數組的時候,默認跳轉music) { path: '*', redirect: '/music' } ]
在main.js的父路由下加一個children的數組,這個數組就是存放子路由:
注意:name屬性最好放在meta對象中,不然name出現重名會警告。
const routes = [ { path:'/music', meta:{ name:"音樂" }, component(){ return System.import("./views/music/index.vue") } }, { path:'/movie', meta:{name:"電影"}, component(){ return System.import("./views/movie/index.vue") }, children:[ { path:'/movie/oumei', meta:{name:"電影"}, component(){ return System.import("./views/movie/oumei/index.vue") } }, { path:'/movie/guochan', meta:{name:"電影"}, component(){ return System.import("./views/movie/guochan/index.vue") } } ] }, //重定向路由(當路由地址不在路由數組中的時候,默認跳到music) { path: "*", redirect : "/music" } ]
重點:給父親添加router-view標籤顯示子頁面。有子路由,父路由頁面必定有一個router-view標籤。
<template> <div> <button v-for="item in nav" @click="routerGo(item.url)">{{item.title}}</button> <h1>電影頁面</h1> <router-view></router-view> </div> </template> <script> export default { data(){ return { nav :[ {title:"歐美", url: "/movie/oumei"}, {title:"國產", url: "/movie/guochan"} ] } }, methods:{ routerGo(url){ this.$router.push({path:url}) } } }; </script>
https://router.vuejs.org/zh/guide/essentials/dynamic-matching.html
const routes = [ { path:'/music', meta:{ name:"音樂" }, component(){ return System.import("./views/music/index.vue") } }, { path:'/movie', meta:{name:"電影"}, component(){ return System.import("./views/movie/index.vue") }, children:[ { //動態路徑參數 以冒號開頭 path:'/movie/:id', meta:{name:"電影"}, component(){ return System.import("./views/movie/list.vue") }, } ] }, //重定向路由(當路由地址不在路由數組中的時候,默認跳到music) {path: "*",redirect : "/music"} ]
movie/list.vue頁面
<template> <div> <h1>電影列表{{$route.params.id}}</h1> </div> </template>
新建data.json,而後發起Ajax請求數據(能夠用vue-axios代替fetch)
{ "mapList" : { "oumei" : [ { "title" : "美國隊長1", "time" : "1小時30分"}, { "title" : "美國隊長2", "time" : "1小時40分"}, { "title" : "美國隊長3", "time" : "1小時50分"}, { "title" : "美國隊長4", "time" : "1小時55分"} ], "guochan" : [ { "title" : "戰狼1", "time" : "1小時30分"}, { "title" : "戰狼2", "time" : "1小時40分"}, { "title" : "戰狼3", "time" : "1小時50分"} ] } }
router.js
import Vue from 'vue'; import VueRouter from 'vue-router'; import Index from '../views/index.vue'; import axios from 'axios'; Vue.use(VueRouter); const router = new VueRouter({ routes: [ { path: "/", name: "首頁", component: Index, meta: { needLogin: true,"juse":["user","admin"] } } ] }) router.beforeEach(async (to, from, next) => { //當用戶切換路由的時候,執行這裏的語句 if(to.meta.needLogin == true){//needLogin字段表明當前頁面須要登陸 //驗證用戶是否登錄了 const { login, username,juse} = await axios.get("/api/checklogin").then(res=>res.data); console.log(login, username)//獲得後端返回 if(login == true){ console.log("你經過驗證了") next();//放行 }else{ console.log("沒有經過驗證,去登錄") router.push("/login")//若是註冊時後端驗證用戶名重複就不容許經過,再回到登陸頁面 } }else{ //不須要驗證登錄的,直接放行 console.log("經過驗證了") next(); } console.log(to) }) export default router;
axios 是一個基於 Promise 的http請求庫,能夠用在瀏覽器和Node.js中,可以使用vue-axios發起Ajax請求,Axios本質上也是對原生XHR的封裝,只不過它是Promise的實現版本,符合最新的ES規範。
https://www.npmjs.com/package/vue-axios
安裝:
npm install --save axios vue-axios
在main.js引入:
import axios from 'axios' import VueAxios from 'vue-axios' Vue.use(VueAxios, axios)
根據文檔使用插件,有三種使用方式:
Vue.axios.get(api).then((response) => { console.log(response.data) }) this.axios.get(api).then((response) => { console.log(response.data) }) this.$http.get(api).then((response) => { console.log(response.data) })
有了插件能夠不用fetch就能輕鬆發送ajax了,在電影頁中點擊菜單的時候發ajax。將請求回來的數據,用[]號將國產電影 和 歐美電影的數據枚舉出來,再使用v-bind傳入 list.vue 組件中:
movie/index.vue:
<template> <div> <h1>我是電影頻道主頁</h1> <button v-for="item in tabNav" @click="routerGo(item.url)">{{item.title}}</button> <router-view :mapList="mapList"></router-view> </div> </template> <script> export default { data(){ return { tabNav :[ { title : "歐美" , url : "/movie/oumei" }, { title : "國產" , url : "/movie/guochan" } ], mapList : [] } }, methods : { routerGo(url){ this.$router.push({ path:url }) //發送Ajax請求數據 this.$http.get("../../../data/data.json").then((res) => { this.mapList = res.data.mapList[this.$route.params.id]; console.log(this.mapList) }) } } } </script>
./views/movie/list.vue頁面接收顯示:
<template> <div> <h1>我是詳情頁面{{$route.params.id}}</h1> <ul> <li v-for="item in mapList"> <span>{{item.title}}</span> <span>{{item.time}}</span> </li> </ul> </div> </template> <script> export default { props : ["mapList"] } </script>
移動端點擊300ms的延遲,vue有一個vue-touch插件能消除300ms的延遲。
網址:https://github.com/vuejs/vue-touch/tree/next
注意:有版本區分。
安裝依賴:
npm install vue-touch@next --save
main.js引入方式:
import VueTouch from 'vue-touch'
Vue.use(VueTouch, {name: 'v-touch'})
頁面使用方式:
<v-touch tag="標籤名" v-on:tap="點擊事件">Tap me!</v-touch>
App.vue:
<v-touch v-for="item in tabNav" :class="{cur : $route.name == item.title}"
v-on:tap="routerGo(item.url)" :key="item.id" tag="li">{{item.title}}</v-touch>
gif.vue組件:
<v-touch tag="div" @tap="play" class="play" v-show="isPlay">play</v-touch>
vue懶加載使用vue-lazyload,網址:https://www.npmjs.com/package/vue-lazyload
安裝依賴:
npm install --save vue-lazyload
main.js引入懶加載:
import VueLazyload from 'vue-lazyload' Vue.use(VueLazyload, { preLoad: 1, //高度縮放比例 // error: 'dist/error.png', loading: '../static/loading.gif', attempt: 1 //嘗試加載圖片數量 })
組件頁面使用方式:
<img v-lazy="child.wifi_img_url" >
vue的插件不少
官網插件庫:https://github.com/vuejs/awesome-vue
網址:https://cn.vuejs.org/v2/guide/transitions.html
插件庫:https://segmentfault.com/p/1210000008583242/read?from=timeline
可使用外部 css動畫插件
網址:https://daneden.github.io/animate.css/
有一個工具,叫作mock.js快速模擬數據。不再用追着後端小夥伴要接口了。
在工做中,後端的接口每每是較晚纔會出來,而且還要寫接口文檔,因而前端的許多開發都要等到接口給咱們才能進行,這樣對於前端來講顯得十分的被動,因而有沒有能夠製造假數據來模擬後端接口呢,答案是確定的。應該有人經過編寫json文件來模擬後臺數據,可是很侷限,好比增刪改查這些接口怎麼實現呢,因而今天咱們來介紹一款很是強大的插件Mock.js,能夠很是方便的模擬後端的數據,也能夠輕鬆的實現增刪改查這些操做。
安裝依賴:
npm install --save-dev mockjs
require依賴,建立Random對象,就能模擬中文姓名了。
下面就是寫生成「模擬數據.txt」的程序:更多使用請移步官網
var path = require("path"); var fs = require("fs"); var Mock = require('mockjs'); var Random = Mock.Random; //基數據的地址 var jishuju = path.resolve(__dirname,"基數據.json"); //存儲生成文件的地址 var monishuju = path.resolve(__dirname,"模擬數據.txt"); //先刪除舊的數據 fs.writeFileSync(monishuju, ""); console.log("模擬數據.txt已清空,下面爲你生成新的") //讀取基數據 fs.readFile(jishuju,function(err,data){ var data = JSON.parse(data.toString()); //遍歷100項,添加一些新的屬性和值 for(var i = 0;i < data.length;i++){ data[i].price = Random.integer(0,100); //售價 data[i].km = Random.integer(0,100); //千米數 data[i].owner = Random.cname(); //賣家姓名 //模擬十年的日期 data[i].buydate = new Date(new Date() - Random.integer(86400000, 86400000 * 365 * 10)); //排量 data[i].engine = Random.pick(['1.4L','1.6L','1.5T','1.6T','1.8L','1.8L','2.0L']); data[i].local = Random.boolean(); //是否本地車 data[i].pai = Random.boolean(); //是否上牌 fs.appendFileSync(monishuju, JSON.stringify(data[i]) + "\n\r") } console.log("模擬數據寫入成功,快打開.txt看看吧!") })
這是純後臺的東西,咱們搞前端的瞭解便可。
HTTP是無鏈接的,當你第一次訪問一個服務器的時候,第二次再來到這個服務器(可能就10s以後),服務器此時的HTTP和第一次毫無關係的。對於服務器來講,HTTP是兩次,兩次之間沒有持久保持連續。因此服務器不知道你曾經來過,也不知道你曾經作的事情。
cookie是HTTP的一個性質,不優雅的解決了HTTP無鏈接,服務器對客戶端的識別問題。
HTTP在最初的版本,就設計了一個cookie的東西,說白了是:
服務器在response的報頭中設置一個set-cookie的報文頭
從此瀏覽器每次訪問這個服務器的時候,都要帶着這個cookies字段上去。
服務器就變相的記住了客戶端電腦曾經的行爲。
Cookie:
當服務器在HTTP響應頭部下發了一個Set-Cookie,從此每次Request瀏覽器都會帶着相同的cookie上去。
Seesion:
session就是cookie,是一種特殊的cookie,是不發送明文,而是發送隨機亂碼的cookie。 服務器就會比較這個亂碼和以前誰的同樣,你就是那誰。
app.js
var express = require("express"); var app = express(); //簡單的cookie演示 app.get("/",function(req,res){ res.cookie('name', 'Marte', { expires: new Date(Date.now() + 900000), httpOnly: true}); res.send("ok"); }) app.listen(3000)
語法:
res.cookie(k,v,設置)
Set-Cookie: name=Marte; Path=/; Expires=Tue, 14 Aug 2018 10:01:46 GMT; HttpOnly
有什麼用,能夠方便讓:
瀏覽器記錄服務器曾經給咱們的信息
服務器記錄用戶提供的信息
裏面有一個Set-Cookie,值爲:
name=Marte; expires=Fri, 14-Aug-2018 10:01:46 GMT
表示Cookie的值,和過時時間。
從此的每一次訪問同一個域名下的任何網站,均可以看見Request Header中攜帶了相同的Cookie:
Cookie的性質:
① Cookie不安全,能夠在任什麼時候候被瀏覽器的network面板被查看。因此千萬不要試圖讓服務器下發密碼等機密信息。能夠被自由修改,信息量不能大。
② Cookie是文件格式存儲。
③ 有超時的限制,能夠自由設置存活時間。
在沒有本地存儲以前,用cookie實現本地存儲的功能
cookie通常來講是服務器端更改,瀏覽器只須要帶cookie碼上去便可。
必須使用cookie-parser這個npm包格式化cookie的顯示,有這個依賴,服務器才能讀取cookie
npm install --save cookie-parser
var express = require("express"); var cookieParser = require('cookie-parser') var app = express(); // cookieParser()是中間件 app.use(cookieParser()); //簡單的cookie演示 app.get("/",function(req,res){ res.cookie('name', 'Marte', { expires: new Date(Date.now() + 900000), httpOnly: true}); console.log(req.cookies.name) res.send("ok"); }) app.listen(3000)
實現一個歷史痕跡功能:作一個旅遊網站,有不少城市簡介,此時網站首頁可以記錄你曾經訪問過的地方,在HTML5時代用localStorage足夠好用,若是不讓使用本地存儲,只能藉助cookie。
var express = require("express"); var app = express(); app.set("view engine" , "ejs"); app.get("/",function(req,res){ res.render("index.ejs"); }); app.get("/:city",function(req,res){ //識別/後面的字符 var city= req.params.city; res.render("city.ejs", {city}); }); app.listen(3000);
views/city.ejs:
<h1><%= city %>旅遊攻略</h1> <script type="text/javascript"> //localStorage.setItem("lvyou","<%= city %>"); //讀 if(localStorage.getItem("lvyou")){ var arr = JSON.parse(localStorage.getItem("lvyou")); }else{ var arr = []; } arr.push("<%= city %>")//避免覆蓋,讀一條用數組存一條 localStorage.setItem("lvyou",JSON.stringify(arr));//設,本地存儲只能放字符串 </script>
views/index.ejs:顯示
<body> <h1>你的足跡:</h1> <div id="info"></div> <script type="text/javascript"> //讀取 var arr = localStorage.getItem("lvyou"); document.getElementById("info").innerHTML = arr; </script> </body>
用cookie實現思路:服務器每次都下發新的set-cookie命令,把你這一次訪問的地點都加入數組。用戶每次都帶着新的cookie上來,首頁不就一直更新了麼?
app.js
var express = require("express"); var app = express(); var cookieParser = require('cookie-parser'); app.use(cookieParser()); app.get("/",function(req,res){ res.send("你的旅遊足跡" + req.cookies.lvyou); }); app.get("/:city",function(req,res){ var arr = req.cookies.lvyou;//讀cookie if(!arr){ arr = []; } //改cookie var city = req.params.city; arr.push(city); //設cookie res.cookie("lvyou",arr,{maxAge:999999}); res.send(city + "旅遊攻略"); }); app.listen(3000);
怎麼實現登陸?
登陸很簡單,但HTTP是無鏈接的,A頁面登陸了,一樣的網站下B頁面不知道你登陸了。
不過有cookie,讓服務器發起Set-Cookie: username=Marte;login=true; 此時瀏覽器從此訪問這個網站的每一個頁面都會帶着cookie上去。服務器識別cookie,一看就知道你登陸了!
可是,cookie能夠被自由篡改!也就是說,我想登錄誰的號,就登陸了誰的號!
後來出現了session,它不經過cookie下發明文信息,而是發送一個隨機亂碼下去,通常代號都是64位。
服務器同時在內存中(服務器重啓數據會丟失)保存這個隨機碼的人的各類信息。若是有人帶這個隨機亂碼上來,必定是這我的!
咱們把這種特別的cookie叫作SESSION,也叫做會話。
也就是說,session就是cookie!是一種特殊的cookie,是不發送明文,而是發送隨機亂碼的cookie。
session使用第三方中間件,叫作express-session。
官方API:https://www.npmjs.com/package/express-session
var express = require("express"); var app = express(); var session = require('express-session') //使用session中間件,這個中間件必須在第一位 app.set('trust proxy', 1) // trust first proxy app.use(session({ //對session id相關的cookie進行簽名 secret: 'Marte', //加密字符串,下發給瀏覽器的隨機亂碼都時基於這個字符串加密的 resave: false, saveUninitialized: true, //是否保存未初始化的會話 cookie: { maxAge : 999999 //設置session的有效時間,單位毫秒 } })) app.get("/",function(req,res){ var sess = req.session; sess.a = ~~(Math.random() * 10000); res.send("ok,已經記錄a爲:" + sess.a) }) app.get("/test",function(req,res){ var sess = req.session; if(sess.a){ var str = sess.a.toString(); }else{ var str = "不存在"; } res.send(str) }) app.listen(3000)
從此個人每一次訪問,都會帶着這個碼上,這個碼對於瀏覽器來講,沒有任何意義,可是服務器就是經過這個碼來知道你是你。
登陸案例:
pages/login.html
<body> <h1>模擬登錄</h1> <p>用戶名:<input type="text" id="username"></p> <p>密碼:<input type="text" id="mima" value="123456"></p> <button id="btn"></button> <script type="text/javascript" src="/jquery-1.12.3.min.js"></script> <script type="text/javascript"> $("#btn").click(function(){ $.post("/dopost",{ "username" : $("#username").val(), "mima" : $("#mima").val() },function(data){ alert(data); if(data == "成功登錄!"){ window.location = "/";//刷新 } }) }); </script> </body>
jquery放在js靜態化文件夾中。
app.js
var express = require("express"); var app = express(); var session = require('express-session'); var path = require("path"); var formidable = require('formidable'); //靜態資源 app.use(express.static("js")); app.set('trust proxy', 1) // trust first proxy app.use(session({ secret: 'Marte', //加密字符串,下發的隨機亂碼都是依靠這個字符串加密的 resave: false, saveUninitialized: true })); app.get("/",function(req,res){ if(req.session.login){ //登陸了就顯示登陸頁面 res.send(`<h1>歡迎${req.session.username}成功登陸,<a href="/logout">退出</a></h1>`) }else{ // 用戶沒有登陸,就顯示登陸頁面 res.sendFile(path.join(__dirname, "pages/login.html")); } }); //接受表單 app.post("/login",function(req,res){ var form = new formidable.IncomingForm(); //設置上傳文件夾路徑 form.uploadDir = "./uploads"; form.parse(req, function(err, fields, files) { console.log(fields.username) if(fields.mima == "123456"){ //核心語句,設置session,若是沒有設置session,就和沒有登陸同樣。 req.session.login = true; req.session.username = fields.username; //顯示信息 res.send("成功登錄!"); }else{ res.send("密碼錯誤!"); } }); }); //退出登陸 app.get("/logout",function(req,res){ //剝奪登陸的session req.session.login = false; req.session.username = ""; res.redirect("/"); }); app.listen(3000);
不能在數據庫中用明碼存密碼,若是你保存明碼,此時若是你的數據庫丟失,或者你的員工、工程師使壞,故意泄密,此時用戶其餘的QQ、Email若是是同一個密碼就被竊取了。
因此咱們就要把密碼加密以後,存儲在數據庫中,當用戶登陸的時候,輸入的密碼再次作一樣的加密,把加密的密文和密文進行比對,若是相同,就說明用戶輸入正確了。
最最著名的兩套加密算法分別是SHA系列、MD5系列。他們都是著名的單向算法,僅僅可以從明文計算出密文,你不可能找到一個方法從密文計算出明文。也就是說SHA、MD5都是用來加密的,而他們沒有解密功能。
Secure Hash Algorithm(安全哈希算法)
Message Digest Algorithm MD5(中文名爲消息摘要算法第五版)
使用http://encode.chahuo.com/來測試一下SHA256加密算法,
sha256加密算法:
原文 |
密文 |
你好 |
670d9743542cae3ea7ebe36af56bd53648b0a1126162e78d81a32934a711302e |
這是單向加密算法,這個密碼常常用於檢測文字信息是否被篡改、是否完整。而不是用於通信,不是說把密碼給別人,別人再次解密,由於這個密碼不能解碼。
MD5加密算法
原文 |
密文 |
你好 |
7eca689f0d3389d9dea66ae112e5cfd7 |
兩種算法都是:
l 無論文字長短都能加密出64位、32位的加密字符串
l 即便改變了一個字,密文也大改
l 即便你掌握了算法,也不能破譯
var crypto = require("crypto"); //建立一個sha256加密方法 // var sha256 = crypto.createHash("sha256"); // var str = sha256.update("你好").digest("hex"); //digest表示處理爲hex十六進制 //建立一個md5加密方法 var md5 = crypto.createHash("md5"); var str = md5.update("世界你好").digest("hex"); console.log(str)