vue基础

vue2基础第一天

1.vue指令

实质上就是特殊的 html 标签属性, 特点: v- 开头

插值表达式

在dom标签中, 直接插入内容,又叫声明式渲染/文本插值

语法: {{ 表达式 }}

dom中插值表达式赋值, vue的变量必须在data里声明

2.vue指令-v-bind

动态给标签属性设置vue变量的值

语法:v-bind:属性名="vue变量"

简写::属性名="vue变量"

<!-- vue指令-v-bind属性动态赋值 -->
<a v-bind:href="url">我是a标签</a>
<img :src="imgSrc">
3.vue指令-v-on
给标签绑定事件
  • 语法
    • v-on:事件名="要执行的==少量代码=="
    • v-on:事件名="methods中的函数"
    • v-on:事件名="methods中的函数(实参)"
  • 简写: @事件名="methods中的函数"
v-on事件对象

语法:

  • 无传参, 通过形参直接接收
  • 传参, 通过$event指代事件对象传给事件处理函数
<template>
  <div>
    <a @click="one" href="http://www.baidu.com">阻止百度</a>
    <hr>
    <a @click="two(10, $event)" href="http://www.baidu.com">阻止去百度</a>
  </div>
</template>

<script>
export default {
  methods: {
    one(e){
      e.preventDefault()
    },
    two(num, e){
      e.preventDefault()
    }
  }
}
</script>
v-on修饰符

语法:

  • @事件名.修饰符="methods里函数"
    • .stop - 阻止事件冒泡
    • .prevent - 阻止默认行为
    • .once - 程序运行期间, 只触发一次事件处理函数
<template>
  <div @click="fatherFn">
    <!-- vue对事件进行了修饰符设置, 在事件后面.修饰符名即可使用更多的功能 -->
    <button @click.stop="btn">.stop阻止事件冒泡</button>
    <a href="http://www.baidu.com" @click.prevent="btn">.prevent阻止默认行为</a>
    <button @click.once="btn">.once程序运行期间, 只触发一次事件处理函数</button>
  </div>
</template>

<script>
export default {
  methods: {
    fatherFn(){
      console.log("father被触发");
    },
    btn(){
      console.log(1);
    }
  }
}
</script>
v-on按键修饰符

给键盘事件, 添加修饰符

语法:

  • @keyup.enter - 监测回车按键
  • @keyup.esc - 监测返回按键
<template>
  <div>
    <input type="text" @keydown.enter="enterFn">
    <hr>
    <input type="text" @keydown.esc="escFn">
  </div>
</template>

<script>
export default {
 methods: {
   enterFn(){
     console.log("enter回车按键了");
   },
   escFn(){
     console.log("esc按键了");
   }
 }
}
</script>
4.vue指令 v-model

把表单标签value属性和vue数据变量, 双向绑定到一起

语法: v-model="vue数据变量"

双向数据绑定

  • 数据变化 -> 视图自动同步
  • 视图变化 -> 数据自动同步
绑定在普通表单标签上:
<input type="text" v-model="username" />
绑定在下拉菜单select上:
<select v-model="from">
    <option value="北京市">北京</option>
    <option value="南京市">南京</option>
    <option value="天津市">天津</option>
</select>
绑定在单选框上:
<input type="radio" value="男" name="sex" v-model="gender">男
<input type="radio" value="女" name="sex" v-model="gender">女
绑定在文本域上:
<textarea v-model="intro"></textarea>
绑定在复选框上:

特别注意: v-model, 在input[checkbox]的多选框状态
变量为非数组, 则绑定的是checked的属性(true/false) - 常用于: 单个绑定使用
变量为数组, 则绑定的是他们的value属性里的值 - 常用于: 收集勾选了哪些值

<input type="checkbox" v-model="hobby" value="抽烟">抽烟
<input type="checkbox" v-model="hobby" value="喝酒">喝酒
<input type="checkbox" v-model="hobby" value="写代码">写代码
v-model修饰符

v-model.修饰符="vue数据变量"

  • .number 以parseFloat转成数字类型
  • .trim 去除首尾空白字符
  • .lazy 在change时触发而非inupt时
