单页面开发案例

1. vue cli 创建一个项目

我们会用到 vue-router

在 views 中创建组件 ,Center.vue、Cinermas.vue、Detail.vue、Films.vue、Login.vue、Order.vue、Search.vue(分别是我的,影院,详情,电影,登录,搜索,订单)。

这只是一个大概框架。

 再创建 films 文件,因为 在 电影页面中包含两个子组件,一个是正在热映 hotplaying.vue 组件,一个是预告电影 Comingsoon.vue.

当点击“我的” 展示用户信息。点击 “ 订单” 展示订单购票信息。点击 “ 影院” 展示附近的影院列表。

点击 “电影” 展示 最近正在热映的电影和预告电影,点击 ”搜索“ 搜索电影。当用户还未登录时,点击 “我的” 会跳转到“登录” 组件。

在 根组件 App.vue 中 显示三个菜单,点击一个菜单,该菜单高亮,进行组件之间的切换。v-slot 传回一个对象,navigate,表示点击的哪一个,isActive 就为 true ,class 值就为 myactive ,否则为 空。(class 用来设置高亮样式。) 详细内容可以见 https:// router.vuejs.org 路由官方文档。

<template>
  <div>
    <header>Welcome to Exciting Cinema</header>
    <ul>
      <router-link to="/films" custom v-slot="{navigate,isActive}">
      <li @click="navigate" :class="isActive?'myactive':''">
        电影--{{isActive}}
      </li>
      </router-link>
      <router-link to="/cinermas" custom v-slot="{navigate,isActive}">
      <li @click="navigate" :class="isActive?'myactive':''">
        影院--{{isActive}}
      </li>
      </router-link>
      <router-link to="/center" custom v-slot="{navigate,isActive}">
      <li @click="navigate" :class="isActive?'myactive':''">
        我的--{{isActive}}
      </li>
      </router-link>
    </ul>
    <!-- 路由容器 相当于插槽 -->
    <!-- router.vuejs.org 路由官方文档 -->
    <router-view></router-view>
  </div>
</template>

在 router 文件下 index.js 打开 注册并且引入路由

import Vue from 'vue'
import VueRouter from 'vue-router'
import Films from '@/views/Films'
import Cinermas from '@/views/Cinermas'
import Login from '@/views/Login'
import Hotplaying from '@/views/films/Hotplaying'
import Comingsoon from '@/views/films/Comingsoon'
import Search from '@/views/Search'
import Detail from '@/views/Detail'

Vue.use(VueRouter) // 注册路由插件
// 配置表
const routes = [
  {
    path: '/films',
    component: Films,
    // 二级路由(嵌套路由)
    children: [
      {
        path: '/films/hotplaying',
        component: Hotplaying
      },
      {
        path: '/films/comingsoon',
        component: Comingsoon
      },
      {
        path: '/films',
        redirect: '/films/hotplaying'
      }
    ]
  },
  {
    name: 'mydetil', // 命名路由
    path: '/detail/:myid', // 动态二级路由
    component: Detail
  },
  {
    path: '/cinermas',
    component: Cinermas
  },
  {
    path: '/cinermas/search',
    component: Search
  },
  {
    path: '/order',
    // 路由懒加载的方式,当需要这个组件出现了这个路径之后再加载 js 文件
    component: () => import('@/views/Order'),
    meta: {
      isMyrequired: true
    }
  },
  {
    path: '/login',
    component: Login
  },
  {
    path: '/center',
    component: () => import('@/views/Center'),
    meta: {
      isMyrequired: true
    }
  },
  {
    // 路由重定向  * 通配符匹配所有
    path: '*',
    redirect: '/films'
  }
]

const router = new VueRouter({
  mode: 'history', // 地址就没有 # 号了
  routes
})


router.beforeEach((to, from, next) => {
  console.log(to.fullPath)
  console.log(to)
  if (to.meta.isMyrequired) {
    // 判断本地存储中是否有 token 字段
    if (localStorage.getItem('token')) {
      next()
    } else {
      next({
        path: '/login',
        query: { myredirect: to.fullPath }
      }) // 重定向到 login 页面 , 并记录从哪儿来的,以备登录成功后再跳转回去。
    }
  } else {
    next()
  }
})
export default router

