动态路由 + 路由传参 + 路由接参
引入组件库
组件库就是可以快速帮助我们实现样式布局和基本逻辑
组件库 vs ui库
类型
说明:Vue的组件库很多,我这边列举的是比较流行的
pc端 【 后台管理系统 】
element-ui 饿了吗前端开发团队完成
iview
移动端
Mint-ui
Vant
组件库安装
安装方式
全局引入: 将组件库中所有组件都引入项目,这样会增大项目体积
yarn add element-ui -D
在main.js中引入: import ElmentUI from ‘element-ui’
在main.js中使用Vue.use注册插件
按需引入: 只将我们需要的组件引入进来
注意: 项目配置文件修改了,我们必须重启项目
测试组件库是否引入成功
多试几个组件库,多用几个
Vue项目配置反向代理,实现跨域
Vue cli3 webpack配置放在node_modules 中,也就是说我们不能直接更改,Vue提供了一个叫做vue.config.js的文件,没来作为webpack的覆盖配置文件,也可以说是vue项目的配置文件
vue.config.js 文件是放在项目 根目录 中
vue.config.js 文件是webpack配置文件,webpack底层就是node.js
module.exports = {
devServer: {
proxy: {
// 一个键值就是一个反向代理的配置
'/index.php': {
target: 'http://www.qinqin.net',//目标源指的就是你要跨域的目标
changeOrigin: true, // 修改目标源为我们当前源
}
}
}
}
修改配置文件,项目要重启 【 特别注意 】
案例演示
动态路由
在vue项目中,使用vue-router如果进行不传递参数的路由模式,则称为静态路由;如果能够传递参数,对应的路由数量是不确定的,此时的路由称为动态路由。动态路由,是以冒号为开头的(
举例:
{
path: '/list/:id', //用于url携带id 和 查找字符串
component: List,
name: 'list'
},
路由传参
在router-link组件的to属性上进行–声明式
<span> {{ ele.name }} span>
router-link>
通过编程式导航来完成
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:
const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
replace
push/replace的参数就是to属性的参数
router(n)
methods: {
goBack () {
this.$router.go( -1 )
}
},
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)
路由接参
通过 this.$route就可以将路由路径中的数据接收到,这个就是路由接参
一般用来请求数据时候的参数 类似于 购物车的 sid。。。。。。。
params: {
r: 'class/cyajaxsub',
page: 1,
cid: this.$route.query.cid, //通过this.$route
px: 't',
cac_id: ''
}
动态路由组件
编程式导航
push
replace
push vs replace
如果我们给组件身上添加原生事件,那么我们需要加一个修饰符 native
登录 el-button>
阿里p7要求: 路由导航守卫 、 路由鉴权
共有三个类型
beforeEach
全局导航守卫 - 前置守卫 - 管理的是路由的进入const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
to表示目标路径 - 我想进哪里
from表示当前路径 - 我现在所处的路径
next 表示 from 到 to的连接 ,它可以控制是否允许进入
业务:当我们登陆了之后,我们前端要将后端给的token值存储起来,然后我们通过判断token是否存在,来进入项目
router.beforeEach(( to,from,next ) => {
const token = localStorage.getItem( 'token' )
// 如果token不存在,那么我们自动跳转登录页面,然后让用户登录,来获得token值
if ( to.path == '/home') {
next()
}
if ( to.path == '/category' ) {
next()
}
if ( !token ) {
// next( 路由路径 ) 可以跳转某一个路由
/* 以下这么些会出现一个问题就是死循环 */
// console.log( 1 )
// next('/mine/login')
// next()
/*
所以要想不出现死循环,我们要加判断条件
思考: 需要打破这个死循环的条件
这样,用户进入哪一个页面可以由我们来控制
*/
switch ( to.path ) {
case '/home':
next('/mine/login')
next()
break;
case '/category':
next('/mine/login')
next()
break;
case '/shopcar':
next('/mine/login')
next()
break;
default:
break;
}
}
}
afterEach
后置守卫 - 表示的离开router.afterEach(( to,from ) => {
//没有next参数,那就没有拦截作用,它可以提示作用
if ( to.path == '/home' ) {
alert( '您是否要今天入首页?' )
}
})
beforeEnter
守卫:针对的是一个路由的配置
案例: 权限验证
{
path: '/recommend',
component: Recommend,
beforeEnter ( to,from,next ) {
//可以做拦截
console.log('beforeEnter')
next()
// 超级管理员
}
},
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
beforeRouteEnter
前置守卫data () {
return {
category: { //注意这里写两层
data: null
}
}
},
beforeRouteEnter ( to,from,next ) { // 表示进入组件前
console.log( this ) // 没有this
axios.get('/mock/shopcar.json')
.then( res => {
console.log( 'res',res )
// 问题:我们想把获得的数据提前给到组件,但是我们在这个钩子中无法获得组件,this也没有
// 解决
next( vm => {
// vm就是当前组件
console.log( 'vm',vm )
// vm.name = "yyb" 这么加的话是无法成功的
// 因为vue中响应式数据要求在data选项中定义
vm.$set( vm.category, 'data', res.data )//这样加我们的数据合并到data选项中
// vm.$set / Vue.$set底层是Object.assign 也就是对象合并
next()
})
})
.catch( err => console.log( err ))
},
beforRouteUpdate
更新守卫this
beforRouteLeave
后置守卫next(false)
来取消。beforeRouteLeave ( to,from,next ) {
// 也是拦截
// this可以拿到
if ( this.username || this.password || this.email || this.phone ) {
if ( confirm( '您确定要离开吗' ) ) {
next()
} else {
next( false )
}
} else {
next()
}
},
如何处理路由拦截,也就是我们被卡在登录页面或是其他页面
数据请求拿不到怎么办?
beforeEach
守卫。
beforeRouteUpdate
守卫 (2.2+)。beforeEnter
。
beforeRouteEnter
。
beforeResolve
守卫 (2.5+)。
afterEach
钩子。
beforeRouteEnter
守卫中传给 next
的回调函数。结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。
const Foo = () => import('./Foo.vue')
有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
是基本的动态组件,所以我们可以用
组件给它添加一些过渡效果:
<transition>
<router-view>router-view>
transition>
<router-view>router-view>
transition>
也可以给单个路由设置过度动画效果
并设置不同的 name。const Foo = {
template: `
...
`
}
const Bar = {
template: `
`
}
普通标签也可以使用过度动画效果
<div id="example-1">
<button @click="show = !show">
Toggle render
button>
<transition name="slide-fade">
<p v-if="show">hellop>
transition>
div>
普通标签也可以使用过度动画效果
<div id="example-1">
<button @click="show = !show">
Toggle render
button>
<transition name="slide-fade">
<p v-if="show">hellop>
transition>
div>
module.exports = {
chainWebpack: config => {
config.resolve.alias
// 需要重启 IDE
.set('assets', resolve('src/assets'))
.set('components', resolve('src/components'))
// 这里只写了两个个,你可以自己再加,按这种格式.set('', resolve(''))
}
}