<template>
    <div>
        <div>
            <span>年龄:</span>
            <input type="text" v-model.number="age">
        </div>
        <div>
            <span>人生格言:</span>
            <input type="text" v-model.trim="motto">
        </div>
        <div>
            <span>自我介绍:</span>
            <textarea v-model.lazy="intro"></textarea>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                age: "",
                motto: "",
                intro: ""
            }
        }
    }
</script>
5.vue指令 v-text和v-html

更新DOM对象的innerText/innerHTML

  • 语法:
    • v-text="vue数据变量"
    • v-html="vue数据变量"
  • 注意: 会覆盖插值表达式
<template>
  <div>
    <p v-text="str"></p>
    <p v-html="str"></p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      str: "<span>我是一个span标签</span>"
    }
  }
}
</script>
6.vue指令 v-show和v-if

控制标签的隐藏或出现

  • 语法:
    • v-show="vue变量"
    • v-if="vue变量"
  • 原理
    • v-show 用的display:none隐藏 (频繁切换使用)
    • v-if 直接从DOM树上移除
  • 高级
    • v-else使用
<template>
  <div>
    <h1 v-show="isOk">v-show的盒子</h1>
    <h1 v-if="isOk">v-if的盒子</h1>

    <div>
      <p v-if="age > 18">我成年了</p>
      <p v-else>还得多吃饭</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isOk: true,
      age: 15
    }
  }
}
</script>
7.vue指令-v-for

循环生成结构命令

  • 口诀: 让谁循环生成, v-for就写谁身上

  • 语法

    • v-for="(值, 索引) in 目标结构"
    • v-for="值 in 目标结构"
  • 目标结构:

    • 可以遍历数组 / 对象 / 数字 / 字符串 (可遍历结构)
  • 注意:

    v-for的临时变量名不能用到v-for范围外

    避免v-for和v-if在一起使用: Vue 处理指令时,v-for 比 v-if 具有更高的优先级, 虽然用起来也没报错好使, 但是性能不高, 如果你有5个元素被v-for循环, v-if也会分别执行5次.

vue2基础第二天

1.v-for更新

数组改变, v-for会监测到并更新页面

数组不改变, v-for不会更新页面

vue2通过数组下标修改数组的值的方式 虽然修改了数组 不会触发v-for 不会同步修改视图

vue2 解决方案:this.$set 更新数据的时候,还会更新视图

语法: this.$set(要设置的原数据, 数组下标, 新的值)

vue3没有这个bug

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

这些方法不会触发v-for更新

  • slice()
  • filter()
  • concat()
2.动态class

语法:

  • :class="{类名: 布尔值}"
3.动态style

此种方式生成的是标签的行内样式

语法

  • :style="{css属性: 值}"
4.计算属性computed
基本概念

一个数据, 依赖另外一些数据计算而来的结果

注意:1.计算属性和data属性都是变量-不能重名

    2.计算属性会根据依赖项的变化而自动重新计算

    3.计算属性定义的时候是一个函数,使用到的其实是个变量

    4.计算属性变量的值就是return返回的数据

简便写法:

computed: {
    "计算属性名" () {
        return "值"
    }
}
计算属性的缓存

计算属性相比函数,具有缓存优势,计算属性对应函数执行后, 会把return值缓存起来

依赖项不变, 多次调用都是从缓存取值,依赖项值变化, 函数会"自动"重新执行并缓存新的值

比普通方法性能更高

计算属性-完整写法

计算属性也是变量,如果要给计算属性赋值 , 需要使用完整写法

computed: {
    "属性名": {
        set(值){
            
        },
        get() {
            return "值"
        }
    }
}
5.侦听器-watch
简单侦听

可以侦听data/computed属性值改变

简便写法: 只能侦听到简单数据类型的变化

watch: {
    "被侦听的属性名" (newVal, oldVal){
        // newVal: 当前最新值
        // oldVal: 上一刻值
        // 变量名对应值改变这里自动触发
    }
}
深度侦听

