vue-router的使用

vue-router的使用

基本vue-cli@2.x创建的vue项目。

1.插件安装

# 安装路由
npm install vue-router --save-dev
# element-ui
npm i element-ui -S
# 安装axios
npm install axios -s
# 提升下载速度,后面加这个 指定下载源
--registry https://registry.npmmirror.com

项目结构图:
在这里插入图片描述

2.项目配置

main.js文件配置

通过es6语法导入npm下载的插件,然后通过Vue.use(xx插件),全局声明使用插件.注意:axios的注册方式不一样。如果要使用Vue.use方法,可以下载vue-axious的插件库。用法差不多。

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
//=======导入路由配置======
import router from './router'
//=====导入element-ui 和其样式======
import ElementUi from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
//=======导入axios========
import axios from 'axios'
Vue.config.productionTip = false

//=======声明使用插件======
Vue.use(ElementUi)
//=====注册axios=====
Vue.prototype.axios=axios
/* eslint-disable no-new */
new Vue({
  el: '#app',
 //=======把路由加入vue实例中=====
  router,
  components: { App },
  template: '<App/>',
  render: h => h(App)
})

路由配置:

在src目录下,新建一个router目录,里面再创建一个index.js的路由配置文件.此路由已经在main.js导入了.所有的compoent都来自下面配置的组件。

配置说明:

  • mode:
    • 默认取值hash,就是每次访问路径时,路径上都会带有#
    • histroy:路径不带#
  • routes:用于定义path的访问,每个数组里面都是{}
    • path:访问的路径定义 如:'/index'
    • component:路径访问对应的组件定义
    • name:当前路径的名称定义,可以实现通过名称访问
    • redirect:重定向到已经定义的path上
    • prop:当前路径开启prop属性,路径对应的组件里面可以定义prop:[xx],来接受参数
  • /main/:name:就是给路径定义一个占位符,在路径跳转时,传入参数,然后通过$route.params.name获取其参数。高级点可以通过正则表达式来匹配。

router/index.js:

import Vue from 'vue'
import Router from 'vue-router'
//所有的组件导入
import HelloWorld from '@/components/HelloWorld'
import Main from '../components/Main'
import Login from '../components/Login'
import Menu from '../components/Menu'
import User from '../components/User'
import Role from '../components/Role'
import NotFound from '../components/NotFound'
Vue.use(Router)

export default new Router({
  mode:'history', //不带#号
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },{
        /*  :参数名就是提供一个占位符,路径跳转的时候可以获取
        如果直接是 /main的路径,则不会配置。
        */
      path:'/main/:username',
      name:'Main',
      component:Main,
      //表示开启props使路由组件可以通过prop:['xxxx']接受 $route.params参数
      props:true
    },{
      path:'/login',
      name:'Login',
      component:Login
    },{
      path:'/menu',
      name:'Menu',
      component:Menu,
       //=====嵌套子路由======
       children:[
        {
          path:'/user',
          name:'User',
          component:User
        },
        {
          path:'/role',
          name:'Role',
          component:Role
        }
      ]
    },{
      //==========定义404页面========
      path:'*',
      component:NotFound
    },{
      //重定向
      path:'/home/:username',
      redirect:'/main/:username'
    }
    
  ]
})

3.路由标签

router-link:

<router-link to="path"></router-link>

请注意,我们没有使用常规的 a 标签,而是使用一个自定义组件 router-link 来创建链接。这使得 Vue Router 可以在不重新加载页面的情况下更改 URL,处理 URL 的生成以及编码。其属性有多个选项表示跳转的状态。

router-view:

<router-view></router-view>

访问路径后,将路径对应的默认组件进行显示。一般在其父组件进行定义。可以指定组件显示。

Main.vue中:

<router-link to="/login">登录</router-link>
<router-link to="/menu">管理</router-link>

在这里插入图片描述

Menu.vue中:

  <ul class="nav">
        <li><router-link to="/user">用户管理</router-link></li>
        <li><router-link to="/role">角色管理</router-link></li>
        <li><router-link to="/home/jack">回到首页</router-link></li>
      </ul>

在这里插入图片描述

App.vue

组件如果没有嵌套,所有组件通过路由访问,在此进行显示

