前端学习八(Vue Router)

Vue Router官网:https://router.vuejs.org/zh/guide/#html

一、引用库

<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

二、定义 (路由) 组件(可以从其他文件 import 进来)

Login组件如下

 const Login = {
            template: `
            <div class="box">
                <el-card class="box-card">
                    <h3>用户登录</h3>
                    <el-form :model="form" label-width="80px">
                        <el-form-item label="账号">
                            <el-input v-model="form.username"></el-input>
                        </el-form-item>
                        <el-form-item label="密码">
                            <el-input v-model="form.password" type="password"></el-input>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" @click="login">点击登录</el-button>
                        </el-form-item>
                    </el-form>
                </el-card>
            </div>`,
            data() {
                return {
                    form: {
                        username: "",
                        password: ""
                    }
                }
            },
            methods: {
                async login() {
                    const r = await http.post("/user/login/", this.form)
                    if (r.status === 200) {
                        const token = r.data.token;
                        window.sessionStorage.setItem("token", token)
                        // 编程式跳转路由
                        this.$router.push('/home')
                        // this.$router.push({ path: '/login' })
                    } else {
                        alert("登录失败")
                    }
                }
            }
        }

Home组件如下

        const Home = {
            template: `
            <div class="box2">
                <el-button type="primary" @click="getProjects">获取项目</el-button>
                <el-table :data="tableData" stripe style="width: 100%">
                    <el-table-column prop="id" label="ID" width="180">
                    </el-table-column>
                    <el-table-column prop="name" label="项目" width="180">
                    </el-table-column>
                    <el-table-column prop="create_time" label="创建时间" min-width="200px">
                    </el-table-column>
                </el-table>
            </div>` ,
            data() {
                return { tableData: "" }
            },
            methods: {
                async getProjects() {
                    const r = await http.get("/projects/")
                    console.log(r);
                    if (r.status === 200) {
                        this.tableData = r.data.results
                    } else {
                        alert("获取项目失败")
                    }
                },
            }
        }
View Code

三、定义路由以及创建路由实例 

        // 2. 定义路由
        // 每个路由应该映射一个组件。 其中"component" 可以是通过 Vue.extend() 创建的组件构造器,
        // 或者,只是一个组件配置对象。
        const routes = [
            { path: "/login", component: Login },
            { path: "/home", component: Home }
        ]

        // 3. 创建 router 实例
        const router = new VueRouter({
            routes: routes
            // 如果定义的路由名和key相同,则可以如下简写 
            // routes
        })

子路由

const routes = [
            {
                path: "/",
                component: Home,
                // 子路由,内容会渲染在父路由的router-view中
                children: [
                    { path: "/index", component: index },
                    { path: "/project", component: project },
                    { path: "/api", component: api }
                ]
            }, {
                path: "/login",
                component: Login
            }
        ]

别名和重定向

        const routes = [
            // 重定向
            { path: "/", redirect: "/login" },
            // 别名name
            { name: "rgs", path: "/register", component: Register },
            { path: "/login", component: Login },
            { path: "/home", component: Home }
        ]

别名被使用的两种方式

// 编程式跳转路由,使用别名
this.$router.push({ name: 'rgs' })    
<!-- 使用router-link标签跳转路由(注意,这里是属性绑定,所以要用绑定的形式) -->
<router-link :to="{name:'rgs'}" >注册</router-link>

四、注入路由到vue实例

// 4. 注入路由到vue实例
        const app = new Vue({
            el: "#app",
            router: router
        })

 五、使用

  <div id='app'>
        <!-- 路由出口,路由匹配到的组件将渲染在这里 -->
        <router-view></router-view>
    </div>

六、编程式导航和声明式导航

// 编程式跳转路由
this.$router.push('/home')
<!-- 声明式导航 -->
<router-link to="/login">登录页面</router-link>

七、上面学习内容练习的实例

实例1

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>