侦听复杂类型, 和立即执行侦听

watch: {
    "要侦听的属性名": {
        // 变量名对应值改变这里自动触发
        immediate: true, // 立即侦听(网页打开handler执行一次)
        deep: true, // 深度侦听复杂类型内变化 对象里面层的值改变
        handler (newVal, oldVal) {
            
        }
    }
}

vue2基础第三天

1.组件

组件是可复用的 Vue 实例,封装的思想,把页面上 可重用的部分 封装为 组件,从而方便项目的 开发 和 维护

组件内template只能有一个根标签

组件内data必须是一个函数, 独立作用域

2.组件全局注册

全局入口在main.js, 在new Vue之上注册

//引入组件
import Pannel from './components/Pannel'
//全局注册组件
Vue.component("PannelG", Pannel)
//使用组件
<PannelG></PannelG>
<PannelG/>
<pannel-g></pannel-g>
3.组件局部注册
import 组件对象 from 'vue文件路径'

export default {
    components: {
        "组件名": 组件对象
    }
}
4.父子组件通讯
父组件向子组件传值
<Product title="好贵的北京烤鸭" price="290" :intro="str"></Product>

export default {
  data(){
    return {
      str: "好贵啊, 快来啊, 好吃"
    }
  },
}
子组件接收数据
export default {
  props: ['title', 'price', 'intro']
}
单向数据流

在vue中需要遵循单向数据流原则

单向数据流:从父到子的单向数据流动

1. 父组件的数据发生了改变,子组件会自动跟着变
2. 子组件不能直接修改父组件传递过来的props  props是只读的

==父组件传给子组件的是一个对象,子组件修改对象的属性,是不会报错的,对象是引用类型, 互相更新==

子通过自定义事件通知父修改数据

子: this.$emit("自定义事件名", 传值) - 通知父执行父methods里函数代码

父:@自定义事件名="父methods函数"

vue2基础第四天

1.生命周期钩子函数

Vue 框架内置函数,随着组件的生命周期阶段,自动执行

4大阶段8个方法

初始化 beforeCreate created

挂载 beforeMount mounted

更新 beforeUpdate updated

销毁 beforeDestroy destroyed

初始化阶段

beforeCreate--此时拿不到data函数和methods中的数据

created--data和methods已初始化,此时可以拿到data函数和methods中的数据,应用场景:网络请求,注册全局事件

挂载阶段

beforeMount--此时拿不到真实dom元素

mounted--可以拿到真实dom元素

更新阶段

data函数里有数据改变才执行的钩子函数,data数据改变重复执行beforeUpdateupdated钩子函数

beforeUpdate--data里数据更新之前, DOM更新之前执行

updated--data数据更新之后,且虚拟dom重新渲染并打补丁到真实dom之后执行的钩子函数

销毁阶段

当$destroy()被调用 – 比如组件DOM被移除(例v-if)执行销毁钩子函数

beforeDestroy--dom元素或组件销毁前执行 场景: 移除全局事件, 移除当前组件, 计时器, 定时器, eventBus移除事件$off方法

destroyed--dom元素或组件销毁后执行

2.$refs-获取DOM和vue实例
获取dom元素

获取dom元素时,webapi获取方式和this.$refs获取方式获取到同一个对象

<h1 id="h" ref="myH">我是一个孤独可怜又能吃的h1</h1>

export default {
  mounted() {
    console.log(document.getElementById("h")); // h1
    console.log(this.$refs.myH); // h1
  },
};
获取组件对象

目标是组件时,webapi获取方式获取到dom元素,this.$refs获取到vue实例

this.$refs可以拿到组件 甚至可以修改组件内部的数据,但是一般不会这么做 这样做会造成后期维护困难 一般只会拿到组件调用组件的方法

3.$nextTick使用

Vue更新DOM异步的,点击count++, 马上通过"原生DOM"拿标签内容, 无法拿到新值

解决: this.$nextTick()

过程: DOM更新完会挨个触发$nextTick里的函数体

this.$nextTick(() => {
    console.log(this.$refs.myP.innerHTML); 
})

