最近整理了一下anjularjs的第三方插件ui-route,在這就以一個demo的形式講解一下。整片博客均以開頭的demo代碼爲例。下邊是個目錄,你們能夠酌情直接跳轉瀏覽。javascript
1. demo的代碼css
2. demo效果圖html
3. ui-route是啥?有啥優點?java
4. ui-route基礎用法jquery
5. 如何實現多個視圖分別加載頁面app
6. 如何實現多個視圖嵌套,視圖中套視圖ide
7. ui-route如何實現頁面傳參函數
1. demo的代碼性能
先看一下demo的目錄結構flex
這裏說明一下,主頁面是 index;
index裏面有 家電、美食、廚具3個頁;
家電頁面內有 電腦、手機、電視 3個子頁面;
手機頁面內有 華爲、蘋果、三星、vivo 4個頁面
notice,提示頁。和家電頁面同級別
再看一下具體的代碼
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ui-route簡易demo</title> <style type="text/css"> *{ margin: 0; padding: 0; text-decoration: none; } #ui-route{ margin: 50px auto; overflow: hidden; width: 616.6px; } ul li{ list-style: none; width: 60px; height: 50px; margin: 50px 20px 10px 20px; cursor: pointer; } ul,.indexView,.view1,.view2{ float: left; overflow: hidden; } .indexView{ height: 350px; width: 400px; border: 1px solid black; } .view1,.view2{ width: 80px; height: 175px; border: 1px solid #66AFE9; font-size: 18px; color: fuchsia; font-weight: bold; } .view1{ text-align: center; word-break: break-all; } .view2{ text-align: center; line-height: 177px; } .jiadian{ width: 400px; list-style: none; display: flex; text-align: center; justify-content: space-around; } .jdView{ width: 300px; height: 200px; border: 1px solid salmon; margin: 110px auto; } .phone li{ list-style: none; width: 40px; height: 30px; margin: 15px; } .phoneView{ width: 200px; height: 200px; border: 1px solid aqua; margin-left: 80px; } .phoneView p{ margin: 10px 5px 15px 5px; } .noticeView{ width: 80px; height: 90px; border-top: 1px solid royalblue; border-bottom: 1px solid royalblue; } </style> </head> <body ng-app="myApp" ng-controller="myControll"> <div id="ui-route"> <ul> <li ui-sref="jia_dian">家電</li> <li ui-sref="mei_shi">美食</li> <li ui-sref="chu_ju({word:'這是向家電頁面傳遞的參數word'})">廚具</li> </ul> <div class="indexView" ui-view="indexView"></div> <div class="view1" ui-view="view1"></div> <div class="view2" ui-view="view2"></div> </div> </body> <script type="text/javascript" src="js/jquery-1.11.3.min.js" ></script> <script type="text/javascript" src="js/angular.min.js" ></script> <script type="text/javascript" src="js/angular-ui-router.js" ></script> <script type="text/javascript"> var myApp = angular.module("myApp", ["ui.router"]); myApp.config(function($stateProvider, $urlRouterProvider){ $urlRouterProvider.when('indexView', "jia_dian"); $stateProvider //這個是多層視圖嵌套的,一共嵌套了3層 //這個仍是多視圖同時呈現,indexView、 view一、view2 同時呈現 .state("jia_dian",{ //url 第一次加載頁面時,有URL能夠自動顯示默認的頁面,沒有隻會在點擊按鈕以後才能加載視圖 //並且刷新頁面時,若是沒有寫URL,頁面不會保存,加了,簡單刷新並不會使頁面消失 url:"/jia_dian", views:{ "indexView":{ templateUrl:'page/jia_dian.html', controller: "myControll" }, "view1":{ templateUrl:'page/notice.html', controller: "myControll" }, "view2":{ templateUrl:'page/buy.html' } } }) .state("mei_shi",{ url:"/mei_shi", views:{ "indexView":{ templateUrl:'page/mei_shi.html', controller: "myControll" } } }) .state("chu_ju",{ url:"/chu_ju", views:{ "indexView":{ templateUrl:'page/chu_ju.html' } } }) //家電內部,電腦、手機等詳情 //注意,視圖的嵌套,路由狀態必須是嵌套的形式,jia_dian.jd_computer。 //若是,路由狀態只是jd_computer,這裏新加載的視圖會默認加載到父視圖indexView中 //切記,多層嵌套必定要把每次視圖狀態名一個個點連接下去,不然會出問題 .state("jia_dian.jd_computer",{ //這裏也能夠傳參數 url:"/jd_computer", views:{ "jdView":{ controller: function($scope,$stateParams){ $scope.myWord = $stateParams.word; console.log($stateParams); console.log($stateParams.word); }, templateUrl:'page/jia_dian/jd_computer.html' } } }) .state("jia_dian.jd_phone",{ url:"/jd_phone", views:{ "jdView":{ templateUrl: 'page/jia_dian/jd_phone.html', controller: "myControll" } } }) .state("jia_dian.jd_TV",{ url:"/jd_TV/?aa", views:{ "jdView":{ controller: function($scope,$stateParams){ console.log($stateParams); console.log($stateParams.word); }, templateUrl: 'page/jia_dian/jd_TV.html' } } }) //家電——手機 中的各類手機介紹路由 .state("jia_dian.jd_phone.hw",{ url:"/jd_phone_hw", views:{ "phoneView":{ templateUrl: 'page/jia_dian/jd_phone_hw.html', controller: "myControll" } } }) .state("jia_dian.jd_phone.pg",{ url:"/jd_phone_pg", views:{ "phoneView":{ templateUrl: 'page/jia_dian/jd_phone_pg.html', controller: "myControll" } } }) .state("jia_dian.jd_phone.sx",{ url:"/jd_phone_sx", views:{ "phoneView":{ templateUrl: 'page/jia_dian/jd_phone_sx.html', controller: "myControll" } } }) .state("jia_dian.jd_phone.vivo",{ url:"/jd_phone_vivo", views:{ "phoneView":{ templateUrl: 'page/jia_dian/jd_phone_vivo.html', controller: "myControll" } } }) //右上角notice模塊路由各狀態 .state("jia_dian.notice_in1",{ url:"/notice_in1", views:{ "noticeView":{ templateUrl: 'page/notice/notice_in1.html', controller: "myControll" } } }) .state("jia_dian.notice_in2",{ url:"/notice_in2", views:{ "noticeView":{ templateUrl: 'page/notice/notice_in2.html', controller: "myControll" } } }) .state("jia_dian.notice_in3",{ url:"/notice_in3", views:{ "noticeView":{ templateUrl: 'page/notice/notice_in3.html', controller: "myControll" } } }) $urlRouterProvider.otherwise('/jia_dian'); }) .controller("myControll",function($scope,$state,$stateParams){ $scope.num = 0; //手機頁須要的數據 $scope.data = [ { name:"華爲 P11", price:"3799 RMB", color:"純潔白", remark:"華爲旗艦版,徠卡雙攝,體驗極度的流暢,你值得擁有!!!" }, { name:"iPhone8s", price:"6034 RMB", color:"冷傲黑", remark:"蘋果旗艦機,你沒有看錯,6千多大洋,就是我,我貴,我任性!!!" }, { name:"三星 Glary12", price:"4799 RMB", color:"冷銀白", remark:"看什麼看,當心我炸你啊" }, { name:"vivo R13", price:"3099 RMB", color:"高貴金", remark:"高貴如我,性能還好,勝在價低,要不要試試?" } ]; $scope.goPhone=function(){ $state.go("jia_dian.jd_phone",{}) }; //經過視圖的形式,點擊切換視圖 $scope.huan=function(){ switch ($scope.num){ case 0: $state.go("jia_dian.notice_in1",{}); break; case 1: $state.go("jia_dian.notice_in2",{}); break; case 2: $state.go("jia_dian.notice_in3",{}); break; default: $scope.num = 0; $state.go("jia_dian.notice_in1",{}); break; } $scope.num++; }; //不推薦 anjularjs 中寫 jQuery ,可是我這就偷懶了 $("li").on("click",function(){ $("li").css({"color":"black","font-weight":"normal"}); $(this).css({"color":"red","font-weight":"600","font-size":"18px"}); }) }) </script> </html>
家電頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <ul class="jiadian"> <li ui-sref="jia_dian.jd_computer">電腦</a></li> <li ng-click="goPhone()">手機</li> <li ui-sref="jia_dian.jd_TV">電視</li> </ul> <div class="jdView" ui-view="jdView"></div> </body> </html> 美食頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> 美食 </body> </html> 廚具頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> 廚具 </body> </html> notice頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <br /> <div class="noticeView" ui-view="noticeView"></div> <br /> <button ng-click="huan()">下一條</button> </body> </html> buy頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <button>加入購物車</button> </body> </html> 電腦頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> 電腦 </body> </html> 手機頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <ul class="phone"> <li ui-sref="jia_dian.jd_phone.hw">華爲</li> <li ui-sref="jia_dian.jd_phone.pg">蘋果</li> <li ui-sref="jia_dian.jd_phone.sx">三星</li> <li ui-sref="jia_dian.jd_phone.vivo">vivo</li> </ul> <div class="phoneView" ui-view="phoneView"></div> </body> </html> 電視頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> 電視 </body> </html> 華爲頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <p>產品: {{data[0].name}}</p> <p>價格: {{data[0].price}}</p> <p>顏色: {{data[0].color}}</p> <p>描述: {{data[0].remark}}</p> </body> </html> 蘋果頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <p>產品: {{data[1].name}}</p> <p>價格: {{data[1].price}}</p> <p>顏色: {{data[1].color}}</p> <p>描述: {{data[1].remark}}</p> </body> </html> 三星頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <p>產品: {{data[2].name}}</p> <p>價格: {{data[2].price}}</p> <p>顏色: {{data[2].color}}</p> <p>描述: {{data[2].remark}}</p> </body> </html> vivo頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <p>產品: {{data[3].name}}</p> <p>價格: {{data[3].price}}</p> <p>顏色: {{data[3].color}}</p> <p>描述: {{data[3].remark}}</p> </body> </html> notice1頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> 驚天大甩賣!!! </body> </html> notice2頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> 買一送三啦!!! </body> </html> notice3頁面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> 你還在等什麼!!! </body> </html>
以上是整個demo的全部代碼,若是有朋友以爲在這複製太麻煩,請到我博客園的 文件區 下載這個demo的源碼。
2. demo效果圖
其實,anjularjs 提供了內置的ng-route,可是不怎麼好用。ui-route相對於ng-route的優點大體以下:
(1) ui-route能夠同時加載多個ui-view,同一張頁面加載多個視圖。ng-route 只能加載一個視圖
(2) ui-route支持 ui-view 中的頁面中也有ui-view,這樣視圖能夠嵌套
(3) ui-route 提供了不少控制視圖的方法,讓咱們操做視圖更便捷
4. ui-route基礎用法
<div id="ui-route"> <ul>
<!--路由狀態跳轉的按鈕--> <li ui-sref="jia_dian">家電</li> <li ng-click="goChuJu()">廚具</li> </ul>
<!--打開的新頁面跳轉到的位置--> <div class="indexView" ui-view="indexView"></div> </div> <script type="text/javascript">
//注入路由模塊 var myApp = angular.module("myApp", ["ui.router"]);
//傳入配置路由的模塊 myApp.config(function($stateProvider, $urlRouterProvider){ $urlRouterProvider.when('indexView', "jia_dian"); $stateProvider
//路由狀態名字,與HTML的ui-sref名字對應 .state("jia_dian",{
//相對的URL url:"/jia_dian", views:{
//加載到哪個 ui-view "indexView":{
//新頁面路徑 templateUrl:'page/jia_dian.html',
//新頁面控制器 controller: "myControll" } } }) .state("chu_ju",{ url:"/chu_ju", views:{ "indexView":{ templateUrl:'page/chu_ju.html', controller: "myControll" } } }) }) .controller("myControll",function($scope,$state,$stateParams){ $scope.goChuJu=function(){ $state.go("jia_dian.jd_phone",{}) }; }) </script>
在HTML中給標籤添加 ui-sref="狀態名";
定義好App以後,配置config,注入 $stateProvider ,經過state配置路由狀態;
當前標籤被點擊時,就會加載對應頁面。
還能夠用 $state.go("jia_dian.jd_phone",{}) 函數,直接跳轉到指定的路由狀態
總之,ui-route 路由頁面跳轉只有 標籤價 ui-sref 和 調用 $state.go() 函數
接下來講明一下如何同時加載多個視圖
<div id="ui-route"> <ul> <li ui-sref="jia_dian">家電</li> </ul> <div class="indexView" ui-view="indexView"></div> <div class="view1" ui-view="view1"></div> <div class="view2" ui-view="view2"></div> </div> <script type="text/javascript"> var myApp = angular.module("myApp", ["ui.router"]); myApp.config(function($stateProvider, $urlRouterProvider){ $urlRouterProvider.when('indexView', "jia_dian"); $stateProvider .state("jia_dian",{ url:"/jia_dian", //經過view屬性進行制定ui-view的頁面分配 views:{ //視圖indexView 的插入內容 "indexView":{ templateUrl:'page/jia_dian.html', controller: "myControll" }, //視圖view1 的插入內容 "view1":{ templateUrl:'page/notice.html', controller: "myControll" }, //視圖view2 的插入內容 "view2":{ templateUrl:'page/buy.html' } } }) }) </script>
同時加載多個視圖,很簡單,只須要再HTML中分別定義好每一個視圖的名字,而後在 state 的 views 中配置每一個view該導入的頁面。這樣就能夠實現一個 index 頁面中有3個 view,並且每一個view都加載本身的HTML文件,實現本身的控制。
可是,有個問題,同一頁面的中的 view ,同一時間只能響應一個路由狀態的變化。
舉一個簡單的例子:
若是,我將 家電、美食 分別加載到 view一、view2 ,這是沒問題的。刷新頁面以後,就能夠實現2個view分別顯示 家電、美食。可是若是我家電中點擊還能分別加載別的手機、電腦頁面,而我在美食點擊以後還能分別加載蘋果、香蕉頁,那這個時候就會發生衝突。路由只能相應一個狀態。好比,點擊 家電——手機,手機頁在 view 中的 jd_view 顯示了,此時再點擊 美食——蘋果,蘋果頁會在 view2顯示,可是view1的手機頁面會被刷新掉,不顯示。家電依然不會變化。
在demo中也有這個問題,你們能夠看一下具體的圖:
仍是,先看代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <ul class="jiadian"> <li ui-sref="jia_dian.jd_computer">電腦</a></li> <li ng-click="goPhone()">手機</li> <li ui-sref="jia_dian.jd_TV">電視</li> </ul> <div class="jdView" ui-view="jdView"></div> </body> <script> ......... //家電內部,電腦、手機等詳情 //注意,視圖的嵌套,路由狀態必須是嵌套的形式,jia_dian.jd_computer。 //若是,路由狀態只是jd_computer,這裏新加載的視圖會默認加載到父視圖indexView中 //切記,多層嵌套必定要把每次視圖狀態名一個個點連接下去,不然會出問題 .state("jia_dian.jd_computer",{ //這裏也能夠傳參數 url:"/jd_computer", views:{ "jdView":{ controller: function($scope,$stateParams){ $scope.myWord = $stateParams.word; console.log($stateParams); console.log($stateParams.word); }, templateUrl:'page/jia_dian/jd_computer.html' } } }) .state("jia_dian.jd_phone",{ url:"/jd_phone", views:{ "jdView":{ templateUrl: 'page/jia_dian/jd_phone.html', controller: "myControll" } } }) .state("jia_dian.jd_TV",{ url:"/jd_TV/?aa", views:{ "jdView":{ controller: function($scope,$stateParams){ console.log($stateParams); console.log($stateParams.word); }, templateUrl: 'page/jia_dian/jd_TV.html' } } }) ......... </script> </html>
嵌套也很簡單,主要是路由狀態的肯定,再就是加載到哪一個view。
由於 電腦 頁面是在 家電頁面之中的,因此 路由狀態名必須加上他父頁面的路由,即 jia_dian.jd_computer,中間用點連接。
注意:(1) 點 前面的名字是 父頁面的路由狀態,必定要一致
(2)嵌套了多少層路由,路由狀態就寫都寫清楚了,不能漏
(3)若是 不寫父頁面的路由,那頁面會直接加載到他的父頁面 所在 的view中,而且會將父頁面給刷掉,只顯示新加載的頁面
(4)新頁面加載到哪,取決於你的views寫的啥,固然,咱們通常會在父頁面中寫個 ui-view ,讓新加載頁面顯示在裏面
多視圖的嵌套,關鍵點 就是路由狀態名 寫對了, views寫明確了。
注意,這個路由傳遞參數是URL傳參,只能小規模的傳字符串之類的;若是是大量數據,仍是用 服務 傳遞,或者直接放在本地存儲中,方便讀取。不過這裏仍是給你們介紹一下ui-route的傳參方式。
首先,看代碼:
<div id="ui-route"> <ul> <li ui-sref="jia_dian">家電</li> <li ui-sref="mei_shi">美食</li> <li ui-sref="chu_ju({word:'這是向家電頁面傳遞的參數word'})">廚具</li> </ul> <div class="indexView" ui-view="indexView"></div> <div class="view1" ui-view="view1"></div> <div class="view2" ui-view="view2"></div> </div> <script type="text/javascript"> .................. .state("jia_dian", { //url 第一次加載頁面時,有URL能夠自動顯示默認的頁面,沒有隻會在點擊按鈕以後才能加載視圖 //並且刷新頁面時,若是沒有寫URL,頁面不會保存,加了,簡單刷新並不會使頁面消失 url: "/jia_dian", views: { "indexView": { templateUrl: 'page/jia_dian.html', controller: "myControll" } } }) .state("jia_dian.jd_phone", { url: "/jd_phone/?word&script&obj", views: { "jdView": { templateUrl: 'page/jia_dian/jd_phone.html', controller: function($scope, $stateParams) { console.log($stateParams); console.log($stateParams.word); console.log($stateParams.obj); } } } }) .controller("myControll", function($scope, $state, $stateParams) { $scope.goPhone=function(){ $state.go("jia_dian.jd_phone",{ word:"前去手機頁面", script:"我將跳轉到jd_phone,即從 家電頁 到 手機頁,我在 家電的controller中寫$state.go函數,並附上參數,而後再路由中問號傳參", obj:{a:"aa",b:"bb"} }) }; }) ................... </script>
其實很簡單,就是URL傳參,步驟以下:
1. 在父頁面HTML中 <li ui-sref="chu_ju({word:'這是向家電頁面傳遞的參數word'})">廚具</li> 這是先定義好要傳遞的變量,附好值
2. 定義變量的另外一種方式 就是在 $state.go("jia_dian.jd_phone",{word:"前去手機頁面"})函數中,這也是在準備須要傳遞的變量
3.上述兩種是觸發路由狀態的2種方式,分別是本身的傳參方式,都是在父頁面的HTML、控制器中。
4. 在子頁面路由狀態中配置將傳的參數 url: "/jd_phone/?word&script&obj", 和問號傳參同樣,多個參數用 & 隔開。
5.在跳轉到的頁面,他的控制器中注入 $stateParams ,而後就能夠打印 $stateParams 這個對象了。
注意:聲明、賦值 是在 父頁面 作的,傳遞是在 子頁面路由中作的,使用、查看在子頁面的控制器。濾清思路就很簡單了。
以上,是我對 ui-route 使用的一點看法,但願對你們能有幫助。若有錯誤的地方,還請朋友們指出!!!