<body>
    <div id='app'>
        <!-- 路由出口,路由匹配到的组件将渲染在这里 -->
        <router-view></router-view>
    </div>
    <script>
        const http = axios.create({
            baseURL: 'http://api.keyou.site:8000',
            timeout: 1000
        });

        http.interceptors.request.use(function (config) {
            const token = window.sessionStorage.getItem("token")
            if (token) {
                config.headers.Authorization = 'JWT ' + token
            }
            return config;
        }, function (error) {
            return Promise.reject(error);
        });
        // 1. 定义 (路由) 组件,可以从其他文件 import 进来
        const Login = {
            template: `
            <div class="box">
                <el-card class="box-card">
                    <h3>用户登录</h3>
                    <el-form :model="form" label-width="80px">
                        <el-form-item label="账号">
                            <el-input v-model="form.username"></el-input>
                        </el-form-item>
                        <el-form-item label="密码">
                            <el-input v-model="form.password" type="password"></el-input>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" @click="login">点击登录</el-button>
                        </el-form-item>
                    </el-form>
                </el-card>
            </div>`,
            data() {
                return {
                    form: {
                        username: "musen123",
                        password: "123456"
                    }
                }
            },
            methods: {
                async login() {
                    const r = await http.post("/user/login/", this.form)
                    if (r.status === 200) {
                        const token = r.data.token;
                        window.sessionStorage.setItem("token", token)
                        // 编程式跳转路由
                        this.$router.push('/home')
                        // this.$router.push({ path: '/login' })
                    } else {
                        alert("登录失败")
                    }
                }
            }
        }
        const Home = {
            template: `
            <div class="box2">
                <el-button type="primary" @click="getProjects">获取项目</el-button>
                <el-table :data="tableData" stripe style="width: 100%">
                    <el-table-column prop="id" label="ID" width="180">
                    </el-table-column>
                    <el-table-column prop="name" label="项目" width="180">
                    </el-table-column>
                    <el-table-column prop="create_time" label="创建时间" min-width="200px">
                    </el-table-column>
                </el-table>
            </div>` ,
            data() {
                return { tableData: "" }
            },
            methods: {
                async getProjects() {
                    const r = await http.get("/projects/")
                    console.log(r);
                    if (r.status === 200) {
                        this.tableData = r.data.results
                    } else {
                        alert("获取项目失败")
                    }
                },
            }
        }

        // 2. 定义路由
        // 每个路由应该映射一个组件。 其中"component" 可以是通过 Vue.extend() 创建的组件构造器,
        // 或者,只是一个组件配置对象。我们晚点再讨论嵌套路由。
        const routes = [
            { path: "/login", component: Login },
            { path: "/home", component: Home }
        ]

        // 3. 创建 router 实例
        const router = new VueRouter({
            routes: routes
            // 如果定义的路由名和key相同,则可以如下简写 
            // routes
        })

        // 4. 注入路由到vue实例
        const app = new Vue({
            el: "#app",
            router: router
        })
    </script>
</body>

</html>
View Code

实例2

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>