扩展: await取代回调函数 $nextTick()原地返回Promise对象

this.$nextTick(() => {                      await this.$nextTick()
    this.$refs.myInp.focus()  ===>          this.$refs.myInp.focus()
})
4.组件name属性使用

可以用组件的name属性值, 来注册组件名字

我们封装的组件-可以自己定义name属性组件名-让使用者有个统一的前缀风格

components/Com.vue

<template>
  <div>
      <p>我是一个Com组件</p>
  </div>
</template>

<script>
export default {
    name: "ComNameHaHa" // 可以定义组件自己的名字
}
</script>

App.vue - 注册和使用

<template>
  <div>
    <ComNameHaHa></ComNameHaHa>
  </div>
</template>
<script>
import Com from './components/Com'
export default {
  components: {
    [Com.name]: Com 
    // "ComNameHaHa": Com
  }
}
</script>

拓展: [这里还可以放表达式]

const obj={

}

等价于====>obj={ ab:1}

vue2基础第五天

1.动态组件component

vue内置component组件, 配合is属性, 设置要显示的组件名字

挂载点: <component :is="变量"></component>

组件切换会导致组件被频繁销毁和重新创建, 性能不高

2.组件缓存keep-alive

使用Vue内置的keep-alive组件, 可以让包裹的组件保存在内存中不被销毁

<div style="border: 1px solid red;">
    <!-- Vue内置keep-alive组件, 把包起来的组件缓存起来 -->
    <keep-alive>
        <component :is="comName"></component>
    </keep-alive>
</div>

总结:keep-alive可以提高组件的性能, 内部包裹的标签不会被销毁和重新创建, 触发激活和非激活的生命周期方法

补充生命周期钩子方法:

activated - 激活时触发

deactivated - 失去激活状态触发

3.组件插槽slot

组件内用<slot></slot>占位

使用组件时<Son></Son>夹着的地方, 传入标签替换slot

Son.vue

<template>
  <div class="box">
    <!-- 坑位 -->
    <slot>
      <section>子组件默认内容</section>
    </slot>
  </div>
</template>

<script>
export default {};
</script>

App.vue

<template>
  <div>
    <Son>
      <h3>你好儿子</h3>
      <a href="#">链接</a>
    </Son>
  </div>
</template>

<script>
import Son from './components/Son.vue'
export default {
  components: { Son },
}
</script>

<style></style>

插槽默认内容---<slot>夹着内容默认显示内容, 如果不给插槽slot传东西, 则使用<slot>夹着的内容在原地显示

4.具名插槽

当一个组件内有2处以上需要外部传入标签的地方

slotname属性起插槽名, 使用组件时, template配合v-slot:插槽名传入具体标签

Son.vue

<template>
  <div class="box">
    <slot name="title">
      <h2>我是子组件标题</h2>
    </slot>
    <!-- 坑位 -->
    <slot name="content">
      <section>子组件默认内容</section>
    </slot>
  </div>
</template>

<script>
export default {};
</script>

<style scoped>
.box {
  border: 1px solid #000;
  margin: 20px;
}
</style>

App.vue

<template>
  <div>
    <Son>
      <template v-slot:title>
        <h3>你好儿子</h3>
      </template>
      
      <template v-slot:content>
        <a href="#">链接</a>
      </template>
    </Son>
  </div>
</template>

<script>
import Son from './components/Son.vue'
export default {
  components: { Son },
}
</script>

v-slot:可以简化成#使用

v-bind可以省略成: v-on:可以省略成@ v-slot:可以简化成#

5.作用域插槽

子组件里值, 在给插槽赋值时在父组件环境下使用

1.子组件, 在slot上绑定自定义属性和子组件内的值

2.使用组件,用template配合v-slot="自定义变量名"

3.自定义变量会收集slot身上属性和值形成对象

Pannle.vue

<template>
  <div class="box">
    <!-- 作用域插槽可以看做:子传父 -->
    <slot :row="defaultObj"></slot>
  </div>
</template>