当用户在电影页面时。访客可以点击正在热映和预告电影。这里使用了嵌套路由,也可说是二级路由。因为访客不离开电影页面,只是页面内的两个组件切换。

  {
    path: '/films',
    component: Films,
    // 二级路由(嵌套路由)
    children: [
      {
        path: '/films/hotplaying',
        component: Hotplaying
      },
      {
        path: '/films/comingsoon',
        component: Comingsoon
      },
      {
        path: '/films',
        redirect: '/films/hotplaying'
      }
    ]
  },

最后一个路由 是始终保持电影页面默认显示 正在热映 组件 采用了重定向。

 用了重定向的地方还有这里,当访客在地址栏后面输入无效内容时都会默认跳转到 这个电影界面。

  {
    // 路由重定向  * 通配符匹配所有
    path: '*',
    redirect: '/films'
  }

当访客点击某一个 正在热映的电影时,需要加载这个电影的详情,这里使用动态路由。每一个电影用不通的id 标识。

 {
    name: 'mydetil', // 命名路由
    path: '/detail/:myid', // 动态二级路由
    component: Detail
  },

当未登录的用户点击“我的”或者查看订单时需要对其跳转进行拦截至登录页 Login.vue。登陆后才能跳转。这里采用的时全局拦截格式如下。

// 全局拦截
/*
router.beforeEach((to,from,next)=>{
  console.log(to)
  if(某几个需要授权的路由){
    if(授权通过){
      next()
    }else{
      next('/login') // 重定向到 login 页面
    }
  }else{
    next()
  }
})
*/

同时我们希望 能够记住用户在跳转登录前的页面,用户登录以后再跳转回来页面。

 

