查看當前所有正在運行的進程,可以看到80端口被httpd占用了(80端口希望分配給nginx使用,而不是httpd)
netstat -tpnul
這里以殺死httpd進程為例:
先查看 httpd 進程
flaskApi) [root@67 flaskDemo]# ps aux |grep httpd root 6732 0.0 0.0 230488 5252 ? Ss 8月06 2:27 /usr/sbin/httpd -DFOREGROUND
apache 22570 0.0 0.0 232572 3888 ? S 9月15 0:00 /usr/sbin/httpd -DFOREGROUND
apache 22571 0.0 0.0 232572 3888 ? S 9月15 0:00 /usr/sbin/httpd -DFOREGROUND
apache 22572 0.0 0.0 232572 3904 ? S 9月15 0:00 /usr/sbin/httpd -DFOREGROUND
apache 22573 0.0 0.0 232572 3904 ? S 9月15 0:00 /usr/sbin/httpd -DFOREGROUND
apache 22574 0.0 0.0 232572 3900 ? S 9月15 0:00 /usr/sbin/httpd -DFOREGROUND
apache 27544 0.0 0.0 232572 3896 ? S 15:41 0:00 /usr/sbin/httpd -DFOREGROUND
apache 27546 0.0 0.0 232572 3900 ? S 15:41 0:00 /usr/sbin/httpd -DFOREGROUND
apache 27548 0.0 0.0 232572 3172 ? S 15:41 0:00 /usr/sbin/httpd -DFOREGROUND
apache 27550 0.0 0.0 232572 3172 ? S 15:41 0:00 /usr/sbin/httpd -DFOREGROUND
apache 27552 0.0 0.0 232572 3172 ? S 15:41 0:00 /usr/sbin/httpd -DFOREGROUND
root 27665 0.0 0.0 112728 988 pts/0 S+ 15:43 0:00 grep --color=auto httpd
這個就是 apache 的所有進程
我們可以用 kill -9 加進程ID 如下
kill -9 6732 kill -9 22570 kill -9 22571 kill -9 22572 kill -9 22573 kill -9 22574 kill -9 27544 kill -9 27546 kill -9 27548 kill -9 27550 kill -9 27552 kill -9 27665
再次查看一下httpd正在運行的進程:
(flaskApi) [root@67 flaskDemo]# ps aux |grep httpd root 27835 0.0 0.0 112724 988 pts/0 S+ 15:46 0:00 grep --color=auto httpd
全部殺完了... 殺死進程方法有很多種...我這個 只是其中的一種
通過netstat確認一下,httpd已經不再占用80端口了
(flaskApi) [root@67 flaskDemo]# netstat -tpnul
另如果不想殺死進程,而想修改端口號,
操作方法參照:centos7 ngxin啟動失敗:Job for nginx.service failed(80端口被占用的解決辦法)
參照文檔:
轉載于:https://www.cnblogs.com/kaerxifa/p/11534539.html
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
因為自己學習了前端大部分知識,然后想自己做網站,于是學習了node.js,可不知道如何將項目發布到網上,所以花了很多天的時間,搜集了很多的資料,才將項目部署到服務器上,這里給大家分享一下我的部署過程,以免大家走彎路。
- 公眾號:前端印象
- 不定時有送書活動,記得關注~
- 關注后回復對應文字領?。骸久嬖囶}】、【前端必看電子書】、【數據結構與算法完整代碼】、【前端技術交流群】
這里我們就用騰訊云的服務器吧,因為優惠感覺還是比較大的,性價比也高。
先進入學生頁面,購買優惠的服務器套餐,每個月才10元,學生服務器優惠套餐鏈接 。也可以參與限時的秒殺活動,一年才99,用來學習再合適不過了,服務器顯示秒殺鏈接。 如果需求大的話,也可以直接買那些高配的服務器其他服務器鏈接
購買中,所有都默認選項。
購買完成后, 進入控制臺
然后重置一下密碼,一定要記住
我們鼠標移到這看一下服務器的系統是不是CentOS, 因為我們要用到這個版本
如果不是的話,就可以點擊重裝系統, 自己選擇一下CentOS這個系統即可,并且重裝時設置的密碼也一定要記住哦。
這樣一臺服務器也就購買成功了。
網上下載一個xshell5, 用于我們登錄我們的服務器
Xshell5下載地址
下載好以后,打開Xshell5, 點擊新建
去復制一下我們的公網ip
然后按以下提示輸入
以下配置完成后直接點確定
在下圖輸入框中,輸入以下代碼,并按回車
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
遇到該命令,直接輸入y 然后回車,就他自動安裝吧,時間就點長,耐心等待一下
安裝好后,會出現這個圖示界面
訪問該頁面, 并輸入相應的賬號密碼進行登錄
登錄了以后點擊 直接安裝
這時候別閑著,去軟件商店里,找到這兩個軟件安裝一下
先回到我們的騰訊云控制臺
按下圖輸入,并點完成
接下來就可以將我們的項目放到壓縮文件中,然后上傳到寶塔面板中了
,上傳好后直接點解壓就可以了
找到我們的pm2, 開始設置我們的項目
然后點擊映射,將我們的公網ip 映射一下
如果這里的端口是3000,我們需要將入口文件中的端口號改一下,我這里是改為5000了
入口文件的端口號修改好后,我們需要放行一下我們項目網站的端口號,即做以下兩個步驟
然后重啟一下項目
這樣一個node.js項目就部署完成啦,接下來就通過公網ip + 端口號的方式進行訪問
可以看到訪問成功了。
這是我查閱了大量資料,才部署上去的node.js 項目,因為我是做前端的,所以不太懂運維這些的,只能做這樣一個簡單的部署, 不過對于新手學習已經完全足夠了,希望這篇文章能幫助到你們。
轉自:csdn 作者:「零一」
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
接口測試:
接口:是傳遞數據的通道。接口測試主要用于檢測外部系統與系統之間以及內部各個子系統之間的交互點。
測試的重點是要檢測數據的交換,傳遞和控制管理過程,以及系統間的相互邏輯依賴關系等。
接口的分類:
外部接口:調用第三方平臺的接口
內部接口:登陸和注冊這種單獨的內部接口
1、首先下載好tomcat軟件包
2、通過Xftp軟件傳輸到我們Linux虛擬機的 /opt目錄下
3、通過Xshell我們可以在/opt目錄下看到tomcat軟件包(如下圖紅色框內)
4、我們解壓tomcat是用:tar -xzvf apache-tomcat-8.0.30.tar.gz 命令進行解壓,可以看到解壓后的文件(如下圖綠色框內)因為我已經解壓過了,就不給大家示范了(這里要注意的是因為我在opt目錄下的,所以用這個解壓命令,如果你沒在你要解壓的目錄下就要在后面加 -c 這個參數)
5、接下來我們下載JDK(注意JDK的位數和系統區別):我是在64位Linux系統部署的
6、上傳和解壓和tomact一樣都是tar.gz格式的,解壓命令都一樣,也是放在opt目錄下
7、驗證JDK是否安裝好(java -version)
8、在其他目錄下執行(java -version)是不成功的,所以要配置JDK環境變量,通過編輯 vi etc/profile 在最后段加上
JAVA_HOME=/opt/jdk1.8.0_141 -----》改成自己的jdk路徑
JAVA_BIN=$JAVA_HOME/bin
JRE_HOME=$JAVA_HOME/jre
JRE_BIN=$JRE_HOME/bin
PATH=$JAVA_BIN:$JRE_BIN:$PATH
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
export JAVA_HOME JRE_HOME PATH CLASSPATH
9、然后輸入 source /etc/profile命令,使環境變量生效,現在使用Java -version目錄下驗證JDK是否已經全局生效
10、在bin目錄啟動tomcat,查看tomcat環境是否能可以啟動( ./startup.sh 啟動 ./startup.sh 關閉 )
11、訪問地址出現如下圖證明tomcat環境搭建好了(你自己虛擬機的IP+tomcat的端口號)
12、修改tomcat的端口號,目錄:在/opt/apache-tomcat-8.0.30/conf,用vi server.xml 修改端口號
13、注意:啟動tomcat要關閉防火墻,最后養成打開日志文件習慣
轉自:csdn 作者:寒門子弟
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
n 次比較相鄰兩數并交換找到最值,然后 n-1 次比較找到次值……較小的數字像氣泡一樣浮出。
這里我引入flag排除,已經有序卻一直遍歷
function bubbleSort(arr){ const n=arr.length; let flag=1,i,j; for(i=0;i<n-1&&flag;i++){ //最壞的情況需要依次比較出最小值、次小值、次次小值 flag=0;//如果交換了就變 for(j=0;j<n-i-1;j++){ if(arr[j]>arr[j+1]){ const swap=arr[j]; arr[j]=arr[j+1]; arr[j+1]=swap; flag=1; } } } return arr; }
和冒泡原理相似,但是少了很多交換,多了一個暫存最值的空間。
n 次比較相鄰兩數后最多只交換一次將最值放到位置上,然后 n-1 次比較找到次值
冒泡更適合基本有序的序列
function selectSort(arr) { const n=arr.length; let i,j,minIndex; for(i=0;i<n-1;i++){ minIndex=i;//先決定誰最小 for(j=i+1;j<n;j++){ if(arr[j]<arr[minIndex]){ minIndex=j; } } if(minIndex!=i){ const swap=arr[i]; arr[i]=arr[minIndex]; arr[minIndex]=swap; } } return arr; }
平均時間復雜度=O(n logn)
function quick_part(arr,left,right){ //留下left和right后面遞歸 var l = left; var r = right; var basic= arr[left]; //arr[left]即basic的原位置 if(left >= right){ //如果數組只有一個元素 return; } while(l!=r){//兩者相遇,意味著一直到找到basic的位置 while(arr[r] > basic && l < r){ //l<r隨時注意嚴格控制哨兵不能錯過,從右邊向左找第一個比key小的數,找到或者兩個哨兵相碰,跳出循環 r--; } while(arr[l] <= basic && l < r){ //這里的=號保證在本輪循環結束前,key的位置不變,否則的話跳出循環,交換l和left的位置的時候,left位置的上元素有可能不是key l++; } //1、兩個哨兵到找到了目標值。2、j哨兵找到了目標值。3、兩個哨兵都沒找到(key是當前數組最小值) if(l!=r){ //交換兩個元素的位置 const swap = arr[l]; arr[l] = arr[r]; arr[r] = swap; } } arr[left] = arr[l] //arr[left]即basic的原位置 arr[l] = basic; quick_part(arr,left,l-1); quick_part(arr,l+1,right); } function quickSort(arr){ quick_part(arr,0,arr.length-1); }
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
轉自:csdn 作者:tututu333
從上往下執行,非常簡單,不做過多贅述。
與c語言不同的是,java的if(布爾表達式)必須是布爾表達式
eg:判斷某一年是否是閏年
public static void main(String[] args) { Scanner scan = new Scanner(System.in); int year = scan.nextInt(); if((year%4==0 && year%100 !=10)||(year%400==0)) System.out.println("閏年!"); else{ System.out.println("不是閏年!"); } }
基礎語法:
switch(整數|枚舉|字符|字符串){ case 內容1 : { 內容滿足時執行語句; [break;] } case 內容2 : { 內容滿足時執行語句; [break;] } ... default:{ 內容都不滿足時執行語句; [break;] } }
面試問題:
不能做switch參數的類型有哪些?
long float double boolean
注意事項:
public static void main(String[] args) { int i=1; int ret=1; while(i<=5) { ret *= i; i++; } System.out.println(ret);
public static void main(String[] args) { Scanner scan = new Scanner(System.in); int num = scan.nextInt(); int sum=0; for(int j=1;j<=num;j++){ int ret=1; for(int i=1;i <= j; i++){ ret*=1; } sum+=ret; } } }
基本語法:
do{
循環語句;
}while(循環條件)
先執行語句再判斷循環條件。
注意事項:
方法就是一個代碼片段. 類似于 C 語言中的 "函數“。
方法:功能
public static 返回值 方法名(形式參數列表){
方法體;
}
方法名:要采用小駝峰的形式,maxNum
public static:因為當前所有的方法寫完之后會在Main方法中調用。
方法體:就是具體方法的實現。
public static void main(String[] args) { int a = 10; int b = 20; // 方法的調用 int ret = add(a, b); System.out.println("ret = " + ret); } // 方法的定義 public static int add(int x, int y) { return x + y; }
方法的重載:
1.方法名相同
2.返回值可以不同
3.參數列表不同(參數的個數和參數的類型不同)
4.必須要在同一個類當中。
eg:
public static void main(String[] args) { int a = 10; int b = 20; int ret = add(a, b); System.out.println("ret = " + ret); double a2 = 10.5; double b2 = 20.5; double ret2 = add(a2, b2); System.out.println("ret2 = " + ret2); double a3 = 10.5; double b3 = 10.5; double c3 = 20.5; double ret3 = add(a3, b3, c3); System.out.println("ret3 = " + ret3); } public static int add(int x, int y) { return x + y; } public static double add(double x, double y) { return x + y; } public static double add(double x, double y, double z) { return x + y + z; } }
方法的名字都叫 add. 但是有的 add 是計算 int 相加, 有的是 double 相加; 有的計算兩個數字相加, 有的是計算三個數字相加.
同一個方法名字, 提供不同版本的實現, 稱為方法重載
一個方法在執行過程中調用自身, 就稱為 “遞歸”。
遞歸相當于數學上的 “數學歸納法”, 有一個起始條件, 然后有一個遞推公式。
遞歸:
1.要調用自己本身。
2.要有一個趨近于終止的條件。
3.推導出遞歸的公式。
eg:求N的階乘
public static void main(String[] args) { int n = 5; int ret = factor(n); System.out.println("ret = " + ret); } public static int factor(int n) { if (n == 1) { return 1; } return n * factor(n - 1); // factor 調用函數自身 }
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
轉自:csdn 作者:flyyyya
在平時獲取后臺數據渲染頁面的時候可能會出現后臺返回的數據是帶有 html 特殊標簽的
需求是附帶的樣式也不要, 意思就是直接刪掉那些內容
但是在網上找挺久都沒有找到現成的方法 最后是自己找了兩個方法拼接出來的 所以在這里總結一下 方便以后直接 cv
// 返回數據: ret : { list: { "introduct": '<p style="color: lightcoral;">就 當文字就是內容吧。</p>', } } // 或者 ret : { list: { "introduct": '<span style="color: skyblue">就當文字就是內容吧。 </p>', } }
// 返回數據帶有html特殊字符的話直接用 v-html 在頁面上顯示的是 html標簽 <body> <div id="app"> <div class="fd"> {{message}} // 如果需要數據中的樣式的可以直接 v-html 指令渲染這個字段就能渲染出來了 <div class="box" v-html="'v-html: ' + message"></div> <button class="btn" @click="click1">dianwo</button> </div> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { message: '<p style="color: lightcoral;">就 當文字就是內容吧。</p>' }, methods: { click1() { this.message = this.escapeHtml(this.message) }, // 處理方法 escapeHtml(str) { var arrEntities = { 'lt': '<', 'gt': '>', 'nbsp': ' ', 'amp': '&', 'quot': '"' }; return str.replace(/&(lt|gt|nbsp|amp|quot);/ig, function(all, t) { return arrEntities[t]; }); }, } }) </script>
上面這個方法來自:https://blog.csdn.net/weixin_49186680/article/details/108746341
// 如果不想要后臺返回在數據終的樣式的話可以這樣處理 <body> <div id="app"> <div class="fd"> {{message}} <div class="box" v-html="'v-html: ' + message"></div> <button class="btn" @click="click1">dianwo</button> </div> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { message: '<span style="color: skyblue">就當文字就是內容吧。 </span>' }, methods: { click1() { this.message = this.delHtmlTag(this.message) }, // 處理方法 delHtmlTag(str) { return str.replace(/<[^>]+>/g, '').replace(/ /ig, "") } } }) </script>
上面的方法來自:https://blog.csdn.net/weixin_44565191/article/details/109716908
// 如果返回的帶有 html特殊字符 都不要 結合上面兩個方法 改吧改吧 就能瞞住要求了 <body> <div id="app"> <div class="fd"> {{message}} <div class="box" v-html="'v-html: ' + message"></div> <button class="btn" @click="click1">dianwo</button> </div> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { message: '<span style="color: skyblue">就當文字就是 內 容吧</span>' }, methods: { click1() { this.message = this.escapeHtml(this.message) }, // 終極 處理方法 escapeHtml(str) { var arrEntities = { 'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"' }; let htmlTag = str.replace(/&(lt|gt|amp|quot);/ig, function(all, t) { return arrEntities[t]; }); // console.log(htmlTag); return htmlTag.replace(/<[^>]+>/g, '').replace(/ /ig, "") }, } }) </script>
感謝一下引用的這些大佬的內容
還有附上 樣式 要想親自試試效果的我把樣式放這里
.fd { margin: 100px auto; display: flex; flex-direction: column; justify-content: center; align-items: center; } .box { margin: 30px 0; display: flex; align-items: center; } .btn { width: 100px; }
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
轉自:csdn 作者:小王幾pl
不管哪種模式,前端路由都是客戶端路由的實現方式,也就是當路徑發生變化時,不會向服務器發送請求,是利用js監視路徑的變化。然后根據不同的地址渲染不同的內容,如果需要服務器內容,會發送Ajax請求來獲取。
https://music.163.com/#/discover/toplist
地址中會存在 # 號
https://music.163.com/discover/toplist
地址中沒有# 類似于普通的地址,但是需要服務端配置支持
在 node 環境下,啟用對history模式的支持可以通過 connect-history-api-fallback 這個中間件來完成
// 導入處理 history 模式的模塊 const history = require('connect-history-api-fallback') // 導入 express const express = require('express') const app = express() // 注冊處理 history 模式的中間件 app.use(history())
運行nginx服務器基本指令
啟動
start nginx
重啟
nginx -s reload
停止
nginx -s stop
location / { root html; index index.html index.htm; #新添加內容
#嘗試讀取$uri(當前請求的路徑),如果讀取不到讀取$uri/這個文件夾下的首頁
#如果都獲取不到返回根目錄中的 index.html
try_files $uri $uri/ /index.html; }
從上圖,可以大致了解一下 VueRouter 這個類中的結構:
上半部分是屬性,下半部分是方法,其中+ 是實例方法,- 是靜態方法。
install 是用來實現Vue.use 插件機制的方法。
要實現install方法,首先先分析一下該方法要做的事情:
let _Vue; export default class VueRouter { static install(Vue) { // 1. 判斷當前插件是否已經被安裝 if(VueRouter.install.installed) return VueRouter.install.installed = true // 2. 把Vue構造函數記錄到全局變量 _Vue = Vue // 3. 把創建Vue實例時候傳入的router對象注入到所有的Vue實例上 // 利用混入讓所有的vue實例加載router _Vue.mixin({ beforeCreate(){ // this.$options.name用來獲取vue實例 data以外的屬性 // new Vue( { router } ) if(this.$options.router) { _Vue.prototype.$router = this.$options.router } } }) } }
VueRouter 的構造函數要初始化三個屬性,分別是: options、data、routeMap。
constructor(options){ this.options = options this.data = _Vue.observable({ current:'/' }) this.routeMap = {} }
接下來我們來實現VueRouter類中 createRouterMap 這個方法,它的作用就是把 options 中rules 路由規則解析出來以鍵值對的形式存儲在routeMap上。
createRouterMap() { this.options.rules.forEach(route => this.routeMap[route.path] = route.component) }
下一步,來創建initComponents 方法,這個方法里我們要創建兩個組件。分別是:RouterLink 和 RouterView
let _Vue; export default class VueRouter { static install(Vue) { // 1. 判斷當前插件是否已經被安裝 if (VueRouter.install.installed) return VueRouter.install.installed = true // 2. 把Vue構造函數記錄到全局變量 _Vue = Vue // 3. 把創建Vue實例時候傳入的router對象注入到所有的Vue實例上 // 利用混入讓所有的vue實例加載router _Vue.mixin({ beforeCreate() { // this.$options.name用來獲取vue實例 data以外的屬性 // new Vue( { router } ) if (this.$options.router) { _Vue.prototype.$router = this.$options.router this.$options.router.init() } } }) } constructor(options) { this.options = options this.routeMap = {} this.data = _Vue.observable({ current: '/' }) } createRouterMap() { this.options.routes.forEach(route => this.routeMap[route.path] = route.component) } initComponents(Vue) { // 創建RouterLink組件 Vue.component('router-link', { props: { 'to': { type: String } }, template: `<a :href="to"><slot></slot></a>` }) } init() { this.createRouterMap() this.initComponents(_Vue) } }
用自己的VueRouter 替換掉官方的運行后,發現報錯
報錯的意思是,運行時版本的Vue 不支持 tempalte 模板,需要打包的時候提前編譯。
如果要讓我們的template被支持可以使用完整版的Vue,完整包包含運行時和編譯器,體積比運行時版本大10k左右,程序運行的時候把模板轉換成render函數
@vue/cli 自動安裝的就是 運行時版本
第一種方案——引入完整版Vue,可以在vue.config.js中 加入配置
module.exports = { runtimeCompiler: true }
第二種方案——使用render函數替換掉tempalte
render(h) { return h('a', { attrs: { href: this.to } }, [this.$slots.default]) } // template: `<a :href="to"><slot></slot></a>`
// 記錄一下this let self = this Vue.component('router-view',{ render(h){ // routeMap以key value形式記錄了path和component // data.current 記錄了當前頁面的path return h(self.routeMap[self.data.current]) } })
為了能夠讓鏈接成功完成跳轉展示組件,我們需要對routerlink中的a標簽添加點擊事件
并且要在點擊的時候,把最新的path更新到router實例的current上.
我們借助于history的pushState方法 該方法會修改瀏覽器地址欄中的地址,但不會向服務器發起請求,并且還可以將新地址記錄在歷史中
Vue.component('router-link', { props: { 'to': { type: String } }, render(h) { return h('a', { attrs: { href: this.to }, on: { click: this.clickHandle } }, [this.$slots.default]) }, methods: { clickHandle(e) { history.pushState({}, "", this.to) // 把點擊的鏈接地址 更新到 current 上 this.$router.data.current = this.to
e.preventDefault() } } // template: `<a :href="to"><slot></slot></a>` })
現在功能基本上已經差不多了,但是還存在一個小問題,就是當我們點擊瀏覽器的前進或者后退按鈕的時候,組件不能實現切換展示,主要思路就是通過添加popstate監聽地址變化,下面我們來完善該功能
initEvent(){ // window.addEventListener("popstate",()=>{ this.data.current = window.location.pathname }) }
完整代碼
let _Vue; export default class VueRouter { static install(Vue) { // 1. 判斷當前插件是否已經被安裝 if (VueRouter.install.installed) return VueRouter.install.installed = true // 2. 把Vue構造函數記錄到全局變量 _Vue = Vue // 3. 把創建Vue實例時候傳入的router對象注入到所有的Vue實例上 // 利用混入讓所有的vue實例加載router _Vue.mixin({ beforeCreate() { // this.$options.name用來獲取vue實例 data以外的屬性 // new Vue( { router } ) if (this.$options.router) { _Vue.prototype.$router = this.$options.router console.log(this.$options.router.init); this.$options.router.init() } } }) } constructor(options) { this.options = options this.routeMap = {} this.data = _Vue.observable({ current: '/' }) } createRouterMap() { this.options.routes.forEach(route => this.routeMap[route.path] = route.component) } initComponents(Vue) { // 創建RouterLink組件 Vue.component('router-link', { props: { 'to': { type: String } }, render(h) { return h('a', { attrs: { href: this.to }, on: { click: this.clickHandle } }, [this.$slots.default]) }, methods: { clickHandle(e) { history.pushState({}, "", this.to) // 把點擊的鏈接地址 更新到 current 上 this.$router.data.current = this.to
e.preventDefault() } } // template: `<a :href="to"><slot></slot></a>` }) let self = this Vue.component('router-view', { render(h) { // routeMap以key value形式記錄了path和component // data.current 記錄了當前頁面的path return h(self.routeMap[self.data.current]) } }) } init() { this.createRouterMap() this.initComponents(_Vue) this.initEvent() } initEvent() { // window.addEventListener("popstate", () => { this.data.current = window.location.pathname }) } }
轉自:csdn 作者:Holyforsaken_FHC
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
--手機appUI設計--
--bs界面設計--
在談回調函數之前,先看下下面兩段代碼:
不妨猜測一下代碼的結果。
function say (value) {
alert(value);
} alert(say); alert(say('hi js.'));
如果你測試了,就會發現:
只寫變量名 say 返回的將會是 say方法本身,以字符串的形式表現出來。
而在變量名后加()如say()返回的就會使say方法調用后的結果,這里是彈出value的值。
再看下面的兩段代碼:
function say (value) { alert(value);
} function execute (someFunction, value) { someFunction(value);
}
execute(say, 'hi js.');
與
function execute (someFunction, value) { someFunction(value);
}
execute(function(value){alert(value);}, 'hi js.');
上面第一段代碼是將say方法作為參數傳遞給execute方法
第二段代碼則是直接將匿名函數作為參數傳遞給execute方法
實際上:
function say (value) { alert(value);
} // 注意看下面,直接寫say方法的方法名與下面的匿名函數可以認為是一個東西 // 這樣再看上面兩段代碼是不是對函數可以作為參數傳遞就更加清晰了 say; function (value) { alert(value);
}
這里的say或者匿名函數就被稱為回調函數。
如果回調函數需要傳參,如何做到,這里介紹兩種解決方案。
回調函數應用場景多用在使用 js 寫組件時,尤其是組件的事件很多都需要回調函數的支持。
轉自:csdn 作者:dkvirus
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
移動互聯網的迅速崛起,讓移動網頁,移動客戶端越來越重要,客戶端的頁面設計也是一門很大的學問??萍佳杆侔l展的今手機屏幕的尺寸越來越放大化,但卻始終 很有限,因此,在APP的界面設計中,精簡是一貫的準則。這里所說的精簡并不是內容上盡可能的少量,而是要注重重點的表達。在視覺上也要遵循用戶的視覺邏 輯,用戶看著順眼了,才會真正的喜歡。
接下來為大家分享精美的app UI設計案例:
--手機appUI設計--
更多精彩文章:
藍藍設計的小編 http://www.syprn.cn