<body>
    <div id='app'>
        <el-menu class="el-menu-demo" mode="horizontal" background-color="#545c64" text-color="#fff"
            active-text-color="#ffd04b">
            <el-menu-item index="11">
                <!-- 声明式导航 -->
                <router-link to="/login">登录页面</router-link>
            </el-menu-item>
            <el-menu-item index="12">
                <router-link to="/home">个人中心</router-link>
            </el-menu-item>

            <el-menu-item index="13">
                <!-- 使用router-link标签跳转路由(注意,这里是属性绑定,所以要用绑定的形式) -->
                <router-link :to="{name:'rgs'}" >注册</router-link>
            </el-menu-item>
            <el-submenu index="2">
                <template slot="title">我的工作台</template>
                <el-menu-item index="2-1">选项1</el-menu-item>
                <el-menu-item index="2-2">选项2</el-menu-item>
                <el-menu-item index="2-3">选项3</el-menu-item>
            </el-submenu>
            <el-menu-item index="3" disabled>消息中心</el-menu-item>
            <el-menu-item index="4"><a href="https://www.ele.me" target="_blank">订单管理</a></el-menu-item>
        </el-menu>
        <!-- 路由出口,路由匹配到的组件将渲染在这里 -->
        <router-view></router-view>
    </div>
    <script>
        const http = axios.create({
            baseURL: 'http://api.keyou.site:8000',
            timeout: 1000
        });

        http.interceptors.request.use(function (config) {
            const token = window.sessionStorage.getItem("token")
            if (token) {
                config.headers.Authorization = 'JWT ' + token
            }
            return config;
        }, function (error) {
            return Promise.reject(error);
        });

        // 1. 定义 (路由) 组件
        const Login = {
            template: `
        <div class="box">
            <el-card class="box-card">
                <h3>用户登录</h3>
                <el-form :model="form" label-width="80px">
                    <el-form-item label="账号">
                        <el-input v-model="form.username"></el-input>
                    </el-form-item>
                    <el-form-item label="密码">
                        <el-input v-model="form.password" type="password"></el-input>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="primary" @click="login">点击登录</el-button>
                    </el-form-item>
                </el-form>
            </el-card>
        </div>`,
            data() {
                return {
                    form: {
                        username: "musen123",
                        password: "123456"
                    }
                }
            },
            methods: {
                async login() {
                    const r = await http.post("/user/login/", this.form)
                    if (r.status === 200) {
                        const token = r.data.token;
                        window.sessionStorage.setItem("token", token)
                        // 编程式跳转路由
                        this.$router.push('/home')
                        // this.$router.push({ path: '/login' })
                    } else {
                        alert("登录失败")
                    }
                }
            }
        }
        const Home = {
            template: `
        <div class="box2">
            <el-button type="primary" @click="registerBtn">注册</el-button>
            <el-button type="primary" @click="getProjects">获取项目</el-button>
            <el-table :data="tableData" stripe style="width: 100%">
                <el-table-column prop="id" label="ID" width="180">
                </el-table-column>
                <el-table-column prop="name" label="项目" width="180">
                </el-table-column>
                <el-table-column prop="create_time" label="创建时间" min-width="200px">
                </el-table-column>
            </el-table>
        </div>` ,
            data() {
                return { tableData: "" }
            },
            methods: {
                async getProjects() {
                    const r = await http.get("/projects/")
                    console.log(r);
                    if (r.status === 200) {
                        this.tableData = r.data.results
                    } else {
                        alert("获取项目失败")
                    }
                },
                async registerBtn() {
                    // 编程式跳转路由,使用别名
                    this.$router.push({ name: 'rgs' })
                },
            }
        }
        const Register = {
            template: `<p1>注册页面</p1>`
        }

        const routes = [
            // 重定向
            { path: "/", redirect: "/login" },
            // 别名name
            { name: "rgs", path: "/register", component: Register },
            { path: "/login", component: Login },
            { path: "/home", component: Home }
        ]

        const router = new VueRouter({
            routes
        })

        var vm = new Vue({
            el: "#app",
            router: router
        })
    </script>
</body>

</html>
View Code

实例3

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>

<body>
    <div id='app'>
        <router-view></router-view>
    </div>
    <script>
        const http = axios.create({
            baseURL: 'http://api.keyou.site:8000',
            timeout: 1000
        });

        http.interceptors.request.use(function (config) {
            const token = window.sessionStorage.getItem("token")
            if (token) {
                config.headers.Authorization = 'JWT ' + token
            }
            return config;
        }, function (error) {
            return Promise.reject(error);
        });

        // 1. 定义 (路由) 组件
        const Login = {
            template: `
        <div class="box">
            <el-card class="box-card">
                <h3>用户登录</h3>
                <el-form :model="form" label-width="80px">
                    <el-form-item label="账号">
                        <el-input v-model="form.username"></el-input>
                    </el-form-item>
                    <el-form-item label="密码">
                        <el-input v-model="form.password" type="password"></el-input>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="primary" @click="login">点击登录</el-button>
                    </el-form-item>
                </el-form>
            </el-card>
        </div>`,
            data() {
                return {
                    form: {
                        username: "musen123",
                        password: "123456"
                    }
                }
            },
            methods: {
                async login() {
                    const r = await http.post("/user/login/", this.form)
                    if (r.status === 200) {
                        const token = r.data.token;
                        window.sessionStorage.setItem("token", token)
                        // 编程式跳转路由
                        this.$router.push('/')
                        // this.$router.push({ path: '/login' })
                    } else {
                        alert("登录失败")
                    }
                }
            }
        }

        const Home = {
            template: `
            <div>
            <el-menu class="el-menu-demo" mode="horizontal" background-color="#545c64" text-color="#fff"
            active-text-color="#ffd04b">
                <el-menu-item index="1">
                    <router-link to="/index">index页面</router-link>
                </el-menu-item>
                <el-menu-item index="2">
                    <router-link to="/project">项目页面</router-link>
                </el-menu-item>
                <el-menu-item index="2">
                    <router-link to="/api">api页面</router-link>
                </el-menu-item>   
            </el-menu>
            <router-view></router-view>        
        </div>`
        }

        const index = {
            template: `<h1>index页面</h1>`
        }

        const project = {
            template: `<h1>项目页面</h1>`
        }

        const api = {
            template: `<h1>api页面</h1>`
        }

        const routes = [
            {
                path: "/",
                component: Home,
                // 子路由,内容会渲染在父路由的router-view中
                children: [
                    { path: "/index", component: index },
                    { path: "/project", component: project },
                    { path: "/api", component: api }
                ]
            }, {
                path: "/login",
                component: Login
            }
        ]

        const router = new VueRouter({
            routes// (缩写) 相当于 routes: routes
        })

        var vm = new Vue({
            el: "#app",
            router: router
        })
    </script>
