[Vue] 06 - Route
Vue风格的路由
Hash 路由配置
一、安装 vue-router
Ref: https://router.vuejs.org/zh/installation.html
二、准备组件
子组件一。
<template> <!-- 所有的内容要被根节点包含起来 --> <div id="home"> 我是首页组件 </div> </template> <script> export default{ data(){ return { msg:'我是一个home组件' } } } </script> <style lang="scss" scoped> </style>
子组件二。
<template> <div id="news"> 我是新闻组件 </div> </template> <script> export default{ data(){ return { msg:'我是一个新闻组件' } } } </script> <style lang="scss" scoped> </style>
三、Route 配置
-
路由配置 - main.js
这里专门对 route 进行了配置。
import Vue from 'vue'; import App from './App.vue'; import VueRouter from 'vue-router'; Vue.use(VueRouter); //1.创建组件 import Home from './components/Home.vue'; import News from './components/News.vue'; //2.配置路由 注意:名字 const routes = [ { path: '/home', component: Home }, { path: '/news', component: News }, { path: '*', redirect: '/home' } /*默认跳转路由*/ ] //3.实例化VueRouter 注意:名字 const router = new VueRouter({ routes // (缩写)相当于 routes: routes }) //4、挂载路由 new Vue({ el: '#app', router, render: h => h(App) }) //5 <router-view></router-view> 放在 App.vue
-
导航页面 - App.vue
基本的套路:
(1)点击链接:router-link
(2)链接页面:router-view
<template> <div id="app"> <router-link to="/home">首页</router-link> <router-link to="/news">新闻</router-link> <hr> <router-view></router-view> </div> </template> <script> export default { data () { return { msg:'你好vue' } } } </script> <style lang="scss"> </style>
效果:说白了就理解为:一个页面但视觉上成了两个页面而已。#的原本意思是 ”Page标识符“。
http://localhost:8080/#/home http://localhost:8080/#/news
动态路由(传参)
一、准备组件
-
App.vue
路由框架主页面,导航链接+内容。
<template> <div id="app"> <router-link to="/home">首页</router-link> <router-link to="/news">新闻</router-link> <hr> <router-view></router-view> </div> </template> <script> /*1、不同路由传值:动态路由 1、配置动态路由 routes: [ // 动态路径参数 以冒号开头 { path: '/user/:id', component: User } ] 2、在对应的页面 this.$route.params获取动态路由的值 */ export default { data () { return { msg:'你好vue' } } } </script> <style lang="scss"> </style>
下面介绍了两种传参的方法。
二、动态路由的链接
-
Home.vue
批量生成了动态路由的链接,这是个 query。
<template> <!-- 所有的内容要被根节点包含起来 --> <div id="home"> 我是首页组件 <ul> <li v-for="(item, key) in list"> <router-link:to="'/pcontent?id='+key">{{key}}--{{item}}</router-link> </li> </ul> </div> </template>
该动态路由方法,路由打开页面为:pcontent.vue + 传入参数 key。
下一步,定义pcontent页面,以及如何从URL中提取出参数key。GET传值 策略。
-
News.vue
批量生成了动态路由的链接,这是个 params。
<template> <div id="news"> 我是新闻组件 <ul> <li v-for="(item, key) in list"> <router-link:to="'/content/'+key">{{key}}--{{item}}</router-link> </li> </ul> </div> </template>
该动态路由方法,路由打开页面为:content.vue + 传入参数 key。
下一步,定义content页面,以及如何接收参数key。
三、动态路由的内容
-
Pcontent.vue
调用打开路由指引页面后,获得 "路由参数”:query。
<template> <div id="content"> 商品详情 </div> </template> <script> export default{ data() { return{ msg:'数据' } }, mounted() { //获取get传值 console.log(this.$route.query); } } </script>
就是“传统地” 获得 GET传值 / URL参数提取 的方法。
-
Conent.vue
调用打开路由指引页面后,获得 “路由参数”:params。
<template> <div id="content"> 我是详情页面 </div> </template> <script> export default{ data(){ return{ msg:'数据' } }, mounted(){ console.log(this.$route.params); /*获取动态路由传值*/ } } </script>
这里定义了vue页面,以及获取参数的套路。
四、动态路由的配置
import Vue from 'vue'; import App from './App.vue'; import VueRouter from 'vue-router'; Vue.use(VueRouter); //1.创建组件 import Home from './components/Home.vue'; import News from './components/News.vue'; import Content from './components/Content.vue'; import Pcontent from './components/Pcontent.vue'; //2.配置路由 注意:名字 const routes = [ { path: '/home', component: Home }, { path: '/news', component: News }, { path: '/content/:aid', component: Content }, /*动态路由*/ { path: '/pcontent', component: Pcontent }, { path: '*', redirect: '/home' } /*默认跳转路由*/ ] //3.实例化VueRouter 注意:名字 const router = new VueRouter({ routes // (缩写)相当于 routes: routes }) //4、挂载路由 new Vue({ el: '#app', router, render: h => h(App) }) //5 <router-view></router-view> 放在 App.vue
实战 - 新闻列表
一、页面效果
二、首页
-
App.vue
这里还是固定的套路:导航栏+内容,上下两部分。
<template> <div id="app"> <header class="header"> <router-link to="/home">首页</router-link> <router-link to="/news">新闻</router-link> </header> <hr> <router-view></router-view> </div> </template> <script>
/* 不同路由传值:动态路由 1、配置动态路由 routes: [ // 动态路径参数 以冒号开头 { path: '/user/:id', component: User } ] 2、在对应的页面 this.$route.params获取动态路由的值 */ export default { data () { return { msg:'你好vue' } } } </script>
<style lang="scss"> .header{ height:4.4rem; background:#000; color:#fff; line-height:4.4rem; text-align:center; a{ color:#fff; padding:0 2rem } } </style>
-
首页代码
<template> <!-- 所有的内容要被根节点包含起来 --> <div id="home"> 我是首页组件 </div> </template> <script> export default{ data(){ return { msg:'我是一个home组件' } } } </script> <style lang="scss" scoped> </style>
三、路由配置
main.js:这里的重点是:"请求数据” 部分。
import Vue from 'vue'; import App from './App.vue'; //引入公共的scss 注意:创建项目的时候必须用scss import './assets/css/basic.scss'; // 请求数据 import VueResource from 'vue-resource'; Vue.use(VueResource); import VueRouter from 'vue-router'; Vue.use(VueRouter); // 1.创建组件 import Home from './components/Home.vue'; import News from './components/News.vue'; import Content from './components/Content.vue'; // 2.配置路由 注意:名字 const routes = [ { path: '/home', component: Home }, { path: '/news', component: News }, { path: '/content/:aid', component: Content }, /* 动态路由,定义了格式 */ { path: '*', redirect: '/home' } /* 默认跳转路由 */ ] // 3.实例化VueRouter 注意:名字 const router = new VueRouter({ routes // (缩写)相当于 routes: routes }) // 4、挂载路由 new Vue({ el: '#app', router, render: h => h(App) }) //5 <router-view></router-view> 放在 App.vue
VueResource: https://github.com/pagekit/vue-resource
{ // GET /someUrl this.$http.get('/someUrl').then(response => { // get body data this.someData = response.body; }, response => { // error callback }); }
四、新闻列表页
jsonp部分请求内容。
{"result":[
{"aid":"499","catid":"20","username":"admin","title":"\u3010\u56fd\u5185\u9996\u5bb6\u3011\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u89c6\u9891\u6559\u7a0b\u514d\u8d39\u4e0b\u8f7d","pic":"portal\/201610\/13\/211832yvlbybpl3rologrr.jpg","dateline":"1476364740"},
{"aid":"498","catid":"20","username":"admin","title":"ionic\u57df\u8d44\u6e90\u5171\u4eab CORS \u8be6\u89e3","pic":"","dateline":"1472952906"}])
新闻内容组件:News.vue
如下:v-for 打印各个链接项。
<template> <div id="news"> 我是新闻组件 <ul class="list"> <li v-for="(item,key) in list"> <router-link :to="'/content/'+item.aid">{{item.title}}</router-link> # 按照格式设置链接 </li> </ul> </div> </template> <script> export default{ data(){ return { msg:'我是一个新闻组件' , list:[] } }, methods:{ requestData(){ //jsonp请求的话 后台api接口要支持jsonp var api='http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1'; this.$http.jsonp(api).then((response)=>{
console.log(response); //注意:用到this要注意this指向 this.list=response.body.result; },function(err){ console.log(err); }) } }, mounted(){ this.requestData(); } } </script>
<style lang="scss" scoped> .list{ li{ height:3.4rem; line-height:3.4rem; boder-bottom:1px solid #eee; font-size:1.6rem; a{ color:#666; } } } </style>
五、新闻内容页
获取 ”html code",然后解析并显示。
http://localhost:8080/#/content/497
v-html:解析网页源代码。
<template> <div id="content"> <h2>{{list.title}}</h2> <div v-html="list.content"></div> </div> </template> <script> export default{ data(){ return{ msg:'数据', list:[] } }, mounted(){ // console.log(this.$route.params); /*获取动态路由传值*/ var aid=this.$route.params.aid; //调用请求数据的方法 this.requestData(aid); }, methods:{ requestData(aid){ // get请求如果跨域的话 后台php java 里面要允许跨域请求 var api='http://www.phonegap100.com/appapi.php?a=getPortalArticle&aid='+aid;
this.$http.get(api).then((response)=>{ console.log(response); this.list=response.body.result[0]; },(err)=>{ console.log(err) }) } } } </script> <style lang="scss"> #content{ padding:1rem; line-height:2; img{ max-width:100%; } } </style>
路由进阶
编程式路由
一、编程控制路由
-
标签路由
除了使用 <router-link>
创建 a 标签来定义导航链接(如下),我们还可以借助 router 的实例方法,通过编写代码来实现。
-
编程路由 & 命名路由
例如:登录成功,进入下一个页面,不成功则不会。此时就需要判断,故,需要引入编程。
点击按钮,进入 (路由到) 另一个页面。$router需要提前定义。
<template> <!-- 所有的内容要被根节点包含起来 --> <div id="home"> 我是首页组件 <button @click="goNews()">通过js跳转到新闻页面</button> </div> </template> <script> export default{ data(){ return { msg:'我是一个home组件' } }, methods:{ goNews(){ // 注意:官方文档写错了 // 第一种跳转方式, 编程式导航 // this.$router.push({ path: 'news' }) // this.$router.push({ path: '/content/495' }); // 另一种跳转方式,命名式路由 (routes 中要先起个名字) // router.push({ name: 'news', params: { userId: 123 }}) this.$router.push({ name: 'news'}) } } } </script> <style lang="scss" scoped> </style>
二、路由 history模式
若要去掉URL中难看的#号。
bash模式:localhost:8080/#/content/499 history模式:localhost:8080/content/499
定义router。实例化 router 时,添加 ‘history'。但注意,需要后端进一步做相应的配置。
import Vue from 'vue'; import App from './App.vue'; //引入公共的scss 注意:创建项目的时候必须用scss import './assets/css/basic.scss'; //请求数据 import VueResource from 'vue-resource'; Vue.use(VueResource); import VueRouter from 'vue-router'; Vue.use(VueRouter); //1.创建组件 import Home from './components/Home.vue'; import News from './components/News.vue'; import Content from './components/Content.vue'; //2.配置路由 注意:名字 const routes = [ { path: '/home', component: Home }, { path: '/news', component: News, name:'news' }, { path: '/content/:aid', component: Content }, /*动态路由*/ { path: '*', redirect: '/home' } /*默认跳转路由*/ ] //3.实例化VueRouter 注意:名字 const router = new VueRouter({ mode: 'history', /* hash模式改为history */ routes // (缩写)相当于 routes: routes }) //4、挂载路由 new Vue({ el: '#app', router, render: h => h(App) }) //5 <router-view></router-view> 放在 App.vue
父子(嵌套)路由
一、路由嵌套
主页标题栏:主路由;侧边栏:子路由。
如下例子所示,主路由不变的情况下,子路由持续变。
需要在 VueRouter 的参数中使用 Children 配置。
User.vue
<template> <!-- 所有的内容要被根节点包含起来 --> <div id="user"> <divclass="user"> <div class="left"> <ul> <li> <router-link to="/user/useradd"> 增加用户</router-link> </li> <li> <router-link to="/user/userlist"> 用户列表</router-link> </li> </ul> </div> <div class="right"> <router-view></router-view> </div> </div>
</div> </template>
二、配置父子路由
为子路由新增两个子模块。
-
main.js
import Vue from 'vue'; import App from './App.vue'; //引入公共的scss 注意:创建项目的时候必须用scss import './assets/css/basic.scss'; /*路由的嵌套 1.配置路由 { path: '/user', component: User, children:[ { path: 'useradd', component: UserAdd }, { path: 'userlist', component: Userlist } ] } 2.父路由里面配置子路由显示的地方 <router-view></router-view> */ //请求数据 import VueResource from 'vue-resource'; Vue.use(VueResource); import VueRouter from 'vue-router'; Vue.use(VueRouter); //1.创建组件 import Home from './components/Home.vue'; import News from './components/News.vue'; import Content from './components/Content.vue'; import User from './components/User.vue'; import UserAdd from './components/User/UserAdd.vue'; import Userlist from './components/User/Userlist.vue'; //2.配置路由 注意:名字 const routes = [ { path: '/home', component: Home }, { path: '/news', component: News,name:'news' }, { path: '/user', component: User, children:[ { path: 'useradd', component: UserAdd }, { path: 'userlist', component: Userlist } ] }, { path: '/content/:aid', component: Content }, /* 动态路由 */ { path: '*', redirect: '/home' } /* 默认跳转路由 */ ] //3.实例化VueRouter 注意:名字 const router = new VueRouter({ mode: 'history', /* hash模式改为history */ routes // (缩写)相当于 routes: routes }) //4、挂载路由 new Vue({ el: '#app', router, render: h => h(App) }) //5 <router-view></router-view> 放在 App.vue
End.