编程式导航:
以前不会vue-cli的时候学过router,当时的写法和在vue-cli中的写法还是有一些不一样的,但是我以后应该还是会用vue的单文件写小程序啊什么的所以我就吧我学习的过程全部记录下来
那么问题来了main.js是如何接收,接收的是什么,和怎么书写?
下面我们来一一解答
首先我们在src的文件下新建一个router文件,下的index.js我们在js中引入vue组件,配置router,导出router
1.引入的方法 import
2.导出的方法 export default router
代码是:
//第二步引入
import Vue from 'vue'
import VueRouter from 'vue-router'
import Hmoe from '../components/Home.vue'
import Question from '../components/Question.vue'
import Vip from '../components/Vip.vue'
import Course from '../components/Course.vue'
//第三步:作为vue的插件
Vue.use(VueRouter)
//创建实例 加入配置
const router = new VueRouter({
routes:[
{
path:'/home',
component: Hmoe
},
{
path:'/vip',
component: Vip
},
{
path:'/coures',
component:Course
},
{
path:'/question',
component:Question
}
]
});
//吧router导出,这样外面的main才可以用
//为模块指定默认输出
export default router
那么大家看到上面的代码可能没有基础的不知道import Course from '../components/Course.vue'他其实就是我们在components文件下写的Course.vue的这个文件,被传到了上面的index.js这个文件
1、选择“文件 -> 首选项 -> 用户代码片段”,此时,会弹出一个搜索框,输入vue
选择
vue
后,编辑器会自动打开一个名字为vue.json
的文件
2.在复制下面的代码,放进去就可以了
"Print to console": {
"prefix": "vue",
"body": [
"",
" $0",
"",
"",
"",
""
],
"description": "Log output to console"
}
}
在router创建的实例中加入mode属性(以下代码为截取的一部分)
#/<路由地址> hash模式 :无刷新
但是当是以
/<路由地址> history模式 :会去请求后端接口在用back,forword,go的方法的时候,当是如果使用pushState和reolaceState方法的时候,这两的方法就可以实现前端路由的目的所以vue-router是通过hash和history这两种模式来控制路由
const router = new VueRouter({
mode: 'hash', //默认情况
})
1.默认router-link是生成的a标签,tag属性可以自定义我们需要生成的标签
2.自动加上了#(hash模式是要加#的)
3.to属性固定我们需要去的路由,:to动态告诉我们要去的路由
4.默认情况下router-link上加active-class属性是支持点击事件的情况下设置的样式
5.跟换默认的事件 events="事件名"
6.全局设置 链接激活时使用的 CSS 类名。默认值可以通过路由的构造选项 linkActiveClass 来全局配置linkActiveClass:'activeClass',
7.模糊匹配:意思就是 /vip 其实他包含了["/","/vip"]两项所以就是不写/,或者在to=/的项上添加 exact(精准匹配) 就可以了
这里的定义了一个/vip的路由,但是当我们要嵌套一些子路由就要添加children这个属性在这个属性中定义一个数组在这个数组中在定义一些路由的对象
要注意,以 /
开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径
{
path: '/vip',
component: Vip,
children: [
{
path: 'one', //这里不可以加/他会主动的生成,加了会报错,只有子路由可以这样
component: VipNoe
},
{
path: 'two',
component: VipTwo
},
{
path: 'three',
component: VipThree
},
]
},
vip.vue文件
我是Vip
给某一个路由添加一个name属性
{
path: '/question',
//命名路由
name: 'wd',
component: Question
},
再在
一般的情况
命名路由的好处
通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes
配置中给某个路由设置名称。
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
}
]
})
要链接到一个命名路由,可以给 router-link
的 to
属性传一个对象:
User
这跟代码调用 router.push()
是一回事:
router.push({ name: 'user', params: { userId: 123 }})
这两种方式都会把路由导航到 /user/123
路径。(上面的用法下面会由讲的)
在路由上这样写
{
path: '/home',
// component: Hmoe,
//命名视图editorconfig
components: {
default: Home, //默认的视图显示的组件
left: HomeLeft, //name为left的视图 显示HomeLeft组件
right: HomeRight //name为right的视图 显示HomeRighr组件
}
},
在
//重定向:从A到B 这里是从/hello到/course
{
path: '/hello',
redirect: '/vip', //跳转到的页面,字符串写法
redirect: '{name:"wd"}', //对象写法
redirect: (to) => { //函数的写法
to 路由信息对象
if(to.hash) {
return '/course'
}else{
return '/vip'
}
}
//别名:他的另一个名字
alias: '/hi' //意思就是不管是/hello 还是 /hi 都指向redirect的值或component的值
},
component:属性值是某一个vue的组件,上面有些案例
redirect:属性值是要跳转的页面,因为有定义过/vip 这个路由,所以会去/vip这个路由中规定的component的值。
这里的to是路由的信息对象;hash就是/后的值
通过js的方法去改变,路由的行为
编程式导航:
Vue({})中参数对象的值
methods: {
pushHandel () {
//console.log(this.$router)
//$router写在了main.js中所以可以使用了就跟使用this.$data是同一个道理
//这里的this.$router中有很多方法
//方法一
//push是给浏览器记录栈(history)添加一项,表意为跳转了一下,但是是有新纪录的
this.$router.push('/question');
},
replaceHandel(){
//replace是给浏览器记录栈(history)添加一项,表意为跳转了一下,但是不会有新纪录的,他只是替换了记录
this.$router.replace('/question')
},
backHandle(){
//后退
this.$router.back();
},
forwardHandle(){
//前进
this.$router.forward();
},
goHandle(){
//在go方法中的参数,正数代表前进,负数代表后
this.$router.go(2);
}
}
多种写法
// 字符串
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
params:一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象,当匹配到一个路由时,参数值会被设置到 this.$route.params
,可以在每个组件内使用
$route.query:一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1
,则有 $route.query.user == 1
,如果没有查询参数,则是个空对象。
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
同样的规则也适用于 router-link
组件的 to
属性。
{
// 动态路径参数 以冒号开头,这里的id类型与一个变量,
path: '/user/:id?', //?:代表0或1
component: user,
props: true, //当这个的props的值为true的时候,这个ID属性就可以传给组件
},
那么这样我就可以不管 /user/* /后面的*是什么都可以匹配,没有值也是可以的
那么在子组件接收的方式有
1.$route.params.id
const User = {
template: 'User {{ $route.params.id }}'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
2.通过props
const User = {
props: ['id'],
template: 'User {{ id }}'
}
方法一:beforeRouteUpdtate
方法二:使用watch监听改变
//动态监听一
// //就是相/user/1 -> 向/user/2切换的是触发的全局钩子事件
beforeRouteUpdate(to, from, next) {
//to: Route: 即将要进入的目标 路由对象
//from: Route: 当前导航正要离开的路由
//next:进行管道中的下一个钩子(也就是我们点击的)
this.userInfo = this.userList.filter(item => {
return item.id === to.params.id;
})[0];
// console.log(this.userInfo);不知道为什么会警告
next();
},
//改变后触发事件
watch: {
$route () {
//console.log(this.$route) 这个就是上面的 to 参数的值一样都是路由信息对象
}
}
路由元信息meta字段是在配置rouer中的数组对象中添加的用来给一个依据,以便钩子函数来做判断
{
path: '/vip',
component: Vip,
//路由元信息meta字段
meta: {
require: true //这里只是为了判断他是否要登录
},
挂载进入路由之前,是在进入路由之前执行 全局钩子会影响所有的路由
router.beforeEach((to, from, next) => {
//console.log('进入路由之前执行',to.meta);
//导航守卫
if (to.meta.require) {
//需要登入
//判断是否已经登录
//跳转next(参数为需要跳转的路由)
next(); //没有这个无法进入我们点击的路由,所以我们通过控制他来实行导航守卫
}else{
next()
}
})
挂载进入路由之后,是在进入路由之后执行
router.afterEach((to , from) => {
if(to.meta.title){
document.title = to.meta.title;
}else{
document.title = '曾皙的第二个router';
}
})
{
path: '/coures',
component: Course,
// 写在路由里面的钩子函数
// beforeEnter(to,from,next){
// //进入之前执行,和全局的写法不一样
// next();
// }
},
export default {
data () {
return {
}
},
components: {
},
//组件中的钩子函数
// befoerRouteEnter(to,from,next){
// //进入之前调用
// },
// beforeRouterLeave (to,from,next){
// //离开后执行
// }
}