</body>

</html>
View Code

八、路由参数传递

1、路径参数

                    // 编程式导航和传参
                    this.$router.push(
                        { name: 'usr', params: { id: 999, key: 100 } }
                    )
            <button type="button">
                <!-- 声明式导航 -->
                <router-link to="/user/99/00">声明式导航1</router-link>
            </button>

            <button type="button">
                <!-- 声明式导航,别名和传参 -->
                <router-link :to="{name:'usr',params:{id:111,key:222}}">声明式导航2</router-link>
            </button>
            const User = {
                // 动态路径匹配,我没定义$route,应该是vue对象自带的
                template: `
                <div>
                    <h1>User页面</h1>
                    <h3>参数值为:{{$route.params.id}}</h3>
                    <h3>参数值为:{{$route.params.key}}</h3>        
                </div>`
            }

练习文件

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>

<body>
    <div id="app">
        <button type="button">
            <!-- 声明式导航 -->
            <!-- <router-link to="/user/99/00">按钮</router-link> -->
            <!-- 声明式导航,别名和传参 -->
            <router-link :to="{name:'usr',params:{id:111,key:222}}">声明式导航</router-link>
        </button>

        <button type="button" @click='usrBtn'>编程式导航</button>

        <router-view></router-view>
    </div>
    <script type="text/javascript">
        const Home = {
            template: "<h1>Home页面</h1>"
        }
        const User = {
            // 动态路径匹配,我没定义$route,应该是vue对象自带的
            template: `
                <div>
                    <h1>User页面</h1>
                    <h3>参数值为:{{$route.params.id}}</h3>
                    <h3>参数值为:{{$route.params.key}}</h3>        
                </div>`
        }

        const routes = [{
            path: "/",
            component: Home,
        }, {
            path: "/user/:id/:key",
            component: User,
            name: "usr"
        }]

        const router = new VueRouter({
            routes: routes
        })

        var vm = new Vue({
            el: "#app",
            data: {},
            router: router,
            methods: {
                usrBtn() {
                    console.log(this.$route);
                    // 编程式导航和传参
                    this.$router.push(
                        { name: 'usr', params: { id: 999, key: 100 } }
                    )
                    console.log(this.$route);
                }
            }
        })
    </script>
</body>

</html>
View Code

2、查询参数

                    // 编程式导航和传参
                    this.$router.push(
                        { name: 'usr', query: { name: 111, age: 222 } }
                    )
        <button type="button">
            <!-- 声明式导航,别名和传参 -->
            <router-link :to="{name:'usr',query:{name:777,age:888}}">声明式导航</router-link>
        </button>
        const User = {
            // 动态路径匹配,我没定义$route,应该是vue对象自带的
            template: `
                <div>
                    <h1>User页面</h1>
                    <h3>参数值为:{{$route.query.name}}</h3>
                    <h3>参数值为:{{$route.query.age}}</h3>        
                </div>`
        }

练习文件

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>

