如何搭建SPA-单页面应用

背景

初出社会,刚实习两个月,在公司做Java开发的时候偶尔使用AngularJS框架写一些页面。觉得用起来特别爽。 
言归正传,为了完成毕设,被迫在工作之余,研究了AngularJS路由的使用,进而了解了SPA应用在用户体验上所占据的优势。于是从毕设项目中提取出了自己搭建SPA的过程,做了一个小的Demo,在此做记录。

准备工作

在这个Demo中我使用npm管理框架的依赖包,需要准备的框架分别如下:

npm命令
AngularJS npm install angular
Angular Route npm install angular-route
为了让页面看起来爽,还加了妹子UI的框架包 ↓↓↓↓
Amaze UI npm install amazeui
jQuery npm install jquery

所以整个项目的目录结构如下:

这里写图片描述

注:view放置的是为主页面引用的模板html代码,js放置的是各模板的Controller和整个应用的配置文件

编写主页面

因为是SPA,所以理论上页面只能有一个,其他的都为主页面所引用。在主页中要做的工作就是把应用的整体结构搭建出来,以及引用一些框架资源和Controller。

页面内容分成了头、内容、脚,其中内容部分通过路由引用其他html代码 
main.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用AngularJS构建SPA</title>
    <link rel="stylesheet" href="../node_modules/amazeui/dist/css/amazeui.min.css"/>
</head>
<body ng-app="spaApp">
    <!--header start 引入页头文件-->
    <section id="header" ng-include="'header.html'">

    </section>
    <!--header end-->

    <!--content start 使用ng-view显示路由控制的html模板 -->
    <section id="content" class="am-container">
        <ng-view></ng-view>
    </section>
    <!--content end-->

    <!--footer start 引入页脚文件-->
    <section id="footer" ng-include="'footer.html'"></section>
    <!--footer end-->

    <!-- js framework file -->
    <script src="../node_modules/jquery/dist/jquery.min.js"></script>
    <script src="../node_modules/amazeui/dist/js/amazeui.min.js"></script>
    <script src="../node_modules/angular/angular.js"></script>
    <script src="../node_modules/angular-route/angular-route.js"></script>

    <!-- js config file 各配置文件 -->
    <script src="js/config/app_config.js"></script>
    <script src="js/config/route_config.js"></script>

    <!-- js controller file 各html模板控制器 -->
    <script src="js/controller/headerCtrl.js"></script>
    <script src="js/controller/footerCtrl.js"></script>
    <script src="js/controller/pageOneCtrl.js"></script>
    <script src="js/controller/pageTwoCtrl.js"></script>

</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

编写页头页脚

页头文件和页脚文件因为是这个应用的基本显示部分,每个页面都具有相同的页头页脚,所以不需要路由控制,独立出header.html和footer.html及他们对应的控制器(当然,如果不需要现实全局变量,不需要控制器也行),代码如下。 
header.html

<div ng-controller="headerCtrl">
    <header class="am-topbar">
        <h1 class="am-topbar-brand">
            <a href="#toOne">{{APP_NAME}}</a>
        </h1>
        <button class="am-topbar-btn am-topbar-toggle am-btn am-btn-sm am-btn-success am-show-sm-only" data-am-collapse="{target: '#doc-topbar-collapse'}"><span class="am-sr-only">导航切换</span> <span class="am-icon-bars"></span></button>
        <div class="am-collapse am-topbar-collapse" id="doc-topbar-collapse">
            <ul class="am-nav am-nav-pills am-topbar-nav">
                <li><a href="#toOne">One</a></li>
                <li><a href="#toTwo">Two</a></li>
            </ul>
        </div>
    </header>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

footer.html

<div ng-controller="footerCtrl">
    <footer data-am-widget="footer"
            class="am-footer am-footer-default am-topbar-fixed-bottom"
            data-am-footer="{  }">
        <div class="am-footer-switch">
            <span>{{APP_NAME}}</span>
            <span class="am-footer-divider"> | </span>
            <span>好好学习,天天向上</span>
        </div>
        <div class="am-footer-miscs ">

            <p><a href class="">{{DEVELOPER_NAME}}</a>
                提供技术支持</p>
            <p>2018 </p>
        </div>
    </footer>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

编写应用主体部分的内容

