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组件库

  • 1. 全部引入, 快速开始: https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart
  • 2. 下载Vant组件库到当前项目中
  • 3. 在main.js中全局导入所有组件,
  • 4. 使用按钮组件 – 作为示范的例子

先创建一个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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/655685.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

短视频内容创意方法有哪些?成都科成博通文化传媒公司

短视频内容创意方法有哪些&#xff1f; 随着移动互联网的迅猛发展&#xff0c;短视频平台已成为人们日常生活中不可或缺的一部分。短视频以其短平快的特点&#xff0c;迅速吸引了大量用户。然而&#xff0c;面对海量的短视频内容&#xff0c;如何让自己的作品脱颖而出&#xf…

【Linux】Linux的权限_2 + Linux环境基础开发工具_1

文章目录 三、权限3. Linux权限管理修改文件的拥有者和所属组 4. 文件的类型5. 权限掩码 四、Linux环境基础开发工具1. yumyum 工具的使用 未完待续 三、权限 3. Linux权限管理 修改文件的拥有者和所属组 在上一节我们讲到如何更改文件的访问权限&#xff0c;那我们需要更改…

二十九、openlayers官网示例DeclutterGroup解析——避免矢量图层的文字重叠

官网demo地址&#xff1a; Declutter Group 这篇说的是如何设置矢量图层上多数据点文字不重叠。 主要是属性declutter &#xff0c;用于处理矢量图层上重叠的标注和符号&#xff0c;为true时启用去重叠功能。所有矢量特征的标注和符号都会被处理以避免重叠。false则与之相反。…

提升(或降低)插入的内容的位置:\raisebox

\raisebox 是 LaTeX 中的一个命令&#xff0c;用于提升&#xff08;或降低&#xff09;插入的内容&#xff08;如文本、图像等&#xff09;的位置。该命令可以用于调整垂直位置&#xff0c;使内容相对于周围内容上下移动。 语法如下&#xff1a; \raisebox{<distance>}…

宝藏网站推荐-封面图片生成器

封面图片生成器&#xff1a;封面图生成器 | 太空编程 (spacexcode.com)[https://spacexcode.com/coverview] 由来 最近爱上了写文案&#xff0c;在网上冲浪的时候发现一个宝藏网站。Spacecode&#xff0c;一个大神维护的个人网站&#xff0c;含有前端知识库、个人博客及他做…

轻松拿捏C语言——自定义类型之【结构体】

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f389;创作不易&#xff0c;请多多支持&#x1f389; &#x1f308;感谢大家的阅读、点赞、收藏和关注&#x1f495; &#x1f339;如有问题&#xff0c;欢迎指正 1. 结构体类型的…

攻击同学网络,让同学断网

技术介绍&#xff1a;ARP欺骗 ARP欺骗&#xff08;ARP spoofing&#xff09;是一种网络攻击技术&#xff0c;它通过伪造ARP&#xff08;地址解析协议&#xff09;响应包来欺骗目标设备&#xff0c;使其将网络流量发送到攻击者指定的位置。具体操作步骤如下&#xff1a; 攻击者…

C# 中 async 与 await 关键字详解

async 和 await 关键字的作用是使方法能够异步执行并等待异步操作的完成。&#xff08;最重要的一点是记住 “异步执行”与“等待异步操作完成”&#xff0c;不是等待主线程操作完成&#xff09; async 修饰符可将 方法、lambda 表达式或匿名方法指定为异步。 async 关键字用于…

MySQL:数据库基础操作

一、MySQL的机制 相信翻到这篇文章的你&#xff0c;应该也是来怀着大大的好奇&#xff0c;来学习MySQL这门语言&#xff0c;那么&#xff0c;现在&#xff0c;就让我和大家一起来学习这门语言吧&#xff01; 这此之前&#xff0c;我们先要了解一个事实&#xff0c;MySQL其实是划…

微服务架构-分支微服务设计模式

