vue组件-----路由系统

  • 能够说出单页面概念和优缺点
  • 能够掌握vue-router路由系统
  • 能够掌握声明式导航和编程式导航
  • 能够掌握路由嵌套和守卫

一.Vue路由简介和基础使用

1.生活中的路由

目标:设备和ip的映射关系

2.nodejs路由

目标:接口和服务的映射关系

3.前端路由

目标:路径和组件的映射关系

1. 路由是什么呢? 路由是一种映射关系

2. Vue中的路由是什么?路径和组件的映射关系

4.为何使用路由

目标:了解为何使用路由

  1. 具体使用示例: 网易云音乐 https://music.163.com/
  2. 单页面应用(SPA): 所有功能在一个html页面上实现
  3. 前端路由作用: 实现业务场景切换

优点:

  • 整体不刷新页面,用户体验更好
  • 数据传递容易, 开发效率高

缺点:

  • 开发成本高(需要学习专门知识)
  • 首次加载会比较慢一点。不利于seo

1. 什么是单页面应用? 所有的业务都在一个页面编写, 只有一个html

2. 单页面应用好处? 开发效率高, 用户体验好

3. 单页面如何切换场景?依赖路由切换显示

 5.vue-router

目标: vue-router本质是一个第三方包

官网: https://router.vuejs.org/zh/

vue-router模块包

  • 它和 Vue.js 深度集成
  • 可以定义 - 视图表(映射规则)
  • 模块化的
  • 提供2个内置全局组件
  • 声明式导航自动激活的 CSS class 的链接

6.组件分类

目标: .vue文件分2类, 一个是页面组件, 一个是复用组件

.vue文件本质无区别, 方便大家学习和理解, 总结的一个经验

src/views文件夹

  • 页面组件 - 页面展示 - 配合路由用

src/components文件夹

  • 复用组件 - 展示数据/常用于复用

1. 为何把.vue文件分类? 方便理解和使用

2. 页面组件用在哪里? 配合路由, 切换页面

3. 复用组件用在哪里?页面组件, 重复渲染结构一样的标签

7.vue-router模块

步骤

  • 1. 下载vue-router模块到当前工程
  • 如果遇到版本不兼容的问题,可以手动编辑项目的 package.json 文件,将 vue-router 的依赖版本指定为与您当前项目中安装的 vue 版本兼容的版本。在重新npm install一下
  • 2. 在main.js中引入VueRouter函数
  • import VueRouter from 'vue-router'
  • 3. 添加到Vue.use()身上 – 注册全局RouterLink和RouterView组件
  • 4. 创建路由规则数组 – 路径和组件名对应关系
  • 5. 用规则生成路由对象
  • 6. 把路由对象注入到new Vue实例中
  • 7. 用router-view作为挂载点, 切换不同的路由页面

main.js

import Vue from 'vue'
import App from './App.vue'
import FindPage from '@/views/Find' // @是src的绝对地址
import MyProfile from '@/views/My'
import PartDetail from '@/views/Part'
// 目标: vue-router基础使用
// 1. 下载vue-router  (yarn add vue-router)
// 2. 引入
import VueRouter from 'vue-router'

// 3. 注册全局组件
Vue.use(VueRouter)

// 4. 规则数组
const routes = [
  {
    path: "/",
    redirect: "/find"
  },
  {
    path: "/find",
    name: "Find",
    component: FindPage,
  },
  {
    path: "/my",
    name: "My",
    component: MyProfile
  },
  {
    path: "/part",
    name: "Part",
    component: PartDetail
  }
]

// 5. 生成路由对象
const router = new VueRouter({
  routes,
  // mode: "history" // 默认不写是"hash"
})

Vue.config.productionTip = false

// 6. 路由对象注入到vue实例中, this可以访问$route和$router
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

 App.vue

<template>
  <div>
    <div class="footer_wrap">
      <a href="#/find">发现音乐</a>
      <a href="#/my">我的音乐</a>
      <a href="#/part">朋友</a>
    </div>
    <div class="top">
      <!-- 7.设置挂载点-当url的hash值路径切换,显示规则里对应的组件到这 -->
      <router-view></router-view>
    </div>
  </div>
</template>

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