这里我简单使用了两个页面pageOne.html、pageTwo.html来模拟单页面应用的两个独立页面。页面代码以及对于Controller如下: 
pageOne.html

<div>
    <h1>I am page One</h1>
    <h2>Here is my data: {{data}}</h2>
</div>
  • 1
  • 2
  • 3
  • 4

pageOneCtrl.js

spaApp.controller('pageOneCtrl',['$scope', '$rootScope', function($scope, $rootScope){
    $scope.data = "Welcome to page one !";
}]);
  • 1
  • 2
  • 3

pageTwo.html

<div>
    <span class="am-text-xxxl">I am page Two</span>
    <hr>
    <span class="am-text-lg">Here is my data: {{data}}</span>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5

pageTwoCtrl.js

spaApp.controller('pageTwoCtrl',['$scope', '$rootScope', function($scope, $rootScope){
    $scope.data = 'Get out from page two !';
}]);
  • 1
  • 2
  • 3

按照期望,点击header中的One应该在页面上显示“Welcome to page one !”,而点击Two应该在页面上显示“Get out from page two !”。所以接下来要写的就是将模板代码引用到主页面上的配置。

编写整体配置文件

1. 全局配置

包含了对module的定义、全局变量的设置 
app_config.js

/*
 * 全局配置文件
 * 1. 定义module
 * 2. 配置全局变量
 */
var spaApp = angular.module('spaApp', ['ngRoute']);

spaApp.run(['$rootScope', function($rootScope){
    //通过rootScope把全局使用的东西配置好,比如应用名
    $rootScope.APP_NAME = 'SPA搭建总结';
    $rootScope.DEVELOPER_NAME = '谢仲东';
}]);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.路由配置

主要配置路由中各个锚点指向的html文件和对应的Controller 
route_config.js

/*
 * 路由配置文件
 * 1.配置路由地址和对应的View&Controller
 */
spaApp.config(function ($routeProvider, $locationProvider) {
    //防止路由地址出现感叹号和乱码
    $locationProvider.hashPrefix('');

    //当锚点为toOne时,ng-view加载pageOne.html和pageOneCtrl
    //当锚点为toTwo时,ng-view加载pageTwo.html和pageTwoCtrl
    //其余情况重定向到toOne
    $routeProvider
        .when(
            '/toOne',
            {
                templateUrl: 'view/pageOne.html',
                controller: 'pageOneCtrl'
            }
        ).when(
            '/toTwo',
            {
                templateUrl: 'view/pageTwo.html',
                controller: 'pageTwoCtrl'
            }
        ).otherwise(
            {
                redirectTo: '/toOne'
            }
        )
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

日后开发流程

经过路由的辅助,再也不用使用js往iframe里面装东西了。岂不爽哉?搭建完这个应用的整体结构后,接下来的开发就可以分为这几步:

  • 写新页面,例如pageThree.html。
  • 写控制这个页面的Controller,例如pageThreeCtrl.js。
  • 在主页面main.html中引用新的Controller
<script src="js/controller/pageThreeCtrl.js"></script>
  • 1
  • 去route_config.js 加一个锚点指向设置
.when(
          '/toThree',
          {
              templateUrl: 'view/pageThree.html',
              controller: 'pageThreetrl'
          }
      )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 最后在任意页面的任意位置使用<a>标签来在应用内改变主体内容。
<a href="#/toThree">Three</a>
  • 1
  • 愉快地开发吧!

效果图

这里写图片描述

搭建过程遇到的问题

  1. 跨域问题:因为AngularJS路由使用了Ajax异步请求,然后将模板注入到主页中。所以会出现跨域问题。所以我把Demo放在了一个SpringBoot项目中,在tomcat上访问就不会出现跨域报错问题。当然也可以放到Apache httpd上,或者在浏览器上做手脚。
  2. ng-include指令不生效:原因是ng-include指令的值没有加单引号,正确的使用方法应该是<div ng-include="'xxx.html'"></div>,粗心。
  3. 有一个缺点就是一个module里只能使用一个路由,所以如果你主页上有多个地方要实现路由就要创建多个module,分别进行配置。

项目地址

传送门:使用AngularJS搭建SPA的Demo

猜你喜欢

转载自blog.csdn.net/weixin_40889776/article/details/80943413
今日推荐