<script>
export default {
  data() {
    return {
      defaultObj: {
        defaultOne: '无名氏',
        defaultTwo: '小传同学',
      },
    }
  },
}
</script>

<style scoped>
.box {
  border: 1px solid #000;
  margin: 20px;
  padding: 20px;
}
</style>

App.vue

<template>
  <div>
    <!-- 
        作用域插槽的使用
          1、子组件,<slot :属性名="值"></slot> 传值
          2、父组件,通过 v-slot="变量名" 接收
        
        PS:作用域插槽相当于是插槽的子传父。
    -->
    <Pannle>
      <!-- 父组件接收:v-slot="变量名"  -->
      <template v-slot="scope">
        <h2>{{ scope }}</h2>
        <h3>{{ scope.row.defaultTwo }}</h3>
      </template>
    </Pannle>
  </div>
</template>

<script>
import Pannle from './components/Pannle.vue'
export default {
  components: {
    Pannle,
  },
}
</script>

6.自定义指令

你需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令

自定义指令作用:可以获取标签,扩展功能

自定义指令全局注册

在main.js用 Vue.directive()方法来进行注册, 然后项目中所有.vue文件里都可以直接用自定义指令

Vue.directive('color', {
  // 挂载时触发 只触发一次 相当于mounted钩子函数
  inserted(el) {
    console.log(el);
  }
});
自定义指令局部注册

只能在当前组件.vue文件中使用的自定义指令

使用指令:v-指令名称

<template>
  <div id="app">
    <!-- 自定义指令 -->
    <input type="text" autofocus v-abc />
    <h2 v-color="'red'">我是大标题</h2>
  </div>
</template>

<script>
export default {
  data() {
    return {};
  },
  methods: {},
  // 自定义指令局部注册
  directives: {
    abc: {
      // 挂载到页面后触发, 相当于mounted钩子函数
      // el表示使用指令时的标签
      inserted(el) {
        console.log(el);
      },
    },
  },
};
</script>
自定义指令-传值

定义自定义指令时定义接收参数

binding为使用自定义指令时传进来的对象

// 全局注册自定义指令-传值
Vue.directive('color', {
  // 挂载时触发 只触发一次 相当于mounted钩子函数
  inserted(el, binding) {
    el.style.color = binding.value;
  },
  // 每次更新后触发 相当于updated钩子函数
  update(el, binding) {
    el.style.color = binding.value;

  }
});

使用自定义指令时传递参数

<template>
  <div>
    <!-- 使用指令时传值:v-指令名称="变量" -->
    <!-- 使用指令时传值:v-指令名称="'字符串'" -->
    <h2 v-color="'red'">我是二标题-什么颜色呢?</h2>

    <h3 v-color="myColor">我是三标题-什么颜色呢?</h3>

    <button @click="myColor = 'green'">改颜色变量</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      myColor: "pink",
    };
  },
};
</script>

vue2基础第六天

1.路由
前端中定义

路径和组件的映射关系或接口和服务的映射关系

作用

实现单页面应用(SPA): 所有功能在一个html页面上实现

实现业务场景切换

路由的优点

整体不刷新页面,用户体验更好

数据传递容易, 开发效率高

路由的缺点

开发成本高(需要学习专门知识)

首次加载会比较慢一点,不利于seo

2.vue-router

定义:vue官方提供的路由系统功能模块包

作用:在Vue项目中集成路由

vue-router提供2个内置全局组件 router-link router-view

注意:vue-router@4不兼容vue2

vue2项目中要下载vue-router@3

3.vue-router使用步骤

在main.js中配置

1.安装

yarn add vue-router@3

2.导入路由

import VueRouter from 'vue-router'

3.使用路由插件

// 在vue中,使用使用vue的插件,都需要调用Vue.use()
Vue.use(VueRouter)

4.1导入组件

import Find from '@/views/Find.vue';
import My from '@/views/My.vue';
import Part from '@/views/Part.vue';
import NotFound from '@/views/NotFound.vue';

4.2创建路由规则数组

