路由传参
跳转路由时 可以给路由对应的组件内传参
声明式导航
router-link 上的to属性,语法格式
/path?参数名=值
/path/值 ------需要路由对象提前配置 path:'/path/:参数名'
对应的页面组件接收传递过来的值
$route.query.参数名
$route.params.参数名
router/index.js
// 3 创建vue路由规则
const routes = [
{
path: '/',
redirect: '/list', //重定向到 /home
},
{
path: '/list',
component: () => import('../views/List'),
},
{
path: '/part',
component: () => import('../views/Part'),
},
{
path: '/detail/:name',
component: () => import('../views/Detail'),
},
{
path: '*',
component: () => import('../views/NotFound'),
},
]
List.vue
<template>
<div>
<router-link to="/part?name=小川">朋友--小川</router-link>
<router-link to="/detail/小妞">朋友--小妞</router-link>
<router-link :to="'/part?name=' + n1">朋友--{{ n1 }}</router-link>
<router-link :to="'/detail/' + n1">朋友--{{ n1 }}</router-link>
</div>
</template>
<script>
export default {
data() {
return {
n1: '花姐',
n2: '露露',
}
},
}
</script>
Part.vue
<template>
<div>
<p>关注明星</p>
{{ $route.query.name }}
<hr />
{{ name }}
</div>
</template>
<script>
export default {
data() {
return {
name: '',
}
},
created() {
// 创建完成 第一次操作data中数据 执行一次
this.name = this.$route.query.name
console.log(this.name)
},
}
</script>
Detail.vue
<template>
<div>
detail
{{ $route.params.name }}
<hr />
{{ name }}
</div>
</template>
<script>
export default {
data() {
return {
name: '',
}
},
created() {
this.name = this.$route.params.name
},
}
</script>
编程式导航
语法:
query/params 任选一个
this.$router.push({
path:"路由路径",
name:"路由名",
query:{
"参数名":"值"
},
params:{
"参数名":"值"
}
})
List.vue
<template>
<div>
<router-link to="/part?name=小川">朋友--小川</router-link>
<router-link to="/detail/小妞">朋友--小妞</router-link>
<router-link :to="'/part?name=' + n1">朋友--{{ n1 }}</router-link>
<router-link :to="'/detail/' + n1">朋友--{{ n1 }}</router-link>
<hr />
<span @click="oneFn">朋友--小川</span>
<span @click="twoFn">朋友--小妞</span>
<span>朋友--{{ n1 }}</span>
<span>朋友--{{ n1 }}</span>
</div>
</template>
<script>
export default {
data() {
return {
n1: '花姐',
n2: '露露',
}
},
methods: {
oneFn() {
this.$router.push({
path: '/part',
query: {
// name: '小川',
name: this.n2,
},
})
},
twoFn() {
// path会自动的忽略params
// this.$router.push({
// name: 'detail',
// params: {
// name: '小妞',
// },
// })
this.$router.push('/detail/' + this.n1)
},
},
}
</script>
路由守卫
ue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。
全局前置守卫
需求:在跳转路由前,判断用户是否登录,登录了才能跳转到“我的音乐“页面,未登录弹窗提示
在路由对象上使用固定的方法 beforeEach
// 1 在路由对象上使用固定的方法 beforeEach
/*
路由跳转"之前" 先执行这里,决定是否跳转
router.beforeEach((to,from ,next)=>{
to 要跳转到的路由 (路由对象信息) 目标
from 从哪里跳转的路由(路由对象信息) 来源
next 函数体, next() 才会让路由正常的跳转切换, next(false)在原地停留 next("路由路径") 强制修改到另一个路由路径上
不调用next 页面留在原地
})
*/
// 在跳转路由前,判断用户是否登录,登录了才能跳转到“part“页面,未登录弹窗提示
const isLogin = false //登陆状态 (未登陆)
router.beforeEach((to, from, next) => {
// console.log(to)
// console.log(from)
if (to.path === '/part' && isLogin === true) {
alert('请登陆')
next(false)
} else {
next() //正常放行
}
})
Vant组件库
vant-contrib.gitee.io/vant/v2/#/z…
vant 轻量、可靠的移动端 Vue 组件库
安装
yarn add vant@latest-v2 -S
导入所有的组件
main.js中导入
// 导入所有的组件
import Vant from 'vant'
import 'vant/lib/index.css'
Vue.use(Vant)
使用组件
<van-button type="primary">主要按钮</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>
手动按需引入
只引入使用的组件
在不使用插件的情况下,可以手动引入需要的组件。---每一个组件中引入
import Button from 'vant/lib/button';
import 'vant/lib/button/style';
注册 --使用
<template>
<div>
<van-button type="primary">主要按钮</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>
import Button from 'vant/lib/button'
import 'vant/lib/button/style'
export default {
components: {
// VanButton: Button,
[Button.name]: Button,
},
}
</script>
自动按需引入组件
babel-plugin-import 是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式。
安装插件
yarn add babel-plugin-import -D
babel.config.js配置,重新启动项目
module.exports = {
plugins: [
['import', {
libraryName: 'vant',
libraryDirectory: 'es',
style: true
}, 'vant']
]
};
组件中使用
<template>
<div>
<van-button type="primary">主要按钮</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>
<van-icon name="chat-o" />
<van-icon name="https://b.yzcdn.cn/vant/icon-demo-1126.png" />
</div>
</template>
<script>
export default {}
</script>
<style scoped></style>
案例
路由配置
二级路由
组件
- Layout.vue ---总的框架
- List.vue ----商品列表
- Search.vue -----商品搜索
- My.vue-----我的信息
配置路由
const routes = [
{
path: '/',
redirect: '/list',
component: () => import('../views/Layout'),
children: [
{
path: 'list',
component: () => import('../views/List'),
},
{
path: 'search',
component: () => import('../views/Search'),
},
{
path: 'my',
component: () => import('../views/My'),
},
],
},
{
path: '*',
component: () => import('../views/NotFound'),
},
]
底部封装
- 创建MyTabBar.vue组件
<template>
<van-tabbar v-model="active" route>
<van-tabbar-item icon="home-o" to="/list">商品列表</van-tabbar-item>
<van-tabbar-item icon="search" to="/search">商品搜索</van-tabbar-item>
<van-tabbar-item icon="friends-o" to="/my">我的信息</van-tabbar-item>
</van-tabbar>
</template>
<script>
export default {
data() {
return {
active: 0,
}
},
}
</script>
顶部封装
-
创建MyHead.vue组件
<template> <div class="head">TabBar案例</div> </template> <script> export default {} </script> <style scoped> .head { height: 50px; line-height: 50px; background-color: blue; text-align: center; color: white; } </style>
商品列表
- 封装MyTable.vue ===标签和样式
- axios 在MyGoodList.vue请求数据回来
- 请求地址www.escook.cn/api/goods
- 传入MyTable.vue 中循环数据显示
axios 在MyGoodList.vue请求数据回来
-
下载axios
yarn add axios -
MyGoodList.vue
<template> <div> <my-table :list="list"></my-table> </div> </template> <script> import axios from 'axios' import MyTable from './MyTable.vue' export default { components: { MyTable, }, data() { return { list: [], } }, created() { // axios({ // url: 'https://www.escook.cn/api/goods', // }).then((res) => { // let { // data: { data: result }, // } = res // console.log(result) // }) this.getDate() }, methods: { async getDate() { let { data: { data: result }, } = await axios({ url: 'https://www.escook.cn/api/goods' }) console.log(result) this.list = result }, }, } </script> -
MyTable.vue
<template> <table class="table"> <thead> <tr> <th>#</th> <th>名称</th> <th>价格</th> <th>标签</th> <th>操作</th> </tr> </thead> <tbody> <tr v-for="(item, index) in list"> <td>{{ item.id }}</td> <td>{{ item.goods_name }}</td> <td>{{ item.goods_price }}</td> <td>{{ item.tags }}</td> <td> <van-button type="primary">删除</van-button> </td> </tr> </tbody> </table> </template> <script> export default { props: { list: Array, }, } </script> <style scoped> .table { width: 100%; margin: 20px auto; border: 1px solid #333; border-collapse: collapse; } td, th { border: 1px solid #333; height: 30px; } </style>
商品表格--插槽
使用插槽技术,和作用域插槽技术,给MyTable.vue组件,自定义列标题,自定义表格内容
需求:允许用户自定义表个头和表格单元格内容
- 把MyTable.vue里准备slot
- 使用MyTable组件时传入具体标签
步骤:
- 提高组件==复用性和灵活性 ==,把表格列标题thead部分预留slot ,设置name属性
- 使用MyTable.vue时,传入列标题标签
- 表格内容td部分也可以让组件使用者自定义,也给tbody预留slot 和name属性
- 使用插槽需要用到插槽内的item对象上的数据,作用域插槽
MyTable.vue
<template>
<table class="table">
<thead>
<tr>
<!-- <th>#</th>
<th>名称</th>
<th>价格</th>
<th>标签</th>
<th>操作</th> -->
<slot name="header"></slot>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in list">
<!-- <td>{{ item.id }}</td>
<td>{{ item.goods_name }}</td>
<td>{{ item.goods_price }}</td>
<td>{{ item.tags }}</td>
<td>
<van-button type="primary">删除</van-button>
</td> -->
<slot name="body" :row="item" :index="index"></slot>
</tr>
</tbody>
</table>
</template>
<script>
export default {
props: {
list: Array,
},
}
</script>
MyGoodList.vue
<template>
<div>
<my-table :list="list">
<template #header>
<th>#</th>
<th>名称</th>
<th>价格</th>
<th>标签</th>
<th>操作</th>
</template>
<template #body="{ row, index }">
<td>{{ row.id }}</td>
<td>{{ row.goods_name }}</td>
<td>{{ row.goods_price }}</td>
<td>{{ row.tags }}</td>
<td>
<van-button type="primary">删除</van-button>
</td>
</template>
</my-table>
</div>
</template>
商品表格tags
<td>
<van-tag v-for="(str, ind) in row.tags" :key="ind" type="primary">{{
str
}}</van-tag>
</td>
\