<style scoped>
.footer_wrap {
  position: fixed;
  left: 0;
  top: 0;
  display: flex;
  width: 100%;
  text-align: center;
  background-color: #333;
  color: #ccc;
}

.footer_wrap a {
  flex: 1;
  text-decoration: none;
  padding: 20px 0;
  line-height: 20px;
  background-color: #333;
  color: #ccc;
  border: 1px solid black;
}

.footer_wrap a:hover {
  background-color: #555;
}

.top {
  padding-top: 62px;
}</style>

 Find.vue

<template>
    <div>
        <p>推荐</p>
        <p>排行榜</p>
        <p>歌单</p>
    </div>
</template>

<script>
    export default {
        name: 'FindPage',
    }
</script>

<style>

</style>

My.vue

<template>
    <div>
        <p>我的收藏</p>
        <p>我的历史记录</p>
    </div>
</template>

<script>
    export default {
        name: 'MyProfile',
    }
</script>

<style>

</style>

 Part.vue

<template>
    <div>
        <p>关注明星</p>
        <p>发现精彩</p>
        <p>寻找伙伴</p>
        <p>加入我们</p>
    </div>
</template>

<script>
    export default {
        name: 'PartDetail',
    }
</script>

<style>

</style>

注意: 一切都要以url上hash值为准

1. vue-router本质是什么?第三方包, 下载后集成到vue项目中

2. vue-router如何使用? 下包/引入/注册/规则/路由对象/注入/挂载点

3. 规则如何生效?切换url上hash值, 开始匹配规则, 对应组件展示到 router-view位置

 声明式导航

1.声明式导航