微服务架构-分支微服务设计模式 这种模式是聚合器模式的扩展&#xff0c;允许同时调用两个微服务链 分支微服务设计模式是一种用于构建大型系统的微服务架构模式&#xff0c;其核心思想是 将复杂的业务逻辑拆解为多个小的、相互独立的子系统&#xff0c;每个子系统由一个或多…

【iOS】didReceiveMemoryWarning实例方法

iPhone下每个App可用的内存是被限制的&#xff0c;如果一个App使用的内存超过20M&#xff0c;则系统会向该App发送Memory Warning&#xff08;内存警告&#xff09;消息&#xff0c;收到此消息后&#xff0c;App必须正确处理&#xff0c;否则可能出错或出现内存泄漏。 目录 流程…

代码随想录算法训练营day14|二叉树的递归遍历、二叉树的迭代遍历、二叉树的统一迭代法

二叉树的递归遍历 首先需要明确的一点是&#xff0c;前序中序和后序在二叉树的递归遍历中的区别仅在于递归函数中操作的顺序&#xff0c;前序是在遍历一个节点的左右子树前进行操作&#xff0c;中序是在遍历一个节点的左子树后进行操作再遍历右子树&#xff0c;而后序是在遍历…

3D点云焊缝提取 平面交线 投影

文章目录 1. 效果2. 思路3. 源码 1. 效果 2. 思路 计算点云法向量&#xff1b;计算点云位姿Pose;翻转Pose中的Z轴方向&#xff0c;使其一致&#xff1b;通过Pose的Z轴对点云进行方向过滤&#xff1b;对点云聚类&#xff1b;根据目标点云的高度提取目标点云&#xff1b;提取两块…

云计算-Amazon S3

亚马逊S3&#xff08;Amazon S3&#xff09; 亚马逊S3是一种云对象存储设施。我们将使用的对象将是您在个人计算机上常用的文件。亚马逊S3产品旨在可扩展到实际无限数量的对象和无限大小的对象&#xff0c;但我们在本实验室的练习中只会使用少量对象。当存储许多对象时&#xf…

微服务架构下的‘黑带’安全大师:Spring Cloud Security全攻略!

深入探讨了微服务间的安全通信、安全策略设计以及面对经典安全问题的应对策略。无论你是微服务的新手还是资深开发者&#xff0c;都能在本文中找到提升安全功力的秘籍。让我们一起成为微服务架构下的‘黑带’安全大师&#xff01; 文章目录 1. 引言微服务安全挑战与重要性Sprin…

前后端 | 低代码平台之 Erupt

前文提要 最近大家是不是都有那种危机感&#xff0c;项目变多了&#xff0c;工时压紧了&#xff0c;老板说&#xff0c;我不管你加不加班&#xff0c;我只看结果&#xff0c;项目经理说&#xff0c;我不管你用什么技术栈&#xff0c;我只要没BUG&#xff0c;测试说&#xff0c…

【SQL学习进阶】从入门到高级应用(一)

文章目录 MySQL命令行基本命令数据库表的概述初始化测试数据熟悉测试数据 &#x1f308;你好呀&#xff01;我是 山顶风景独好 &#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01; &#x1f49d;希望您在这里可以感受到一份轻松愉快的氛围&#x…

算法002:复写零

力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/duplicate-zeros/ 使用 双指针 来解题&#xff1a; 具体思路 如果是和00…

【Linux】线程安全及锁的使用

文章目录 前言一、锁1.定义一个锁变量2.pthread_mutex_init3.pthread_mutex_destroy4.pthread_mutex_lock/pthread_mutex_unlock5.静态变量锁和全局变量锁的初始化 二、问题描述及锁的运用三、RAII风格的锁 前言 临界资源: 在多个线程或进程间共享的资源. 临界区: 代码中访问临…

echarts-象形柱图

象形柱图 一般的柱图都是纯色柱图&#xff0c;使用象形柱图可以给柱图定义自己的样式。 样式的调节与柱图一样&#xff0c;核心在于symbol调节柱图的组成。 let options {tooltip: {},xAxis: {type: "category",data: ["d1", "d2", "d3&qu…