const routes = [
  {
    // 默认页面重定向为Find页
    path: '/',
    redirect: '/find'
  },
  {
    path: "/find",
    component: Find,
    // 嵌套路由:二级路由
    children: [
      // main.js中二级路由路径书写无需 / 开头
      // path为空表示默认打开的页面
      {
        path: '',
        // 重定向
        redirect: 'recommend'
      },
      {
        path: 'recommend',
        component: Recommend
      },
      {
        path: 'ranking',
        component: Ranking
      },
      {
        path: 'songlist',
        component: SongList
      }
    ]
  },
  {
    path: "/my",
    name: 'mypage',
    component: My
  },
  {
    path: "/part/:id",
    component: Part
  },
  // 404页面
  {
    path: '*',
    component: NotFound
  }
];

5.创建路由对象 - 传入规则

const router = new VueRouter({
    routes,
    //默认hash模式
    //history模式url地址栏上没有#号
    mode: 'history' //设置history模式,路由上线需要服务器端支持, 否则找的是文件夹
})

6.关联到vue实例

new Vue({
  router
})

7.使用路由

使用路由页面components换成router-view

使用router-view挂载点显示切换的路由

<router-view></router-view>
4.声明式导航
基本使用

用全局组件router-link来替代a标签

router-link配合to, 实现点击切换路由

router-link实质上最终会渲染成a链接 to属性等价于提供 href属性

router-link提供了声明式导航高亮的功能(router-link-exact-active router-link-active)

router-link自带的2个类名

router-link-exact-active (精确匹配) url中hash值路径, 与href属性值完全相同, 设置此类名

router-link-active (模糊匹配) url中hash值, 包含href属性值这个路径, 设置此类名

<template>
  <div id="app">
    <ul>
      <!-- 声明式导航 -->
      <!-- 声明式导航也可以传对象 此时to前要绑定: -->
      <!-- <li><router-link to="/find">发现页</router-link></li> -->
      <li><router-link :to="{ path: '/find' }">发现页</router-link></li>
      <li><router-link to="/my?id=123">我的主页</router-link></li>
      <li><router-link to="/part/456">我的分页</router-link></li>
    </ul>
    <!-- 路由挂载点 -->
    <router-view></router-view>
  </div>
</template>

<script>
export default {};
</script>

<style scoped lang=less>
.router-link-exact-active {
  color: aqua;
}
</style>
声明式导航传参

方案1: 传值---to="/path?参数名=值"

        接收---`$route.query`

方案2: 传值---to="/path/值"(需要在路由规则数组中配置 /path/:参数名)

        接收---`$route.params`

两种方案二选一即可,选择哪种看团队习惯

拓展: 声明式导航也可以传对象 此时to前面要绑定:

<router-link :to="{ path: '/find'}">发现页</router-link>
等价于
<router-link to="/find">发现页</router-link>
5.vue路由 - 重定向

定义:匹配path后, 强制切换到目标path上

网页打开url默认hash值是/路径

redirect是设置要重定向到哪个路由路径

强制重定向后, 还会重新来数组里匹配一次规则

//网页默认打开, 匹配路由"/", 强制切换到"/find"上
const routes = [
  {
    path: "/", // 默认hash值路径
    redirect: "/find" // 重定向到/find
    // 浏览器url中#后的路径被改变成/find-重新匹配数组规则
  }
]
6.404页面

如果路由hash值, 没有和数组里规则匹配,默认给一个404页面

放在路由规则数组最后, path匹配*(任意路径) – 前面不匹配就命中最后这个, 显示对应组件页面

7.编程式导航

用JS代码来进行跳转,大多数情况使用声明式导航,当需要在导航前判断是就要使用编程式导航

基础使用
<template>
  <div id="app">
    <!-- 编程式导航 -->
    <button @click="btnFn">编程式导航</button>
    <!-- 路由挂载点 -->
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  methods: {
    btnFn() {
      // 方式1 使用 name
      // 方式1需要在路由数组里, 给路由起名字
      this.$router.push("Find");
      // 方式2 使用 path
      this.$router.push("/find");
    },
  },
};
</script>
跳转传参

方式1: query方式传参 搭配path 接收参数用 $route.query