目标:可用组件router-link来替代a标签

  • 1. vue-router提供了一个全局组件 router-link
  • 2. router-link实质上最终会渲染成a链接 to属性等价于提供 href属性(to无需#)
  • 3. router-link提供了声明式导航高亮的功能(自带类名)

App.vue

<template>
    <div>
        <div class="footer_wrap">
            <router-link to="#/find">发现音乐</router-link>
            <router-link to="#/my">我的音乐</router-link>
            <router-link to="#/part">朋友</router-link>
        </div>
        <div class="top">

            <router-view></router-view>
        </div>
    </div>
</template>

<script>
// 目标:声明式导航 - 基础使用
// 本质:vue-router提供的全局组件"router-link"替代a标签
// 1,router-link 替代a标签
// 2.to属性  替代herf属性
// 好处:router-link 自带高亮的类名(激活时类名)
// 3.对激活的类名做出样式的编写
export default {};
</script>

<style scoped>
.footer_wrap {
    position: fixed;
    left: 0;
    top: 0;
    display: flex;
    width: 100%;
    text-align: center;
    background-color: #333;
    color: #ccc;
}

.footer_wrap a {
    flex: 1;
    text-decoration: none;
    padding: 20px 0;
    line-height: 20px;
    background-color: #333;
    color: #ccc;
    border: 1px solid black;
}

.footer_wrap a:hover {
    background-color: #555;
}

.top {
    padding-top: 62px;
}
.footer_wrap .router-link-active{
  color: white;
  background: black;
}
</style>

1. router-link是什么? VueRouter在全局注册的组件, 本质就是a标签

2. router-link怎么用? 当标签使用, 必须传入to属性, 指定路由路径值

3. router-link好处?自带激活时的类名, 可以做高亮

2.声明式导航 - 跳转传参  

目标:在跳转路由时, 可以给路由对应的组件内传值

在router-link上的to属性传值, 语法格式如下

  • /path?参数名=值
  • /path/值 – 需要路由对象提前配置 path: “/path/参数名”

对应页面组件接收传递过来的值

  • $route.query.参数名
  • $route.params.参数名

第一种:

第二种:

App.vue

<template>
    <div>
        <div class="footer_wrap">
            <router-link>发现音乐</router-link>
            <router-link>我的音乐</router-link>
            <router-link to="/part?name=小传">朋友-小传</router-link>
            <router-link to="/part/小智">朋友-小智</router-link>
        </div>
        <div class="top">
            <router-view></router-view>
        </div>
    </div>
</template>

<script>
// 目标: 声明式导航 - 传值
// 方式1:
// to="/path?参数名=值"
// 接收: $route.query.参数名

// 方式2:
// (1): 路由规则path上 定义 /path/:参数名
// (2): to="/path/值"
// 接收: $route.params.参数名
export default {};
</script>

<style scoped>
.footer_wrap {
    position: fixed;
    left: 0;
    top: 0;
    display: flex;
    width: 100%;
    text-align: center;
    background-color: #333;
    color: #ccc;
}

.footer_wrap a {
    flex: 1;
    text-decoration: none;
    padding: 20px 0;
    line-height: 20px;
    background-color: #333;
    color: #ccc;
    border: 1px solid black;
}

.footer_wrap a:hover {
    background-color: #555;
}

.top {
    padding-top: 62px;
}

/*激活时样式 */
.footer_wrap .router-link-active {
    color: white;
    background: black;
}</style>

Part.vue

<template>
    <div>
        <p>关注明星</p>
        <p>发现精彩</p>
        <p>寻找伙伴</p>
        <p>加入我们</p>
        <p>人名: {
   
   { $route.query.name }} 
        -- 
        {
   
   { $route.params.username }}
    </p>
    </div>
</template>

<script>
    export default {
        name: 'PartDetail',
    }
</script>

<style>

</style>

1. 声明式导航跳转时, 如何传值给路由页面? to="/path?参数名=值" to=“/path/值” (需在路由规则里配置/path/:参数名)

2. 如何接收路由传值? $route.query.参数名      $route.params.参数名

重定向和模式

1.路由 - 重定向

目标:匹配path后, 强制跳转path路径

  • 网页打开url默认hash值是/路径
  • redirect是设置要重定向到哪个路由路径

当我们打开页面路由得时候,页面没有任何显示,当使用重定向到/find得界面时,打开项目弹出得就是/find界面的内容 

main.js

import Vue from 'vue'
import App from './App.vue'
import FindPage from '@/views/Find' // @是src的绝对地址
import MyProfile from '@/views/My'
import PartDetail from '@/views/Part'
// 目标: vue-router基础使用
// 1. 下载vue-router  (yarn add vue-router)
// 2. 引入
import VueRouter from 'vue-router'

// 3. 注册全局组件
Vue.use(VueRouter)

// 4. 规则数组
const routes = [
  {
    path:"/",   //默认hash值路径
    redirect:"/find" //重定向到/find
    // 浏览器url中#后得路径被改变后/find-重新匹配规则
  },
  {
    path: "/find",
    name: "Find",
    component: FindPage,
  },
  {
    path: "/my",
    name: "My",
    component: MyProfile
  },
  {
    path: "/part",
    name: "Part",
    component: PartDetail
  }
]

// 5. 生成路由对象
const router = new VueRouter({
  routes,
  // mode: "history" // 默认不写是"hash"
})

Vue.config.productionTip = false

// 6. 路由对象注入到vue实例中, this可以访问$route和$router
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

1. 如何监测默认路由? 规则里定义path: '/'

2. 如何重定向路由路径? redirect配置项, 值为要强制切换的路由路径

2.路由 - 404

目标:找不到路径给个提示页面

路由最后, path匹配*(任意路径) – 前面不匹配就命中最后这个

NotFound.vue

<template>
    <img src="../assets/404.png" alt="">
</template>

<script>
export default {

}
</script>

<style scoped>
img {
    width: 100%;
}
</style>

main.js

import Vue from 'vue'
import App from './App.vue'
import Find from '@/views/Find' // @是src的绝对地址
import My from '@/views/My'
import Part from '@/views/Part'
import NotFound from '@/views/NotFound'

// 目标: vue-router基础使用
// 1. 下载vue-router  (yarn add vue-router)
// 2. 引入
import VueRouter from 'vue-router'
// 3. 注册全局组件
Vue.use(VueRouter)
// 4. 规则数组
const routes = [
  {
    path: "/", // 默认hash值路径
    redirect: "/find" // 重定向到/find
    // 浏览器url中#后的路径被改变成/find-重新匹配规则
  },
  {
    path: "/find",
    name: "Find",
    component: Find
  },
  {
    path: "/my",
    name: "My",
    component: My
  },
  {
    path: "/part",
    name: "Part",
    component: Part
  },
  {
    path: "/part/:username", // 有:的路径代表要接收具体的值
    component: Part
  },
  // 404在最后(规则是从前往后逐个比较path)
  {
    path: "*",
    component: NotFound
  }
]
// 5. 生成路由对象
const router = new VueRouter({
  routes,// routes是固定key(传入规则数组)
  // mode: "history" // 默认不写是"hash"
})


Vue.config.productionTip = false

// 6. 路由对象注入到vue实例中, this可以访问$route和$router
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

3.路由 - 模式设置

目标:修改路由在地址栏的模式

  • hash路由例如: http://localhost:8080/#/home
  • history路由例如: http://localhost:8080/home (以后上线需要服务器端支持, 否则找的是文件夹)

main.js

import Vue from 'vue'
import App from './App.vue'
import Find from '@/views/Find' // @是src的绝对地址
import My from '@/views/My'
import Part from '@/views/Part'
import NotFound from '@/views/NotFound'

// 目标: vue-router基础使用
// 1. 下载vue-router  (yarn add vue-router)
// 2. 引入
import VueRouter from 'vue-router'
// 3. 注册全局组件
Vue.use(VueRouter)
// 4. 规则数组
const routes = [
  {
    path: "/", // 默认hash值路径
    redirect: "/find" // 重定向到/find
    // 浏览器url中#后的路径被改变成/find-重新匹配规则
  },
  {
    path: "/find",
    name: "Find",
    component: Find
  },
  {
    path: "/my",
    name: "My",
    component: My
  },
  {
    path: "/part",
    name: "Part",
    component: Part
  },
  {
    path: "/part/:username", // 有:的路径代表要接收具体的值
    component: Part
  },
  // 404在最后(规则是从前往后逐个比较path)
  {
    path: "*",
    component: NotFound
  }
]
// 5. 生成路由对象
const router = new VueRouter({
  routes,// routes是固定key(传入规则数组)
  mode: "history" // 默认不写是"hash"
})


Vue.config.productionTip = false

// 6. 路由对象注入到vue实例中, this可以访问$route和$router
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

 

编程式导航

1.编程式导航 - 基础使用

目标:用JS代码来进行跳转

语法: path或者name任选一个

App.vue

<template>
    <div>
        <div class="footer_wrap">
            <span @click="btn('/find', 'Find')">发现音乐</span>
            <span @click="btn('/my', 'My')">我的音乐</span>
            <span @click="btn('/part', 'Part')">朋友</span>
        </div>
        <div class="top">
            <router-view></router-view>
        </div>
    </div>
</template>

<script>
// 目标: 编程式导航 - js方式跳转路由
// 语法:
// this.$router.push({path: "路由路径"})
// this.$router.push({name: "路由名"})
// 注意:
// 虽然用name跳转, 但是url的hash值还是切换path路径值
// 场景:
// 方便修改: name路由名(在页面上看不见随便定义)
// path可以在url的hash值看到(尽量符合组内规范)
export default {
    methods: {
        btn(targetPath, targetName) {
            // 方式1: path跳转
            this.$router.push({
                // path: targetPath,
                name: targetName
            })
        }
    }
};
</script>

<style scoped>
.footer_wrap {
    position: fixed;
    left: 0;
    top: 0;
    display: flex;
    width: 100%;
    text-align: center;
    background-color: #333;
    color: #ccc;
}

.footer_wrap span {
    flex: 1;
    text-decoration: none;
    padding: 20px 0;
    line-height: 20px;
    background-color: #333;
    color: #ccc;
    border: 1px solid black;
}

.footer_wrap span:hover {
    background-color: #555;
}

.top {
    padding-top: 62px;
}

/*激活时样式 */
.footer_wrap .router-link-active {
    color: white;
    background: black;
}</style>

 

JS如何切换路由路径? this.$router.push()配置path/name

要和路由规则数组里对应

2.编程式导航 - 跳转传参  

目标:JS跳转路由,传参

语法:query或者params任选一个

注意:使用path会忽略params

<template>
    <div>
        <div class="footer_wrap">
            <span @click="btn('/find', 'Find')">发现音乐</span>
            <span @click="btn('/my', 'My')">我的音乐</span>
            <span @click="oneBtn">朋友-小传</span>
            <span @click="twoBtn">朋友-小智</span>
        </div>
        <div class="top">
            <router-view></router-view>
        </div>
    </div>
</template>

<script>
// 目标: 编程式导航 - 跳转路由传参
// 方式1:
// params => $route.params.参数名
// 方式2:
// query => $route.query.参数名
// 重要: path会自动忽略params
// 推荐: name+query方式传参
// 注意: 如果当前url上"hash值和?参数"与你要跳转到的"hash值和?参数"一致, 爆出冗余导航的问题, 不会跳转路由
export default {
    methods: {
        btn(targetPath, targetName) {
            // 方式1: path跳转
            this.$router.push({
                // path: targetPath,
                name: targetName
            })
        },
        oneBtn() {
            this.$router.push({
                name: 'Part',
                params: {
                    username: '小传'
                }
            })
        },
        twoBtn() {
            this.$router.push({
                name: 'Part',
                query: {
                    name: '小智'
                }
            })
        }
    }
};
</script>

<style scoped>
.footer_wrap {
    position: fixed;
    left: 0;
    top: 0;
    display: flex;
    width: 100%;
    text-align: center;
    background-color: #333;
    color: #ccc;
}

.footer_wrap span {
    flex: 1;
    text-decoration: none;
    padding: 20px 0;
    line-height: 20px;
    background-color: #333;
    color: #ccc;
    border: 1px solid black;
}

.footer_wrap span:hover {
    background-color: #555;
}

.top {
    padding-top: 62px;
}

/*激活时样式 */
.footer_wrap .router-link-active {
    color: white;
    background: black;
}</style>

嵌套和守卫

1.路由 - 路由嵌套

目标:在现有的一级路由下, 再嵌套二级路由

二级路由示例-网易云音乐-发现音乐下 https://music.163.com/

1. 创建需要用的所有组件

  • src/views/Find.vue -- 发现音乐页
  • src/views/My.vue -- 我的音乐页
  • src/views/Second/Recommend.vue -- 发现音乐页 / 推荐页面
  • src/views/Second/Ranking.vue -- 发现音乐页 / 排行榜页面
  • src/views/Second/SongList.vue -- 发现音乐页 / 歌单页面

2. main.js– 继续配置2级路由

  • 一级路由path从/开始定义
  • 二级路由往后path直接写名字, 无需/开头
  • 嵌套路由在上级路由的children数组里编写路由信息对象

3. 说明:

  • App.vue的router-view负责发现音乐和我的音乐页面, 切换
  • Find.vue的的router-view负责发现音乐下的, 三个页面, 切换

main.js

import Vue from 'vue'
import App from './App.vue'
import Find from '@/views/Find' // @是src的绝对地址
import My from '@/views/My'
import Part from '@/views/Part'
import NotFound from '@/views/NotFound'
import Recommend from '@/views/Second/Recommend'
import Ranking from '@/views/Second/Ranking'
import SongList from '@/views/Second/SongList'
// 目标: vue-router基础使用
// 1. 下载vue-router  (yarn add vue-router)
// 2. 引入
import VueRouter from 'vue-router'
// 3. 注册全局组件
Vue.use(VueRouter)
// 4. 规则数组
const routes = [
  {
    path: "/", // 默认hash值路径
    redirect: "/find" // 重定向到/find
    // 浏览器url中#后的路径被改变成/find-重新匹配规则
  },
  {
    path: "/find",
    name: "Find",
    component: Find,
    children: [
      {
        path: "recommend",
        component: Recommend
      },
      {
        path: "ranking",
        component: Ranking
      },
      {
        path: "songlist",
        component: SongList
      }
    ]
  },
  {
    path: "/my",
    name: "My",
    component: My
  },
  {
    path: "/part",
    name: "Part",
    component: Part
  },
  {
    path: "/part/:username", // 有:的路径代表要接收具体的值
    component: Part
  },
  // 404在最后(规则是从前往后逐个比较path)
  {
    path: "*",
    component: NotFound
  }
]
// 5. 生成路由对象
const router = new VueRouter({
  routes,// routes是固定key(传入规则数组)
  // mode: "history" // 默认不写是"hash"
})


Vue.config.productionTip = false

// 6. 路由对象注入到vue实例中, this可以访问$route和$router
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

 App.vue

<template>
    <div>
        <div class="footer_wrap">
            <span @click="btn('/find', 'Find')">发现音乐</span>
            <span @click="btn('/my', 'My')">我的音乐</span>
            <span @click="oneBtn">朋友-小传</span>
            <span @click="twoBtn">朋友-小智</span>
        </div>
        <div class="top">
            <router-view></router-view>
        </div>
    </div>
</template>

<script>
// 目标: 编程式导航 - 跳转路由传参
// 方式1:
// params => $route.params.参数名
// 方式2:
// query => $route.query.参数名
// 重要: path会自动忽略params
// 推荐: name+query方式传参
// 注意: 如果当前url上"hash值和?参数"与你要跳转到的"hash值和?参数"一致, 爆出冗余导航的问题, 不会跳转路由
export default {
    methods: {
        btn(targetPath, targetName) {
            // 方式1: path跳转
            this.$router.push({
                // path: targetPath,
                name: targetName
            })
        },
        oneBtn() {
            this.$router.push({
                name: 'Part',
                params: {
                    username: '小传'
                }
            })
        },
        twoBtn() {
            this.$router.push({
                name: 'Part',
                query: {
                    name: '小智'
                }
            })
        }
    }
};
</script>

<style scoped>
.footer_wrap {
    position: fixed;
    left: 0;
    top: 0;
    display: flex;
    width: 100%;
    text-align: center;
    background-color: #333;
    color: #ccc;
}

.footer_wrap span {
    flex: 1;
    text-decoration: none;
    padding: 20px 0;
    line-height: 20px;
    background-color: #333;
    color: #ccc;
    border: 1px solid black;
}

.footer_wrap span:hover {
    background-color: #555;
}

.top {
    padding-top: 62px;
}

/*激活时样式 */
.footer_wrap .router-link-active {
    color: white;
    background: black;
}</style>

1. 二级路由如何配置? 创建需要的二级页面组件 路由规则里children中配置二级路由规则对象 一级页面中设置router-view显示二级路由页面

2. 二级路由注意什么? 二级路由path一般不写根路径/ 跳转时路径要从/开始写全

2.声明式导航 – 类名区别 

观察路由嵌套导航的样式

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

<template>
    <div>
        <div class="footer_wrap">
            <router-link to="/find">发现音乐</router-link>
            <router-link to="/my">我的音乐</router-link>
            <router-link to="/part">朋友</router-link>
        </div>
        <div class="top">
            <router-view></router-view>
        </div>
    </div>
</template>

<script>
// 目标: 声明式导航 - 激活类名区别
// 1. url上hash值(#/home/recommend) 包含 导航的href值(#/home) - 当前a就有 "router-link-active"  (模糊)
// 2. url上hash值(#/home/recommend) 等于 导航的href值(#/home/recommend) - 当前a就有"router-link-exact-active" (精确)
export default {};
</script>

<style scoped>
.footer_wrap {
    position: fixed;
    left: 0;
    top: 0;
    display: flex;
    width: 100%;
    text-align: center;
    background-color: #333;
    color: #ccc;
}

.footer_wrap a {
    flex: 1;
    text-decoration: none;
    padding: 20px 0;
    line-height: 20px;
    background-color: #333;
    color: #ccc;
    border: 1px solid black;
}

.footer_wrap a:hover {
    background-color: #555;
}

.top {
    padding-top: 62px;
}

/*激活时样式 */
.footer_wrap .router-link-active {
    color: white;
    background: black;
}</style>

3.全局前置守卫

目标:路由跳转之前, 会触发一个函数

例如: 登陆状态去页面, 未登录弹窗提示

语法: router.beforeEach((to, from, next) =>{})

  • 一定调next(), 才会跳转下一页

main.js

import Vue from 'vue'
import App from './App.vue'
import Find from '@/views/Find' // @是src的绝对地址
import My from '@/views/My'
import Part from '@/views/Part'
import NotFound from '@/views/NotFound'
import Recommend from '@/views/Second/Recommend'
import Ranking from '@/views/Second/Ranking'
import SongList from '@/views/Second/SongList'
// 目标: vue-router基础使用
// 1. 下载vue-router  (yarn add vue-router)
// 2. 引入
import VueRouter from 'vue-router'
// 3. 注册全局组件
Vue.use(VueRouter)
// 4. 规则数组
const routes = [
  {
    path: "/", // 默认hash值路径
    redirect: "/find" // 重定向到/find
    // 浏览器url中#后的路径被改变成/find-重新匹配规则
  },
  {
    path: "/find",
    name: "Find",
    component: Find,
    children: [
      {
        path: "recommend",
        component: Recommend
      },
      {
        path: "ranking",
        component: Ranking
      },
      {
        path: "songlist",
        component: SongList
      }
    ]
  },
  {
    path: "/my",
    name: "My",
    component: My
  },
  {
    path: "/part",
    name: "Part",
    component: Part
  },
  {
    path: "/part/:username", // 有:的路径代表要接收具体的值
    component: Part
  },
  // 404在最后(规则是从前往后逐个比较path)
  {
    path: "*",
    component: NotFound
  }
]
// 5. 生成路由对象
const router = new VueRouter({
  routes,// routes是固定key(传入规则数组)
  // mode: "history" // 默认不写是"hash"
})

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

// 例子: 判断用户是否登录, 是否决定去"我的音乐"/my
const isLogin = true; // 登录状态(未登录)
router.beforeEach((to, from, next) => {
  if (to.path === "/my" && isLogin === false) {
    alert("请登录")
    next(false) // 阻止路由跳转
  } else {
    next() // 正常放行
  }
})

Vue.config.productionTip = false

// 6. 路由对象注入到vue实例中, this可以访问$route和$router
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

什么是路由守卫? 路由在真正跳转前, 会执行一次beforeEach函数, next调用则跳转, 也可以强制修改要跳转的路由

Vant组件库

1.Vant组件库

目标: Vant是一个轻量、可靠的移动端 Vue 组件库, 开箱即用

Vant组件库: https://vant-contrib.gitee.io/vant/#/zh-CN/

特点

  • 提供 60 多个高质量组件,覆盖移动端各类场景
  • 性能极佳,组件平均体积不到 1kb
  • 完善的中英文文档和示例
  • 支持 Vue 2 & Vue 3
  • 支持按需引入和主题定制

2.全部引入

目标:看官网文档, 下载, 引入Vant组件库

先创建一个vue组件项目

然后下载vant组件

main.js

import Vue from 'vue'
import App from './App.vue'
// 方式3: 引入所有vant组件
import Vant from 'vant';
import 'vant/lib/index.css'; // 引入vant所有组件样式
Vue.use(Vant); // 全局注册vant所有组件


Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

App.vue

<template>
  <div>
    <van-button type="primary" @click="btn">主要按钮</van-button>
    <van-button type="info">信息按钮</van-button>
    <van-button type="default">默认按钮</van-button>
    <van-button type="warning">警告按钮</van-button>
    <van-button type="danger">危险按钮</van-button>
  </div>
</template>

<script>

export default {
 }
  data() {
    return {

    };
  },
  methods: {
};
</script>

<style></style>

如何引入Vant组件库? 组件库是一个包, 先下载 按照文档指引, 在main.js全局注册 到某.vue内直接使用Vant组件名

3.按需引入

目标:手动引入使用的某个组件

1. 手动单独引入, 快速开始: https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart  

Vant组件库如何手动按需引入使用? import 从vant库里引出某个组件 import 单独引出样式 在当前页面注册此组件名即可

4.自动按需引入

目标:依赖插件自动按需引入

自动按需引入, 快速开始: https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart

 

如何自动按需引入Vant组件库? webpack依赖babel-plugin-import的插件

把import按需引入方式, 自动转成只引入某个组件方式

5.弹出框使用

目标:完成效果

 弹出框地址: https://vant-contrib.gitee.io/vant/#/zh-CN/dialog

main.js

import Vue from 'vue'
import App from './App.vue'
// 方式3: 引入所有vant组件
// import Vant from 'vant';
// import 'vant/lib/index.css'; // 引入vant所有组件样式
// Vue.use(Vant); // 全局注册vant所有组件

// 方式1: 全局 - 自动按需引入vant组件
// (1): 下载 babel-plugin-import
// (2): babel.config.js - 添加官网说的配置 (一定要重启服务器)
// (3): main.js 按需引入某个组件, Vue.use全局注册 - 某个.vue文件中直接使用vant组件
import { Button, Form, Field } from 'vant';
Vue.use(Button) // Button组件全局注册, 真正注册的组件名VanButton
Vue.use(Form);
Vue.use(Field);

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

 App.vue

<template>
  <div>
    <van-button type="primary" @click="btn">主要按钮</van-button>
    <van-button type="info">信息按钮</van-button>
    <van-button type="default">默认按钮</van-button>
    <van-button type="warning">警告按钮</van-button>
    <van-button type="danger">危险按钮</van-button>

    <hr />

    <van-form @submit="onSubmit">
      <van-field v-model="username" name="用户名" label="用户名" placeholder="用户名"
        :rules="[{ required: true, message: '请填写用户名' }]" />
      <van-field v-model="password" type="password" name="密码" label="密码" placeholder="密码"
        :rules="[{ required: true, message: '请填写密码' }]" />
      <div style="margin: 16px">
        <van-button round block type="info" native-type="submit">提交</van-button>
      </div>
    </van-form>
  </div>
</template>

<script>
// 方式2: 手动 按需引入
// import Button from 'vant/lib/button'; // button组件
// import 'vant/lib/button/style'; // button样式

// 目标: 使用弹出框
// 1. 找到vant文档
// 2. 引入
// 3. 在恰当时机, 调用此函数 (还可以用组件的用法)
import { Dialog } from "vant";
export default {
  // components: { // 手动注册组件名
  //   // VanButton: Button
  //   // 等价的
  //   [Button.name]: Button
  // }
  data() {
    return {
      username: '',
      password: '',
    };
  },
  methods: {
    onSubmit(values) { // 表单提交事件, values收集表单里的值
      console.log('submit', values);
    },
    btn() {
      Dialog({ message: "提示", showCancelButton: true }); // 调用执行时, 页面就会出弹出框
    },
  },
};
</script>

<style></style>

6.表单使用

目标: 使用Vant组件里的表单组件

具体 – 看表单组件地址: https://vant-contrib.gitee.io/vant/#/zh-CN/form

main.js

import Vue from 'vue'
import App from './App.vue'
// 方式3: 引入所有vant组件
// import Vant from 'vant';
// import 'vant/lib/index.css'; // 引入vant所有组件样式
// Vue.use(Vant); // 全局注册vant所有组件

// 方式1: 全局 - 自动按需引入vant组件
// (1): 下载 babel-plugin-import
// (2): babel.config.js - 添加官网说的配置 (一定要重启服务器)
// (3): main.js 按需引入某个组件, Vue.use全局注册 - 某个.vue文件中直接使用vant组件
import { Button, Form, Field } from 'vant';
Vue.use(Button) // Button组件全局注册, 真正注册的组件名VanButton
Vue.use(Form);
Vue.use(Field);

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

 App.vue

<template>
  <div>
    <van-button type="primary" @click="btn">主要按钮</van-button>
    <van-button type="info">信息按钮</van-button>
    <van-button type="default">默认按钮</van-button>
    <van-button type="warning">警告按钮</van-button>
    <van-button type="danger">危险按钮</van-button>

    <hr />

    <van-form @submit="onSubmit">
      <van-field v-model="username" name="用户名" label="用户名" placeholder="用户名"
        :rules="[{ required: true, message: '请填写用户名' }]" />
      <van-field v-model="password" type="password" name="密码" label="密码" placeholder="密码"
        :rules="[{ required: true, message: '请填写密码' }]" />
      <div style="margin: 16px">
        <van-button round block type="info" native-type="submit">提交</van-button>
      </div>
    </van-form>
  </div>
</template>

<script>
// 方式2: 手动 按需引入
// import Button from 'vant/lib/button'; // button组件
// import 'vant/lib/button/style'; // button样式

// 目标: 使用弹出框
// 1. 找到vant文档
// 2. 引入
// 3. 在恰当时机, 调用此函数 (还可以用组件的用法)
import { Dialog } from "vant";
export default {
  // components: { // 手动注册组件名
  //   // VanButton: Button
  //   // 等价的
  //   [Button.name]: Button
  // }
  data() {
    return {
      username: '',
      password: '',
    };
  },
  methods: {
    onSubmit(values) { // 表单提交事件, values收集表单里的值
      console.log('submit', values);
    },
    btn() {
      Dialog({ message: "提示", showCancelButton: true }); // 调用执行时, 页面就会出弹出框
    },
  },
};
</script>

<style></style>

猜你喜欢

转载自blog.csdn.net/2201_76041915/article/details/139064060