<template>
  <div id="app">
    <router-view/> 
  </div>
</template>

4.路径跳转

分为带参数和不带参数

用户和密码通过element-ui进行校验后,通过配置路由的的相关对象进行跳转

跳转的方式:

声明式编程式
<router-link :to="...">router.push(...)

所谓声明式,就是像a标签一样进行点击跳转,而编程式,则在js里面操作路由对象进行跳转。

  • 路径直接跳:

    router.push('/users/eduardo')
    
  • 带有路径对象跳:

    // 带有路径的对象
    router.push({ path: '/users/eduardo' })
    
  • 带有路径的名称和参数跳:

    //path为 /user/eduardo
    //name是路由配置时定义的,可以匹配到路由路径
    router.push({ name: 'user', params: { username: 'eduardo' } })  
    
  • 带有路由和查询参数对象

    $route.query.play

    // 带查询参数/register?plan=private
    router.push({ path: '/register', query: { plan: 'private' } })
    
  1. 如果提供了 path+params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是,你需要提供路由的 name +params或手写完整的带有参数的 path:/main/jack.
  2. 注意路径参数的传递,必须保证路径的配置文件里面已经开启了 形如:/main/:name:name,表示传递参数赋值
  3. /user/jakc{path:'/user',params:{username:'jakc'}}的路径一样,只是表现形式不同而已

案例:登录验证后,通过路由跳转

Login.vue文件内容:

<template>
  <div>
    <el-form ref="form" :model="form" class="login-box" :rules="rules">
      <h3>欢迎登录</h3>
      <el-form-item label="账号" prop="name">
        <el-input
          type="text"
          placeholder="请输入用户名"
          v-model="form.name"
        ></el-input>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input
          type="password"
          placeholder="请输入密码"
          v-model="form.password"
        ></el-input>
      </el-form-item>
      <el-form>
        <el-button type="primary" @click="submitForm('form')">登录</el-button>
      </el-form>
    </el-form>
  </div>
</template>

<script>
export default {
  name: "Login",
  data() {
    return {
      form: {
        name: "",
        password: "",
      },
      rules: {
        name: [
          { required: true, message: "请输入用户名", trigger: "blur" },
          { min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" },
        ],
        password: [
          { required: true, message: "请输入密码", trigger: "blur" },
          {
            min: 6,
            max: 10,
            message: "长度在 6 到 10 个字符",
            trigger: "blur",
          },
        ],
      },
    };
  },
  methods: {
     submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            //登录成功,保存登录信息
              sessionStorage.setItem("loginInfo",this.form.name);
            //=====================带信息跳转=============
              //path==>  /main/jakc?q=查询饕餮
            this.$router.push({name:'Main',params:{username:this.form.name},query:{q:"查询饕餮"}});
          } else {
             this.$message.error('输入有误');
            return false;
          }
        });
      }
  },
};
</script>

<style scoped>
.login-box {
  width: 400px;
  margin: 30px auto;
  border: 1px solid #dcdfe6;
  padding: 20px;
  border-radius: 6px;
  box-shadow: 0 0 30px #dcdfe6;
}
.login-box h3 {
  text-align: center;
}
</style>

效果:

在这里插入图片描述

5.参数获取

路径的配置中有

{
    path:"/main/:username",
    component:xxx,
    name:xxx,
    prop:true //开启,第二种才能使用
}

第一种:

<template>
<p><span>1:{{$route.params.username}}</span>
</template>

第二种:

<template>
<span>2:{{username}}</span>
</template>