方式2: params方式传参 搭配name 接收参数用 $route.params

注意: vue2固有的bug 编程式导航跳转相同的页面 会报错

<template>
  <div id="app">
    <!-- 编程式导航 -->
    <button @click="btnFn">编程式导航</button>
    <!-- 路由挂载点 -->
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  methods: {
    btnFn() {       
      // 进阶使用:传对象的形式,适用于参数较多的情况

      // name 和path选其中一个就好
      //传参 params搭配name传参
      //格外注意: 使用path会自动忽略params
      this.$router.push({
         
        /*name: "part",
        params: {
          id: 123,
          aaa: "rose",
          bbb: "flower",
        }, */

        path: "/my",
        query: {
          id: 1234444,
          aaa: "aaa",
          bbb: "15dsaaf",
        },
      });
    },
  },
};
</script>

<style scoped lang=less>
.router-link-exact-active {
  color: aqua;
}
</style>
8.路由嵌套
规则

main.js继续配置2级路由

一级路由path从/开始定义

二级路由往后path直接写名字, 无需/开头

嵌套路由在上级路由的children数组里编写路由信息对象

main.js展示
// 导入二级路由
import Recommend from '@/views/second/Recommend';
import SongList from '@/views/second/SongList';
import Ranking from '@/views/second/Ranking';

const routes = [
  {
    // 默认页面重定向为Find页
    path: '/',
    redirect: '/find'
  },
  {
    path: "/find",
    component: Find,
    // 嵌套路由:二级路由
    children: [
      // main.js中二级路由路径书写无需 / 开头
      // path为空表示默认打开的页面
      {
        path: '',
        // 重定向
        redirect: 'recommend'
      },
      {
        path: 'recommend',
        component: Recommend
      },
      {
        path: 'ranking',
        component: Ranking
      },
      {
        path: 'songlist',
        component: SongList
      }
    ]
  },
  // 404页面
  {
    path: '*',
    component: NotFound
  }
];
二级路由展示

跳转时, 要去的路由路径从一级开始写,需要/开头

<template>
  <div>
    find页面
    <!-- 二级路由挂载点 -->
    <ul>
      <!-- 注意点:页面中 to 属性的每一级路径都需要写/开头  如:/一级/二级 / -->
      <li>
        <router-link to="/find/recommend">发现音乐页/ 推荐页面</router-link>
      </li>
      <li>
        <router-link to="/find/ranking">发现音乐页 / 排行榜页面</router-link>
      </li>
      <li>
        <router-link to="/find/songlist">发现音乐页 / 歌单页面</router-link>
      </li>
    </ul>
    <router-view></router-view>
  </div>
</template>

<script>
export default {};
</script>
<style scoped>
/* 精确匹配类名 */
.router-link-exact-active {
  color: red;
}
</style>
9.全局前置守卫

路由跳转之前, 先执行一次前置守卫函数, 判断是否可以正常跳转

在main.js中得到路由对象router之后书写代码

// 语法: router.beforeEach((to, from, next)=>{//路由跳转"之前"先执行这里, 决定是否跳转})
// 参数1: 要跳转到的路由 (路由对象信息)    目标
// 参数2: 从哪里跳转的路由 (路由对象信息)  来源
// 参数3: 函数体 - next()才会让路由正常的跳转切换, next(false)在原地停留, next("强制修改到另一个路由路径上")
// 注意: 如果不调用next, 页面留在原地

// 例子: 判断用户是否登录, 是否决定去"我的音乐"/my
const isLogin = false; // 登录状态(未登录)
router.beforeEach((to, from, next) => {
  if (to.path === "/my" && isLogin === false) {
    alert("请登录")
    next(false) // 阻止路由跳转
  } else {
    next() // 正常放行
  }
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 224,728评论 6 522
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,220评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 171,936评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,976评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,981评论 6 399
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,468评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,843评论 3 428
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,817评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,353评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,384评论 3 346
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,510评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,113评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,833评论 3 338
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,290评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,419评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,055评论 3 381
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,577评论 2 365

推荐阅读更多精彩内容