学习列表

初学Vue(一)-- Vue简略入门

初学vue(二)-- 条件渲染、修饰符、循环

初学vue(三)-- 生命周期、过滤器、监听属性、计算属性

初学vue(四)-- axios前后端交互、组件


单页面应用程序

  • SPA : Single Page Application 单页面应用程序
  • MPA : Multiple Page Application 多页面应用程序
  • 单页 web 利用

    就是只有一个 web 页面的利用,
    是加载单个 HTML 页面,
    并在用户与应用程序交互时, 动静更新该页面的 web 应用程序

  • 区别

    • 对于传统的多页面应用程序来说, 每次申请服务器返回的都是一个残缺的页面
    • 对于单页应用程序来说,

      只有第一次会加载页面,
      当前的每次申请,
      仅仅是获取必要的数据.而后,
      由页面中 js 解析获取的数据,
      展现在页面中

  • 单页面劣势 :

    1. 缩小了申请体积,放慢页面响应速度,升高了对服务器的压力
    2. 更好的用户体验,让用户在 web app 感触 native app 的晦涩, (部分刷新)
  • 单页面劣势 :

    1. 开发成本高 (须要学习路由)
    2. 不利于 SEO
  • 演示 : https://music.163.com/

介绍路由

  • 路由 : 是浏览器 URL 中的哈希值( # hash) 与 展现视图内容 之间的对应规定

    • 简略来说,路由就是一套映射规定(一对一的对应规定), 由开发人员制订规定.-
    • 当 URL 中的哈希值( # hash) 产生扭转后,路由会依据制订好的规定, 展现对应的视图内容
  • 为什么要学习路由?

    • 在 web App 中, 常常会呈现通过一个页面来展现和治理整个利用的性能.
    • SPA 往往是性能简单的利用,为了无效治理所有视图内容,前端路由 应运而生.
  • vue 中的路由 : 是 hashcomponent 的对应关系, 一个哈希值对应一个组件

一 : 路由的根本应用

筹备工作 (3个)

  • 装置 : npm i vue-router
  • 引入 :
<script src="./vue.js"></script>// 千万留神 :引入路由肯定要在引入vue之后,因为vue-router是基于vue工作的<script src="./node_modules/vue-router/dist/vue-router.js"></script>
  • 实例路由对象 + 挂载到vue上

    • 实例路由对象 : const router = new VueRouter()
    • 挂载到vue上 : new Vue({ router,data,methods })
    • 验证路由是否挂载胜利, 就看关上页面,最初面有没有个 #/

具体步骤 (4个)

  • 1.入口
  • 2.路由规定
  • 3.组件
  • 4.进口
# 1. 入口     // 形式1 : url地址为入口   调试开发用     输出url地址 扭转哈希值 `01-路由的根本应用.html#/one`         // 形式2 : 申明式导航 : router-link+to (见上面介绍)# 2. 路由规定// path : 路由门路// component : 未来要展现的路由组件routes: [    { path: '/one', component: One },     { path: '/two', component: Two }]# 3. 组件// 应用返回值的这个组件名称const One = Vue.component('one', {  template: ` <div> 子组件 one </div> `})# 4. 进口<!--  进口 组件要展现的中央--><router-view></router-view># 总结拿到入口哈希门路, 依据路由匹配规定,找到对应的组件,显示到对应的进口地位 

二 : 由应用注意事项

  • 入口

    • 最罕用的入口 是 申明式导航 router-link
<!-- router-link 组件最终渲染为 a标签, to属性转化为 a标签的href属性to 属性的值 , 实际上就是哈希值,未来要参加路由规定中进行与组件匹配  --><router-link to="/one">首页</router-link>
  • 组件
const One = {  template: `<div> 子组件 one </div> `}
  • 演示 : 多个组件匹配
<div id="app">  <!-- 1 路由入口:链接导航 -->  <router-link to="/one">One</router-link>  <router-link to="/two">Two</router-link>  <!-- 4 路由进口:用来展现匹配路由视图内容 -->  <router-view></router-view></div><!--  导入 vue.js --><script src="./vue.js"></script><!--  导入 路由文件 --><script src="./node_modules/vue-router/dist/vue-router.js"></script><script>  // 3 创立两个组件  const One ={    template: '<h1>这是 one 组件</h1>'  }  const Two =  {    template: '<h1>这是 two 组件</h1>'  }  // 0 创立路由对象  const router = new VueRouter({    // 2. 路由规定    routes: [      { path: '/one', component: One },      { path: '/two', component: Two }    ]  })  const vm = new Vue({    el: '#app',    //0. 不要遗记,将路由与vue实例关联到一起!    router  })</script>

三 : 入口导航菜单高亮解决

  • 点击导航 => 元素里增加了两个类
<a href="#/one" class="router-link-exact-active router-link-active">One</a><a href="#/two" class="">Two</a>
  • 批改形式1 : 间接批改类的款式
.router-link-exact-active,.router-link-active {  color: red;  font-size: 50px;}
  • 批改形式2 : 应用存在过的类款式 => 批改默认高亮类名
const router = new VueRouter({  routes: [],  // 批改默认高亮的a标签的类名  // red 是曾经存在过的  linkActiveClass: 'red'})

四: 路由配置

4.1 动静路由 => 详情列表

导入 : 列表三个手机都要点击进去详情页, 只须要一个组件,显示不同的数据即可
# 入口<router-link to="/detail/1">手机1</router-link><router-link to="/detail/2">手机2</router-link><router-link to="/detail/3">手机3</router-link><router-link to="/detail">手机4</router-link>  没有参数如何????# 规定routes: [  // 2 . 路由规定  { path: '/detail/:id?', component: Detail }]# 获取参数的三种形式const Detail =  {    template: `        // 形式1 : 组件中间接读取        <div> 显示详情页内容....{{ $route.params.id  }} </div>    `,    created() {        // 形式2 : js间接读取        // 打印只会打印一次,因为组件是复用的,每次进来钩子函数只会执行一次        console.log(this.$route.params.id)    },    // 形式3 : 监听路由的参数,为什么不须要深度监听,因为一个门路变动,就会对应一个对新的路由对象(地址变)    watch: {        $route(to, from) {            console.log(to.params.id)        }    }}

4.2 路由对象 - $route

  • 一个路由对象 (route object) 示意以后激活的路由的状态信息,蕴含了以后 URL 解析失去的信息
  • 一个哈希值门路 ==> 一个路由对象
  • $route.path

    • 类型: string
    • 字符串,对该当前路由的门路,总是解析为绝对路径,如 "/foo/bar"
    • # 前面?后面的内容
  • $route.params

    • 类型: Object
    • 一个 key/value 对象,蕴含了动静片段和全匹配片段,如果没有路由参数,就是一个空对象。
    • 一个 key/value 对象,蕴含了动静片段和全匹配片段,如果没有路由参数,就是一个空对象。
  • $route.query

    • 类型: Object
    • 参数对象
    • 一个 key/value 对象,示意 URL 查问参数。例如,对于门路 /foo?user=1,则有 $route.query.user == 1,如果没有查问参数,则是个空对象。
  • $route.hash

    • 类型: string

      以后路由的 hash 值 (带 #) ,如果没有 hash 值,则为空字符串。

  • $route.fullPath

    • 类型: string
    • 全门路
    • 实现解析后的 URL,蕴含查问参数和 hash 的残缺门路。
# 演示 : <router-link to="/detail/4?age=21#one">detail</router-link>{ path: '/detail/:id?', component: detail } 在组件内 created打印 this.$route> fullPath: "/detail/4?id=001#one"> hash : "#one"> params : {id:'4'}> query : {age : 21}> path : '/detail/4'

4.3 嵌套路由 => children

导入 : url测试 parent 和child, 想让child 在 parent 中显示
  • parent 的外部 增加 : <router-view> </router-view>
  • 规定里增加 children
  • /child 和 child 的区别

    • 如果是/child => 那么拜访就能够间接拜访#/child就能够拜访 子组件
    • 如果是child => 那么拜访就应该拜访#/parent/child才能够拜访子组件
const parent = {    template: `<p>parent  <router-view> </router-view> </p>`}const child = {    template: `<p>child</p>`}const router = new VueRouter({    routes: [        {            path: '/parent',            component: parent,            children: [                { path: '/child', component: child }            ]        }    ]})

4.4 命名路由

  • 有时候,通过一个名称来标识一个路由显得更不便一些,
  • 特地是在链接一个路由,或者是执行一些跳转的时候。 ===> 场景
  • 你能够在创立 Router 实例的时候,在 routes 配置中给某个路由设置名称。 ==> 如何命名
# 命名routes: [    {        path: '/parent',        name: 'parent',        component: parent    }]# 入口链接 + 跳转  (应用 path 和 name 的转换)<!-- 形式1 : url手动写 --><!-- 形式2 : 入口链接 申明式导航 --><router-link to="/parent">点击</router-link><router-link :to="{ name : 'parent' }">点击</router-link>  # 忘了 带 : 原始对象类型<!-- 形式3 : 编程式导航 --> fn() {     // this.$router.push('/parent')     this.$router.push({         name: 'parent'     }) }

4.5 命名视图

导入 : 有时候想同时 (同级) 展现多个视图,

需要 : 拜访 / 根目录 同时展现以下三个组件

  • 三个组件
const header = {    template: `<p>header  </p>`}const main = {    template: `<p>main  </p>`}const footer = {    template: `<p>footer  </p>`}
  • 规定
# 以前的那个形式只能显示三个 header# 演示之前的成果 routes: [    {        path: '/',        components: {            default: header,            m: main,            f: footer        }    }]
  • 进口
<router-view> </router-view><router-view name="m"> </router-view><router-view name="f"> </router-view>

4.6 重定向

redirect: '/header'redirect: { name: 'header' }redirect: to => {      // console.log(to)    return {        name: 'about'    }}

4.7 组件传参

  • 原始形式应用 $route获取
# 入口    <router-link to="/header/3">123</router-link># 规定routes: [    {        path: '/header/:id',        component: header,    }]# 获取参数const header = {    template: `<p>header  {{ $route.params.id }}  </p>`}
  • 布尔模式
# 入口    <router-link to="/header/3">123</router-link># 规定routes: [    {        path: '/header/:id',        component: header,        // 如果 props 被设置为 true,route.params 将会被设置为组件属性        props: true    }]# 获取参数const header = {    // 参数 id 当成参数    props: ['id'],    template: `<p>header   {{ id }} </p>`}
  • 对象模式
# 入口 <router-link to="/header">123</router-link># 规定 routes: [     {         path: '/header',         component: header,         props: { foo: '0000' }     } ]# 组件 const header = {        props: ['foo'],        template: `<p>header   {{ foo }} </p>` }
  • 函数模式
# 同对象模式一样# 区别是props值不一样 props: to => {     return { foo: '0000' } }
  • 留神 : 对象模式和函数模式参数 在props里,所以申明式导航那里就不要传参了

4.8嵌套路由

理论生存中的利用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动静门路也按某种构造对应嵌套的各层组件。

借助 vue-router,应用嵌套路由配置,就能够很简略地表白这种关系。

  • 单层路由
<div id="app">  <router-view></router-view></div>
const User = {  template: '<div>User {{ $route.params.id }}</div>'}const router = new VueRouter({  routes: [    { path: '/user/:id', component: User }  ]})

这里的 <router-view> 是最顶层的进口,渲染最高级路由匹配到的组件。同样地,一个被渲染组件同样能够蕴含本人的嵌套 <router-view>。例如,在 User 组件的模板增加一个 <router-view>

  • 嵌套路由

    • 模板配置
    const User = {  template: `    <div class="user">      <h2>User {{ $route.params.id }}</h2>      <router-view></router-view>    </div>  `}
  • 路由配置:要在嵌套的进口中渲染组件,须要在 VueRouter 的参数中应用 children 配置
const router = new VueRouter({  routes: [    { path: '/user/:id', component: User,      children: [        {          // 当 /user/:id/profile 匹配胜利,          // UserProfile 会被渲染在 User 的 <router-view> 中          path: 'profile',          component: UserProfile        },        {          // 当 /user/:id/posts 匹配胜利          // UserPosts 会被渲染在 User 的 <router-view> 中          path: 'posts',          component: UserPosts        }      ]    }  ]})

留神,以 / 结尾的嵌套门路会被当作根门路。 这让你充沛的应用嵌套组件而无须设置嵌套的门路。

五 : 路由进阶

5.1 元信息

  • 规定申明
 routes: [     {         path: '/header',         component: header,         meta: {            title: 'XXXX'         }     } ]
  • 获取
 created() {    document.title = this.$route.meta.title }
  • 作用 :
  • 在路由导航的时候,能够用作判断

5.2 编程式导航

const one = {    template: ` <div> <button @click="handleClick('back')">返回 上一页</button><button @click="handleClick('push')">跳转 two页</button><button @click="handleClick('replace')">替换 two页</button> </div>`,    methods: {        handleClick(type) {            if (type == 'back') {                // 返回                this.$router.back()            } else if (type == 'push') {                // 跳转 有历史记录                this.$router.push('/two')            } else {                // 替换 没有历史记录                this.$router.replace('/two')            }        }    }}const two = {    template: `<p>two </p>`}

5.3 导航守卫

router.beforeEach((to, from, next) => {    // 拜访 login    if (to.name == 'login') {        // 下一步        next()    } else {        // 进行跳转        next(false)        // 跳转到下一步        next({ name: 'login' }) 或者 应用门路  next('/login')    }})