这里我们模拟用 token 字段来验证用户有无登录

  if (to.meta.isMyrequired) {
    // 判断本地存储中是否有 token 字段
    if (localStorage.getItem('token')) {
      next()

在需要拦截的 路径我们加了 meta 用来标记

  {
    path: '/center',
    component: () => import('@/views/Center'),
    meta: {
      isMyrequired: true
    }

这是路由懒加载的引入方式,因为当组件很多时,提高首页加载的速度,访客点击了其他的内容再去加载相应的 js 文件。

component: () => import('@/views/Center')

接下来来到 login.vue 

<template>
    <div>
        登录页面
        <button @click="handlogin()">登录</button>
    </div>
</template>
<script>
export default {
  methods: {
    handlogin () {
      setTimeout(() => {
        localStorage.setItem('token', '后端返回的 token 字段')
        // this.$router.back() // 返回
        // 1. 获取 query 字段
        console.log(this.$route.query.myredirect)
        // 2. 跳转到跳转之前的界面。
        this.$router.push(this.$route.query.myredirect)
      }, 2000)
    }
  }
}
</script>

 表示跳转到登录页面之前我是在 这个路径下 的页面。query 是我们上面拦截路由时所传的一个对象。

films.vue 这里用的声明式导航的另一种写法。因为导航栏不多可以手写。

<template>
    <div>
        <div class="lun">轮播</div>
        <ul>
            <router-link to="/films/hotplaying" tag="li" active-class="play_class">正在热映</router-link>
            <router-link to="/films/comingsoon" tag="li" active-class="play_class">即将上映</router-link>
        </ul>
        <router-view></router-view>
    </div>
</template>

detail.vue 当点击正在热映列表电影的时候就会显示页面创建完成。获得id和路径 .页面创建完成了

<template>
    <div>
        detail
    </div>
</template>
<script>

export default {
  created () {
    console.log('created', this.$route)
  },
  mounted () {
    console.log('mounted', this.$route.params.myid)
  }
}
</script>

 

hotplaing.vue 制造一个一一些假数据。这里介绍了点击跳转的三种方式。最后我们用了通过命名路由跳转方式。

<template>
    <div>
        hotplaying
        <ul>
            <li v-for="items in datalist" :key="items" @click="handetail(items)">{{items}}</li>
        </ul>
    </div>
</template>
<script>
export default {
  data () {
    return {
      datalist: ['1111', '2222', '3333']
    }
  },
  methods: {
    handetail (id) {
      // 编程式导航
      //   location.href = '#/detail'
      // 通过路劲跳转
      // this.$router.push(`/detail/${id}`)
      // 通过命名路由跳转
      this.$router.push({
        name: 'mydetil',
        params: {
          myid: id
        }
      })
    }
  }
}
</script>

因为要考虑不同设备大小的兼容性,这里使用 rem 等比例缩放。

在index.html 文件中设置等比例缩放,这里 750 *16 都是可以更改的。不过 px to rem 默认是16 ,如果更改也需要同步更改 px to rem 配置。

<script>
      // font-size 计算
      document.documentElement.style.fontSize=document.documentElement.clientWidth/750*16+'px'
    </script>

以及 px to rem 小工具来帮助我们实现 px 到 rem 的自动转换,px to rem 默认的是 16px

未完待续

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
# 页面和多页面开发及应用 # 页面: - 什么是页面页面是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入。 - 跳转仅加载一次,用于PC和公务网站 - 页眉 -> 第一页,第二页, 第三页 -> 脚本 # 页面技术: -AngularJS是一个全面的客户端侧框架。其模板基于双向UI数据绑定。数据绑定是一种自动方法,在模型改变时更新视图,以及在视图改变时更新模型。其HTML模板在浏览器中编译。编译步骤创建纯HTML,浏览器将其重新渲染到实时视图。该步骤会在随后的页面浏览中重复。在传统的服务器端HTML编程中,控制器和模型等概念在服务器进程中进行交互以产生新的HTML视图。在AngularJS框架中,控制器和模型状态在客户端的浏览器中维护,从而使生成新页面不依赖与服务器的交互。 -Ember.js是基于模型-视图-控制器(MVC)软件架构模型的客户端侧JavaScript Web应用程序框架。它允许开发人员在一个框架中通过常用的习惯用语和最佳实践来创建可伸缩的页面应用程序。该框架提供丰富的对象模型、声明性双向数据绑定、计算属性,Handlebars.js提供的自动更新模板,以及一个路由器管理应用程序状态。 -Meteor.js是一个专门为页应用设计的全栈(客户端-服务器)JavaScript框架。它具有比Angular、Ember或ReactJS更简的数据绑定特性且使用--Distributed Data Protocol和一个发布/订阅来自动将数据更改传播到客户端,无需开发人员编写任何同步代码。全栈反应确保从数据库到模板的所有层都可以在必要时自动更新。诸如服务器端渲染等生态系统包则解决搜索引擎优化(SEO)等问题。 -Aurelia是一个适用于移动设备、桌面和网页的JavaScript客户端框架。它类似AngularJS,但更新、更符合标准,并采用模块化举措。Aurelia使用下一代ECMAScript编写。 -Vue.js(通常称为Vue)是一个用于构建用户界面的开源渐进式JavaScript框架。 -React(通常写为React.js或ReactJS)是一个构建用户界面的JavaScript函式庫。它由Facebook、Instagram和个人开发者以及企业社区维护。React最大的优势是易于使用——基本上任何熟悉HTML的开发人员都可以创建React应用程序。另一个所称的优势是可能使用相同的技术堆栈来同时创建Web与移动应用程序。有多家公司使用React和Redux库来让开发人员创建复杂但可扩展的Web应用程序。 -Fulcro是一个全栈库,它采用Netflix的Falcor,Facebook的Relay和Om Next对反应性,功能性,数据驱动软件进行改编的数据驱动原则。 -页面做seo(搜索引擎优化): -根据部分进行优化为每个关键字创建一个<div>或<section>或每个关键字并为其分配一个适当的ID,该页面上的内部链接将链接至ID。 -优化页面速度对于页网站SEO来说至关重要。 - 做了seo 以后,页面还是页面 # 页面优点: -减小服务器压力。 如果不用页面(spa),如果每次切换页面的时候,都向服务器发送一个请求,服务器返回一个html文件;但是如果使用了页面,在切换时,不需要请求服务器,只要通过本地的js来切换即可。并且服务器端就不需要配置路由,完全做到了前后端分离 -增强用户体验,增加app的使用流畅性。 使用spa之后,页面在切换的时候非常流畅,完全没有那种不断刷新的感觉,而是非常快的就有了响应,因为js运行速度很快,所以js在做本地路由的时候,就会非常快。 -页应用没有页面之间的切换,就不会出现“白屏现象”,也不会出现假死并有“闪烁”现象。 -页应用相对服务器压力小,服务器只用出数据就可以,不用管展示逻辑和页面合成,吞吐能力会提高几倍。 -良好的前后端分离。后端不再负责模板渲染、输出页面工作,后端API通用化,即同一套后端程序代码,不用修改就可以用于Web界面、手机、平板等多种客户端。 -页面缺点: -首次加载耗时比较多。 解决办法:可以采用基于HTTP Chunk 的首屏数据渐进式预加载方案,该方案总体减少了页应用1.2s的首屏呈现时间。首屏数据渐进式预加载的优化思路也得到了体现: 优化首屏数据加载节点的速度。 预先加载首屏数据,使得多个串行节点并行化。 -SEO问题,不利于百度,360等搜索引擎收录。 解决办法:可以采用prerender服务,它拿到请求够,直接在服务端的一个js engine里,运行这个HTML(就像浏览器做的那样),直到内容动态填完之后,再广播一个事件告诉phantomjs“内容已经好了,可以返回给爬虫了”,这样爬虫就拿到了一份完整的HTML,就和在浏览器里渲染完的一样。目前流行的框架都有对应的服务器渲染框架 -如有造成Css命名冲突。 解决办法:我们可以使用Sass、LESS和Stylus等CSS预处理器,在一定程度上可以解决该问题。 -前进、后退、地址栏、书签等,都需要程序进行管理,页面的复杂度很高,需要一定的技能水平和开发成本高。 # 多页面: -什么是多页面:每一次页面跳转的时候,后台服务器都会给返回一个新的html文档,这种类型的网站也就是多页网站,也叫做多页应用 - 跳转需要刷新所有资源,用于app 或 客户端 - 页眉 -> 第一页 -> 脚本,页眉 -> 第二页 -> 脚本,页眉 -> 第三页 -> 脚本 -多页面优点:给用户提供一个完美的视觉方向,重点是没有很多的菜,简洁明了的SEO管理。由于可以针对每页一个关键字优化应用程序 -多页面缺点:后端和移动客户端不能同时使用,前端和后端开发紧密结合。开发变得相当复杂。开发人员需要为客户端和服务器端使用框架。这导致应用程序开发时间更长。 # 区别: -组成:页面由一个外壳页面和多个页面组成, 多页面由多个完整页面组成 -css(资源公用):页面为共用,只需要外壳部分加载,多页面则不共用,每个页面独加载 -刷新方式:页面页面局部更改或刷新,多页面整页刷新 -url模式:页面 a.com/#/pageone 多页面 a.com/pageone.html -用户体验:页面页面切换快,用户体验良好,多页面加载缓慢,流畅度不够,用户体验较差 -转场动画:页面容易实现,多页面无法实现 -数据传递:页面容易,多页面需要依赖url传参,或cookie,localSrorage等 -搜索引擎优化:页面需要独方案,实现较为困难,不利于SEO搜索,可利用与SSR优化,多页面实现方法容易 -适用范围:页面高要求的体验度,追求页面的流畅,多页面追求高度支持搜索引擎的应用 -开发成本:页面较高,需要专业的框架,多页面较低,但页面重复代码较多 -维护成本:页面相对容易,双页面相对复杂

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值