单页 Web 应用 (single-page application 简称为 SPA) 是一种特殊的 Web 应用。它将所有的活动局限于一个Web页面中,仅在该Web页面初始化时加载相应的HTML、JavaScript 和 CSS。一旦页面加载完成了,SPA不会因为用户的操作而进行页面的重新加载或跳转。而是利用 JavaScript 动态的变换HTML的内(采用的是div切换显示和隐藏),从而实现UI与用户的交互。由于避免了页面的重新加载,SPA 可以提供较为流畅的用户体验。得益于ajax,我们可以实现无跳转刷新,又多亏了浏览器的histroy机制,我们用hash的变化从而可以实现推动界面变化。

angularJS,是目前中最流行的mvvm框架,非常适合做SPA;与之类似的还有vueJS,backbone,extjs等。

hash值

即url中#号后面的部分。

<a href="target">go target</a>

......
<div id="target">i am target place</div>
点击a链接,文档会滚动到id为target的div的可视区域上面去。hash除了这个功能还有另一一种含义:指导浏览器的行为但不上传到服务器。大家都知道,改变url中的任何一个字符都会导致浏览器重新请求服务器,除了#号后面那段字符之外。所以,简而言之我们可以这样理解:改变#后面的值不触发网页重载,但会记录到浏览器history中去。

驱动div显示隐藏的方式有很多种,比较好的选择为以下两种:

1.监听地址栏中hash变化驱动界面变化

2.用pushsate记录浏览器的历史,驱动界面发送变化

如何搭建一个基础的SPA

首先,我们画出三个div,它们实际上是作为三个界面存在界面上的,body作为界面外框容器,限制着它们的大小。为了给每个界面配对一个hash地址,我们给每个div配一个id,将hash地址与对应的选择器(id、class)建立链接关系,从而可以从hash变化值中操作界面。

 <body>
  <div id=”A” class=”a”>A</div>
  <div id=”B” class=”b” style=”display:none;”>B</div>
  <div id=”C” class=”c” style=”display:none;”>C</div>
</body>
Hash的改变不会引起界面的刷新,但是会出发onhashchange事件,我们要做的就是监听这个事件:
 
 目前,只需要以上的代码,我们便可以完成一个最简单的SPA,通过地址栏的变化,界面会相应地变化。当然,除了手动在地址栏里面改变hash的变化,我们也可以用代码改变它的变化,从而推动界面变化,
 window.localtion.hash=”A”;
下面是一个利用$.ajax实现的单页面切换的例子:

window.onhashchange = function(){ //监听hash值变化,实现页面变换
var hash=window.location.hash;
changePage(hash);
}

function changePage(hash){
switch (hash)
{
case ‘#index’:
url=’partials/list.html’;
break;
case ‘#newpage’:
url=’partials/newpage.html’;
break;
case ‘#edit’:
url=’partials/edit.html’;
break;
case ‘#view’:
url=’partials/view.html’;
break;
}

$.ajax({            //根据hash值选择页面
type:’GET’,
url:url,
//async:false,
success:function(data){
main.innerHTML=data;
}
});
}


一、SPA的概述

SPA(single page application)单页面应用程序,在一个完成的应用或者站点中,只有一个完整的html页面,这个页面有一个容器,可以把需要加载的代码片段插入到该容器中。

SPA的工作原理:

eg:  http://127.0.0.1/index.html#/start

①根据地址栏中url解析完整的页面:index.html
加载index.html

②根据地址栏中url解析#后的路由地址: start
根据路由地址,去在当前应用的配置中 找该路由地址的配置对象去查找该路由地址 所对应的模板的页面地址
发起异步请求加载该页面地址

③把请求来的数据加载到指定的容器中

二、通过VueRouter来实现一个SPA的基本步骤

①引入对应的vue-router.js(该文件我已经上传到我的文件中)
②指定一个盛放代码片段的容器

<router-view></router-view>

③创建业务所需要的各个组件
④配置路由词典
每一个路由地址的配置对象(要加载哪个页面…)

const myRoutes = [
  {path:'/myLogin',component:TestLogin},
  {path:'/myRegister',component:TestRegister}
  ]
  const myRouter = new VueRouter({
  routes:myRoutes 
  })
  new Vue({
    router:myRouter 
  })

⑤测试
在地址栏中 输入对应的不同的路由地址 确认是否能够加载对应的<!doctype html>

<html>
 <head>
 <meta charset="UTF-8">
 <title></title>
  <script src="js/vue.js"></script>
<!-- 引入文件 -->
  <script src="js/vue-router.js"></script>
 </head>
 <body>
 <div id="container">
    <p>{{msg}}</p>
<!--通过router-view指定盛放组件的容器 -->
    <router-view></router-view>
  </div>
  <script>
    var testLogin = Vue.component("login",{
      template:`
        <div>
          <h1>这是我的登录页面</h1>
        </div>
      `
    })
    var testRegister = Vue.component("register",{
      template:`
        <div>
          <h1>这是我的注册页面</h1>
        </div>
      `
    })
    //配置路由词典
    //对象数组
    const  myRoutes =[
    //当路由地址:地址栏中的那个路径是myLogin访问组件
    //组件是作为标签来用的所以不能直接在component后面使用
    //要用返回值 
      //path:''指定地址栏为空:默认为Login页面
        {path:'',component:testLogin},

      {path:'/myLogin',component:testLogin},
      {path:'/myRegister',component:testRegister}
    ]

    const myRouter = new VueRouter({
      //myRoutes可以直接用上面的数组替换
      routes:myRoutes
    })
    new Vue({
      router:myRouter,
      //或者:
      /*
        router:new VueRouter({
            routes:[
              {path:'/myLogin',component:testLogin},
      {path:'/myRegister',component:testRegister}
            ]
        })
      */
      el:"#container",
      data:{
        msg:"Hello VueJs"
      }
    })
  </script>
 </body>
</html>

<!doctype html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>SPA练习</title>
  <script src="js/vue.js"></script>
  <script src="js/vue-router.js"></script>
 </head>
 <body>
 <div id="container">
    <p>{{msg}}</p>
    <router-view></router-view>
  </div>
  <script>
  /*
    需要大家创建一个SPA,这个SPA有3个组件,分别对应的是collect/detail/order
    功能需求:
    在地址栏中路由地址是:
    /myColllect --> 收藏页组件
    /myDetail --> 详情页组件
    /myOrder --> 订单页组件
  */
  /*
    1、引入js文件
    2、创建三个组件,需要返回值
    3、路由词典配置(三小步)const myRoutes、const myRouter、router:myRouter,
    4、指定一个盛放代码片段的容器
          <router-view></router-view>
  */
    var testCollect = Vue.component("collect",{
      template:`
        <div>
          <h1>这是收藏页</h1>
        </div>
      `
    })
    var testDetail = Vue.component("detail",{
      template:`
        <div>
          <h1>这是详情页</h1>
        </div>
      `
    })
    var testOrder = Vue.component("order",{
      template:`
        <div>
          <h1>这是订单页</h1>
        </div>
      `
    })
    const myRoutes = [
        {path:"",component:testCollect},
        {path:"/myColllect",component:testCollect},
        {path:"/myDetail",component:testDetail},
        {path:"/myOrder",component:testOrder},
    ]
    const myRouter = new VueRouter({
      routes:myRoutes
    })
    new Vue({
      router:myRouter,
      el:"#container",
      data:{
        msg:"Hello VueJs"
      }
    })
  </script>
 </body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助。