<body>
    <div id="app">
        <button type="button">
            <!-- 声明式导航,别名和传参 -->
            <router-link :to="{name:'usr',query:{name:777,age:888}}">声明式导航</router-link>
        </button>

        <button type="button" @click='usrBtn'>编程式导航</button>

        <router-view></router-view>
    </div>
    <script type="text/javascript">
        const Home = {
            template: "<h1>Home页面</h1>"
        }
        const User = {
            // 动态路径匹配,我没定义$route,应该是vue对象自带的
            template: `
                <div>
                    <h1>User页面</h1>
                    <h3>参数值为:{{$route.query.name}}</h3>
                    <h3>参数值为:{{$route.query.age}}</h3>        
                </div>`
        }

        const routes = [{
            path: "/",
            component: Home,
        }, {
            path: "/user",
            component: User,
            name: "usr"
        }]

        const router = new VueRouter({
            routes: routes
        })

        var vm = new Vue({
            el: "#app",
            data: {},
            router: router,
            methods: {
                usrBtn() {
                    console.log('==',this.$route);
                    // 编程式导航和传参
                    this.$router.push(
                        { name: 'usr', query: { name: 111, age: 222 } }
                    )
                    console.log("++",this.$route);
                }
            }
        })
    </script>
</body>

</html>
View Code

九、导航守卫

应用场景,把没有权限访问的路径重定向回开始路径

to  前往路径

from  开始路径

next   执行跳转动作,默认参数是to路径

        // 定义路由导航守卫
        router.beforeEach((to, from, next) => {
            if (to.path === '/login' || window.sessionStorage.getItem('token')) {
                // 这里还可以鉴别token是否有效
                next()
            } else {
                next('/login')
            }
        })

练习文件

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>

<body>
    <div id='app'>
        <!-- 路由出口,路由匹配到的组件将渲染在这里 -->
        <router-view></router-view>
    </div>
    <script>
        const http = axios.create({
            baseURL: 'http://api.keyou.site:8000',
            timeout: 1000
        });

        http.interceptors.request.use(function (config) {
            const token = window.sessionStorage.getItem("token")
            if (token) {
                config.headers.Authorization = 'JWT ' + token
            }
            return config;
        }, function (error) {
            return Promise.reject(error);
        });

        const Login = {
            template: `
            <div class="box">
                <el-card class="box-card">
                    <h3>用户登录</h3>
                    <el-form :model="form" label-width="80px">
                        <el-form-item label="账号">
                            <el-input v-model="form.username"></el-input>
                        </el-form-item>
                        <el-form-item label="密码">
                            <el-input v-model="form.password" type="password"></el-input>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" @click="login">点击登录</el-button>
                        </el-form-item>
                    </el-form>
                </el-card>
            </div>`,
            data() {
                return {
                    form: {
                        username: "musen123",
                        password: "123456"
                    }
                }
            },
            methods: {
                async login() {
                    const r = await http.post("/user/login/", this.form)
                    if (r.status === 200) {
                        const token = r.data.token;
                        window.sessionStorage.setItem("token", token)
                        // 编程式跳转路由
                        this.$router.push('/home')
                        // this.$router.push({ path: '/login' })
                    } else {
                        alert("登录失败")
                    }
                }
            }
        }
        const Home = {
            template: `
            <div class="box2">
                <el-button type="primary" @click="getProjects">获取项目</el-button>
                <el-table :data="tableData" stripe style="width: 100%">
                    <el-table-column prop="id" label="ID" width="180">
                    </el-table-column>
                    <el-table-column prop="name" label="项目" width="180">
                    </el-table-column>
                    <el-table-column prop="create_time" label="创建时间" min-width="200px">
                    </el-table-column>
                </el-table>
            </div>` ,
            data() {
                return { tableData: "" }
            },
            methods: {
                async getProjects() {
                    const r = await http.get("/projects/")
                    console.log(r);
                    if (r.status === 200) {
                        this.tableData = r.data.results
                    } else {
                        alert("获取项目失败")
                    }
                },
            }
        }


        const routes = [
            { path: "/login", component: Login },
            { path: "/home", component: Home }
        ]

        const router = new VueRouter({
            routes: routes
        })
        // 定义路由导航守卫
        router.beforeEach((to, from, next) => {
            if (to.path === '/login' || window.sessionStorage.getItem('token')) {
                // 这里还可以鉴别token是否有效
                next()
            } else {
                next('/login')
            }
        })


        const app = new Vue({
            el: "#app",
            router: router
        })
    </script>
</body>

</html>
View Code

 

posted @ 2021-11-21 22:41  whitewall  阅读(60)  评论(0)    收藏  举报