<script>
  export default {
    //路径配置必须开启,接受来自$route.params.xxx的参数
    props:['username'],
</script>
案例:登录后主页展示数据

Main.vue:

<template>
<div>
  <i class="el-icon-user"></i>
<p>
    <!-- =======数据获取===================-->
    <span>1:{{$route.params.username}}</span>
	<span>2:{{username}}</span>
	<span>3:query参数:{{$route.query.q}}</span>
    </p>
<router-link to="/login">登录</router-link>
<router-link to="/menu">管理</router-link>
  <el-table 
    :data="tableData"
    center
    style="width: 50%;margin:20px auto">
    <el-table-column
      prop="date"
      label="日期"
      width="180">
    </el-table-column>
    <el-table-column
      prop="name"
      label="姓名"
      width="180">
    </el-table-column>
    <el-table-column
      prop="address"
      label="地址">
    </el-table-column>
  </el-table>
</div>
</template>

<script>
  export default {
    //==========路径配置必须开启,接受来自$route.params.xxx的参数========
    props:['username'],
    data() {
      return {
        tableData: [{
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄'
        }, {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        }, {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄'
        }, {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }]
      }
    },
    //使用路由的钩子函数获取异步数据  -=== 后面axios讲了====
    beforeRouteEnter (to, from, next) {
      /*由于路由进入之前,此组件为实例化,
      通过回调函数获取实例,从而调用methods里面的方法*/
      console.log("进入path:"+to.fullPath);
      next(vm=>vm.getData());
    },
    methods:{
      //定义函数通过axios获取参数
      getData(){
        this.axios.get("./static/data.json").then((res)=>{
            // console.log(res);
            this.tableData=res.data.info;
        }).catch(err=>{
          console.log("请求失败的信息:");
          console.log(err);
        });
      }
    }
  }
</script>
<style lang="">
    
</style>

效果:

在这里插入图片描述

6. 重定向与404

index.js中:

routes:[
    {
      //====定义404页面====
      path:'*',
      component:NotFound
    },{
      //重定向
      path:'/home/:username',
      redirect:'/main/:username'
    }
]

Menu.vue中:

 <li><router-link to="/home/jack">回到首页</router-link></li>

在这里插入图片描述

NotFoud.vue中:

<template lang="">
    <div>
        <img src="@/assets/404.jpeg"/>
    </div>
</template>
<script>
export default {
    name:'NotFound'
}
</script>
<style lang="">
    
</style>

在这里插入图片描述

7.路由嵌套

配置的路由访问中,通过children再次配置路由访问。即在当前路径a中如果访问配置的子路由b,则b路由组件可以直接显示到当前路由a的组件中。

index.js文件:a

{
      path:'/menu',
      name:'Menu',
      component:Menu,
       //嵌套子路由
       children:[
        {
          path:'/user',
          name:'User',
          component:User
        },
        {
          path:'/role',
          name:'Role',
          component:Role
        }
      ]

Menu.vue:

<template lang="">
    <div>
      <ul class="nav">
        <li><router-link to="/user">用户管理</router-link></li>
        <li><router-link to="/role">角色管理</router-link></li>
        <li><router-link to="/home/jack">回到首页</router-link></li>
      </ul>
      <router-view></router-view>
    </div>
</template>

User.vue

<template>
  <el-table
    :data="tableData"
    style="width: 100%">
    <el-table-column
      label="日期"
      width="180">
      <template slot-scope="scope">
        <i class="el-icon-time"></i>
        <span style="margin-left: 10px">{{ scope.row.date }}</span>
      </template>
    </el-table-column>
    <el-table-column
      label="姓名"
      width="180">
      <template slot-scope="scope">
        <el-popover trigger="hover" placement="top">
          <p>姓名: {{ scope.row.name }}</p>
          <p>住址: {{ scope.row.address }}</p>
          <div slot="reference" class="name-wrapper">
            <el-tag size="medium">{{ scope.row.name }}</el-tag>
          </div>
        </el-popover>
      </template>
    </el-table-column>
    <el-table-column label="操作">
      <template slot-scope="scope">
        <el-button
          size="mini"
          @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
        <el-button
          size="mini"
          type="danger"
          @click="handleDelete(scope.$index, scope.row)">删除</el-button>
      </template>
    </el-table-column>
  </el-table>
</template>
<script>
  export default {
    data() {
      return {
        tableData: [{
          date: '2016-05-02',
          name: '悟空',
          address: '上海市普陀区金沙江路 1518 弄'
        }, {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        }, {
          date: '2016-05-01',
          name: '圣将',
          address: '上海市普陀区金沙江路 1519 弄'
        }, {
          date: '2016-05-03',
          name: '唐僧藏',
          address: '上海市普陀区金沙江路 1516 弄'
        }]
      }
    },
    methods: {
      handleEdit(index, row) {
        console.log(index, row);
      },
      handleDelete(index, row) {
        console.log(index, row);
      }
    }
  }
</script>

Role.vue:

<template>
  <el-table
    :data="tableData"
    border
    style="width: 100%">
    <el-table-column
      prop="index"
      label="序号"
      width="180">
    </el-table-column>
    <el-table-column
      prop="name"
      label="姓名"
      width="180">
    </el-table-column>
    <el-table-column
      prop="power"
      label="战力值">
    </el-table-column>
  </el-table>
</template>

<script>
  export default {
    data() {
      return {
        tableData: [{
          index: '1',
          name: '悟空',
          power: '100'
        }, {
          index: '2',
          name: '王小虎',
          power: '20'
        }, {
          index: '3',
          name: '圣将',
          power: '90'
        }, {
          index: '4',
          name: '唐僧藏',
          power: '80'
        }]
      }
    }
  }
</script>

效果:

menu.vue页面:

在这里插入图片描述

点击用户管理:当前menu.vue保存不变,显示user.vue内容

在这里插入图片描述

点击角色户管理:当前Menu.vue保存不变,显示Role.vue内容

在这里插入图片描述

8.路由钩子函数

所谓钩子函数,访问某个路径,在这个路径关联的组件里面,自动执行所触发的函数。

  • Main.vue

    export default{
        data(){
            return {}
        },
        //进入当前路径  执行
        beforeRouteEnter (to, from, next) {
          console.log("进入path:"+to.fullPath);
            next();//可继续去往下一个路由
        },
        //离开当前路径 执行
        beforeRouteLeave(to,from,next){
          console.log("离开path"+to.fullePath);
            next(); //可继续去往下一个路由
        }
    }
    
  • main.js文件:

    beforeEach是全局钩子函数,所有的路径访问都会触发执行此函数。相当于javaweb的/的拦截器。可做登录验证。

        // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
        import Vue from 'vue'
        import App from './App'
        //导入路由配置
        import router from './router'
        //import .............
        Vue.config.productionTip = false
    
        //===========导航全局首位,相当于过滤器,如验证是否登录=========
        router.beforeEach((to,from,next)=>{
          //获取登录状态
          let isLogin=sessionStorage.getItem("loginInfo");
          if(to.path=='/logout'){
            //清除登录状态
            sessionStorage.clear();
              //去往登录页
              next({path:'/login'})
              //如果不加  to.fullPath!='/login',则会不断循环next路由
          }else if(isLogin==null && to.path!='/login'){
              //去往登录页
              next({path:'/login'})
          }
          //下一个路由
            next();
        });
        new Vue({
          el: '#app',
          router,
          components: { App },
          template: '<App/>',
          render: h => h(App)
        })
    
  • 参数说明:

    • to:路由将要跳转的路径信息
    • from :路径跳转前的路径信息
    • next :路由的控制参数:
      • next() 跳入下一个页面
      • next('/path') 改变路由的跳转方向,使其跳到另一个路由
      • next(false) 返回原来的页面
      • next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例化

9.钩子函数+axios

通过路径访问前,异步加载axios获取数据。如从登录Login.vue组件到Main.vue组件

data.json文件内容:

{
    "info":[
        {
            "date":"2020/3/11",
            "name":"jack",
            "address":"饭都花园"
        },
        {
            "date":"2022/4/11",
            "name":"jack",
            "address":"西湖公园"
        },
        {
            "date":"2021/3/4",
            "name":"jerry",
            "address":"天门山游玩"
        }
    ]
 
}

Main.vue文件:

<script>
export default{
    //使用路由的钩子函数获取异步数据
    beforeRouteEnter (to, from, next) {
      /*由于路由进入之前,此组件未实例化,
      通过回调函数获取实例,从而调用methods里面的方法*/
      console.log("进入path:"+to.fullPath);
      next(vm=>vm.getData());
    },
    methods:{
      //定义函数通过axios获取参数
      getData(){
        this.axios.get("./static/data.json").then((res)=>{
            // console.log(res);
            this.tableData=res.data.info;
        }).catch(err=>{
          console.log("请求失败的信息:");
          console.log(err);
        });
      }
    }
  }
</script>

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值