Vue.js note9(脚手架:数据请求封装&一级路由&二级路由&动态路由传参&路由重定向)
文章目录
- 1、数据请求axios的封装使用
- 2、路由&一级路由
- (一)含路由项目创建流程:
- (二)一级路由配置
- 创建路由的过程(总结)
自己的第一个一级路由小程序
- (三)路由的跳转方式:
- **>> 扩展1——.router-link-active**
- (四)路由规则通配符匹配问题:`*` 或者 `demo-*`
- **>> 扩展2——路由匹配顺序问题**
- (五)路由的重定向:通过router中的redirect属性配置的。
- 3、多级路由(二级及以上,嵌套路由)
- **>> 多级路由的创建过程:**
- 4、动态路由匹配
- <1> 动态路径参数(路由规则配置时)
- <2> 绑定参数(发送数据参数)
- <3> 获取路由传入的参数(获取数据参数)
- 动态路由—知识点扩展query传参
- params与query区别
下面我们通过一个小栗子来看一下动态路由传参的具体流程。
- (一)promise是什么?
- (二)为什么会有promise
- (三)如何使用promise
- 其他
- 配置解析别名—-修改文件夹引用别名
- 总结
1、数据请求axios的封装使用
以后工作中都进行封装,所以不再使用传统的方式进行数据请求。记得要在src下的api文件夹下创建.js文件,用promise封装api。
(1)下载axios:npm install —save axios(或者使用cnpm来下载)
(2)在src(别名 @)下新建一个api的文件夹,用来存放请求的.js文件
另外,还可以自定义路径别名,比如把 src/api 用 & 来替代。在项目根目录下新建一个vue.config.js文件,添加以下内容:
(3)对axios请求进行封装,用 promise
- 在该请求js文件里面,首先要引入axios的资源包
- 然后用promise封装axios请求数据,注意:一个请求一个函数
然后export导出(暴露)这个函数
//myaxios.js---
import axios from "axios"
export function axioslink() {
return new Promise((resolve, reject) => {
axios({
url: "http://api.artgoer.cn:8084/artgoer/api/v1/user/324380/v3/topic/topicHomeByLabel?pageIndex=1&token=b544cd63-6d42-46fe-a96c-3cf96bae3113&topicId=62187",
method:"get"
}).then((ok)=>{
resolve(ok);
}).catch((err)=>{
reject(err);
})
})
}
(4)在组件中,使用该封装好的模块来进行数据请求
- 先引入并解构出该函数(CommonJS规范)
- 钩子函数中使用封装好的请求函数,将数据存放到组件里面的变量中
页面数据渲染
//myaxios.vue---
<template>
<div>
<!--图片的索引,是相对于public的index.html走的,所以直接写就OK-->
<img src="1.gif" alt="" v-if="!arr.length">
<ul v-else>
输出arr:
<li v-for="(item,index) in arr" :key="index">{
{item.commentTxt}}</li>
</ul>
</div>
</template>
<script> // 因为是用es6模块化export暴露的,所以这里要用花括号解构出来属于commonjs规范 import { axioslink} from "&/myaxios.js" //&代表 src/api ,自定义别名,下面有介绍 export default { data(){ return{ arr:'', } }, created() { // 函数axioslink返回的是个promise对象,所以直接执行axioslink函数就相当于new了个新的promise axioslink().then((ok)=>{ this.arr=ok.data.data.commentList; console.log(ok); }).catch((err)=>{ console.log(err); }) }, } </script>
<style scope> img{ width: 200px; height: 200; margin: 0 auto; } </style>
(5)然后将组件引入全局根组件里面使用
//myApp.vue 打算将它作为全局根组件---
<template>
<div>
<myaxios/>
</div>
</template>
<script> import myaxios from "%/myaxios.vue" export default { components:{ myaxios //引入后声明一下这个组件然后再使用 } } </script>
<style scope> </style>
(6)在main.js文件里更改全局根组件的路径,改成自己现在写的全局根组件的路径,修改后的vue组件就是能够打开的页面。
(7)打开服务:npm run serve
在数据没有请求到时展示”请稍后logo”,等数据出来了,就会切换到数据展示页面。
以上就完成了vue工程化的数据的封装请求、数据的渲染。
2、路由&一级路由
之前我们都用传统页面跳转,比如 a标签 、JavaScript Window Location、window的history对象。比如我们之前见过的js的跳转方式:
window,location.href() 点返回键能回来
window.location.reload(); 重新加载当前页面
window.history.replaceState() 替换或者修改地址,无法再回到更改之前的url
window.history.go(number|URL) 可加载历史记录中的某个具体的页面。
window.history.forward() 可加载历史列表中的下一个 URL。
window.history.back() 可加载历史列表中的前一个 URL(如果存在)。
调用后两种方法的效果等价于点击前进按钮或调用 history.go(1)。
在使用location.href、a标签的href[非锚点的方式]等,进行页面访问时,页面会刷新。history可以实现页面不刷新,原理是使用浏览器历史记录,虽然不用再次请求数据,但跟路由区别还是挺大的。
所以现在我们学了vue,改用路由进行无缝跳转。 我的文章:路由的两种模式:hash与history 。
路由原理: 利用锚点来完成切换,页面不刷新。或者另一种说法,根据url不同,来分发不同的页面。
路由的作用:
- 路由:所有的路径都经由这个模块进行重新分配(改变URL,在不重新请求页面的情况下,更新页面视图。)
- 根据 url 锚点路径,在容器中加载不同的模块
- 完成 SPA(单页面应用)的开发
这里用到一个概念 SPA:单页面应用 。
csdn 2019:浅谈前端SPA(单页面应用)
sf 2019:彻底理清前端单页面应用(SPA)的实现原理 【精读源码】(超有价值)
简书 2018:SPA(单页面应用)和MPA(多页面应用)
sf 2015:前端:将网站打造成单页面应用SPA(一)
路由功能引入: 官方推荐 vue-router.js库来引入路由功能模块。但是呢,这都是适用于本地路由开发的。
我们下载既然在用脚手架搭建项目,那就使用脚手架的自动创建路由功能吧。
(一)含路由项目创建流程:
(1)创建一个项目,比如命名为 myrouter
(2)然后选择自定义选项(光标可以切换选项)
(3)选择路由,光标到Router,然后空格选中。
(4)然后剩下的选项,就一路默认回车了。
(5)当下载完成后,打开项目目录,会发现,跟默认项目创建不同的是,src里多了两个文件,分别是router、views。
(6)现在我们进入项目根目录,把项目运行起来:npm run serve。可以发现,我们可以通过新增的 Home|About 来切换页面,这就是路由的演示。(是不是跟选项卡很像)
(二)一级路由配置
用 Vue.js + Vue Router 创建单页面应用,是非常简单的。将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们。
主要分四步:
- 定义 (路由) 组件。
注意:可以使用template模板进行html封装,调用id属性更加方便。 - 定义路由
使用component来进行路由映射组件。name属性是命名路由通过一个名称来标识一个路由。 - 创建 router 实例,然后传
routes
配置。 创建和挂载根实例。
新建一个vue实例,将 router 配置参数注入路由,从而让整个应用都有路由功能。
然后使用<router-link to="/url"></router-link>
标签设置路由跳转(声明式路由导航)。其中to
属性用来设置跳转链接.路由出口
<router-view></router-view>
表明路由模版显示的位置。(系统会把
<router-link></router-link>
这个标签解析成<a></a>
标签)就比如初始页面的切换,看浏览器的代码就是被a标签包裹,而不是router-link。另外得注意,在框架里面写的时候,不能用a标签代替router-link,因为不能解析。
创建路由的过程(总结)
1、创建路由组件页面
2、定义路由的规则
3、脚手架帮我们完成了两步:实例化路由对象,把路由规则传入路由实例化对象中
4、脚手架又帮我们完成了一步:把路由对象注入到vue实例(main.js中创建的vue实例化对象中)
5、创建路由出口 router-view
6、创建路由导航 router-link
>> 自己的第一个一级路由小程序
比如写上面这个小例子,每次点击,不跳转更新页面,跟选项卡很像的功能,但又确实链接地址不同了。
(1)在views文件夹
里,新建单组件页面,是用于路由切换时展示的页面。平常组件怎么写,它就怎么写。然后需要切换几个页面,就建立几个页面。
这里我写了电影、图书、广播、小组
五个不同页面,分别命名为movie.vue / book.vue / broadcast.vue / group.vue
;然后里面展示的东西很简单,只有一个词组:
<template>
<div>
小组
</div>
</template>
(2)在router文件夹
里的index.js
中,路由映射组件。配好后,测试一下。类似于:http://127.0.0.1:3004/group
在index.js文件夹里给那四个页面组件注册路由,一个组件映射一个。
//index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Movie from '../views/movie.vue'
import Book from '../views/book.vue'
import Broadcast from '../views/broadcast.vue'
import Group from '../views/group.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Movie',
component: Movie
},
{
path: '/book',
name: 'Book',
component: Book
},
{
path: '/broadcast',
name: 'Broadcast',
component: Broadcast
},
{
path: '/group',
name: 'Group',
component: Group
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
(3)在全局根组件里面,使用<router-link to="/url"></router-link>
设置路由跳转(设置路由导航,使用路由path,因为已经映射到组件了嘛),和路由出口<router-view/>
。
(4)或者可以将<router-link to="/url"></router-link>
设置路由跳转这块儿,再放到另一个组件里面。
我是把路由导航单独放到了一个组件里面,然后导入到全局根组件,这样做是考虑到以后路由很多的话,不会再根组件里面显得太乱。
//routerlink.vue
<template>
<div class="nav_div">
<router-link to="/">电影</router-link>
<router-link to="/book666">图书</router-link>
<router-link to="/broadcast">广播</router-link>
<router-link to="/group">小组</router-link>
</div>
</template>
<script> export default { } </script>
<style scope> a{ padding: 0 10px; color:#000; text-decoration: none; } a:hover{ color:tomato; } .nav_div{ /* text-align:center;*/ border-bottom:1px solid teal; margin-bottom:10px; } </style>
然后在全局根组件里面写入路由入口,并导入路由导航。
<template>
<div>
<routerlink></routerlink>
<router-view />
</div>
</template>
<script> import routerlink from "@/components/routerlink.vue" export default { components:{ routerlink } } </script>
(5)运行程序。
(三)路由的跳转方式:
1、声明式跳转:使用<router-link to=""></router-link>
(之前练习的小栗子都是声明式跳转方法)
2、编程式跳转:this.$ router.push()
(js使用的跳转方式)
另外还有:
this.$router.replace ("替换的路径");
//也能路由跳转,但是和push的区别是replace跳转完不能回退。它不会向历史url记录中添加新记录,而是替换掉当前的 history 记录。this.$router.go(正数/负数);
//这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。
>> 扩展1——.router-link-active
当 <router-link>
对应的路由匹配成功,会自动设置 class 属性值 .router-link-active
。通过自动设置的类名方便进行路由导航样式设置。比如给导航选中的标签设置背景颜色:
<style scope> .router-link-active{ background: pink; } </style>
就会有下面这种效果:
(四)路由规则通配符匹配问题:*
或者 demo-*
*
代表匹配任意路径,比如当匹配不到正确路径的时候,就走*
下的页面。demo-*
代表匹配任意开头的路径,比如demo开头的全部路由path,匹配到某个页面。
当使用通配符路由时,请确保路由的顺序是正确的,也就是说含有通配符的路由应该放在最后。路由 { path: ‘*’ } 通常用于客户端 404 错误。
比如说下面这种效果:404错误 ; 是当用户乱输入内容时,提示找不到信息 ; 然后我就设置 * 全部匹配,一旦出现这种问题,我就跳转到404页面。
首先我们要先新建一个404页面比如命名为"no404.vue"
,然后去index.js页面里面定义路由规则:
import No404 from '../views/no404.vue'
//路由规则里面配置
{
path: '/*', //通配符路径匹配,放最下面,因为优先级,按定义顺序来匹配
name: 'No404',
component: No404
},
>> 扩展2——路由匹配顺序问题
同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。
(五)路由的重定向:通过router中的redirect属性配置的。
比如下面这个例子,当路由路径匹配到"/"
时,会被重新定位到路径为"/movie"
,而我们从之前的例子中知道,路径”/movie”会展示'../views/movie.vue'
组件页面。
// 路由重定向
{
path:'/', //当路径匹配"/"时,重定向到movie.vue页面
redirect:"/movie"
},
3、多级路由(二级及以上,嵌套路由)
不过现在的APP三级及以上的路由已经很少见了,顶多到二级路由。
>> 多级路由的创建过程:
1、创建多级路由的路由组件页面。
我在views中新建了二级路由索要切换的页面组件,目录结构如下:
里面写的东西很简单,就一行字而已。比如 er1.vue 里写的是 “二级路由 111”。
2、定义路由的规则:
- 二级路由规则定义在一级路由的相关某个规则里面
- 写一个children属性,与一级路由的path等同级
现在我想在图书这个一级路由下插入二级路由,并展示出来。(跟之前一级路由的那个例子联系起来)
先把这3个页面导入到index.js中,然后在book这个一级路由规则中,通过children属性配置二级路由规则。在设置二级路由path时有两种方法,不加”/“,或者加上。
//index.js-------
// 一级路由
import Book from 'vs/book.vue'
// 二级路由
import Er1 from "vs/er/er1.vue"
import Er2 from "vs/er/er2.vue"
import Er3 from "vs/er/er3.vue"
Vue.use(VueRouter)
const routes = [
{
path: '/book',
name: 'Book',
component: Book,
children:[
//path写法一:path:"不加斜杠"
{ path:"er1",name:"Er1",component:Er1},
{ path:"er2",name:"Er2",component:Er2},
//path写法二:path:"加斜杠"
{ path:"/er3",name:"Er3",component:Er3},
]
},
]
//实例化路由对象
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
3、设置二级路由的出口,必须设置在它所依赖的一级路由页面中。
//book.vue------
<template>
<div>
图书
<Erlink/>
<router-view/>
</div>
</template>
<script> import Erlink from "%/erlink.vue" export default { components:{ Erlink } } </script>
4、设置二级路由的路由导航(声明式 || 编程式),然后导入一级路由界面中。
注意:
- 如果在设置路由规则的时候path没有加 “/”,那么在设置< routerlink to=””></ routerlink>的时候,to属性应该写成
"/一级路径/二级路径"
- 如果加了斜杆,to属性应该是
"/二级路由路径"
感觉第一种比较好一些,因为结构很清晰
//erlink.vue———-
//路由规则配置时path:“不加斜杠”
er1
er2
//路由规则配置时path:“加斜杠”
er3
到此为止,运行程序,是能够展现出二级页面的。
但是,却不会自动展示首个二级路由组件的内容。想到了重定向,但有点麻烦,还有没有更简单的方法?可以设置一级路由导航的to属性,更改成二级路由的路径。
//原来的to属性路径
<router-link to="/book">图书</router-link>
//如果index.js配置路由规则的path:"er1",没加斜杠;则更改成如下:
<router-link to="/book/er1">图书</router-link>
//如果index.js配置路由规则的path:"/er3",加斜杠;则更改成如下:
<router-link to="/er3">图书</router-link>
当我们一点开图书一级路由时,就会转到二级路由的相关路径组件页面。
二级路由展示的小栗子就先到这里了。
4、动态路由匹配
- 动态路由也可以叫做路由传参
- 组件的显示内容,经常会根据用户选择的内容不同,在同一个组件中渲染不同内容。那么在这个时候就需要动态路由。
<1> 动态路径参数(路由规则配置时)
- 使用动态路由匹配中的动态路径参数来进行路由配置。
- 动态路径参数以冒号
:
开头
<2> 绑定参数(发送数据参数)
- 声明式路由导航绑定参数有两种方式,但是注意:params只能通过路由配置中的name属性来引用路由
- js方式进行参数绑定
<3> 获取路由传入的参数(获取数据参数)
- 如果想得到路径参数那么使用
$route.params.id
或this.$route.params.id
- 或者是使用this实例中的
this.$route.params.id
进行调用
动态路由–知识点扩展query传参
- 路由参数不需要添加内容
- 路由导航绑定参数的方式
- js方式进行参数绑定
params与query区别
- 用法上的:query要用path来引入,params要用name来引入,接收参数都是类似的,分别是
this.$route.query.name
和this.$route.params.name
。 - url展示上的
- params类似于post,query更加类似于我们ajax中get传参,说的再简单一点,前者在浏览器地址栏中不显示参数,后者显示,所以params传值相对安全一些。
>> 下面我们通过一个小栗子来看一下动态路由传参的具体流程。
(1)创建一个数据展示组件页面,命名为getDate.vue,用于以后获取参数并展示出来。
(2)在index.js中配置路由规则。设置接收参数,在规则里面匹配传递的值。
//index.js-----
import GetData from "vs/getData.vue"
// 动态传参 路由匹配
{
path: '/getdata/:xiaoming',
name: 'GetData',
component: GetData
},
(3)在发送数据的页面绑定参数,比如首页。我这里是movie.vue,用的js方法发送参数。
//movie.vue-----
<template>
<div>
电影------------<br>
<button @click="push1()">点击查看 传递过去的数据</button>
</div>
</template>
<script> export default { methods:{ push1(){ this.$router.push("/getdata/data参数");//发送参数 } } } </script>
(4)在getData.vue页面接收参数并展示数据。
//getData.vue-----
<template>
<div>
<button @click="back()">返回 <</button>
<p>获得的数据1:{
{this.$route.params.xiaoming}}</p>
<!--注意{ {this.$route.params.xiaoming}}里的$route没有r,然后此处也可以写{ {$route.params.xiaoming}}-->
</div>
</template>
<script> export default { methods:{ back(){ this.$router.go(-1);//返回到上一个页面,读取历史记录,不刷新页面 } }, mounted() { console.log(this.$route.params.xiaoming); }, } </script>
到目前为止,简单的参数传递小栗就写到这儿了。
params与query不同方式的总结及代码示例
友友的博客:动态路由传参、vue动态路由与vue路由传参
5、promise
(一)promise是什么?
Promise是一种异步操作的解决方案,将写法复杂的传统的回调函数和监听事件的异步操作,用同步代码的形式表达出来。避免了多级异步操作的回调函数嵌套。
1、主要用于异步计算
2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
3、可以在对象之间传递和操作promise,帮助我们处理队列
简书:Javascript 中的神器——Promise
MDN:Promise 对象用于表示一个异步操作的最终完成 (或失败), 及其结果值.
(二)为什么会有promise
在处理多个有依赖关系的异步操作时,会出现回调地狱,且程序的可读性变差。
(三)如何使用promise
Promise是一个对象,它的内部其实有三种状态。
初始状态( pending )
已完成( fulfilled ): resolve 方法可以使 Promise 对象的状态改变成成功
已拒绝( rejected ): reject 方法则是将 Promise 对象的状态改变为失败
其他
配置解析别名—修改文件夹引用别名
在项目的根路径下vue.config.js的文件中,添加下列代码,configureWebpack与devServer同级。
configureWebpack:{
resolve:{
alias:{
// "自定义别名":"所指向的路径";别名也可以用符号代替,比如&
"com":"@/components"
}
}
}
总结
本篇介绍了axios数据请求封装,一级路由,二级路由,动态路由数据传参,另外还有promise的简介。
也有一些小技巧,比如改变全局跟组件的指向,自定义文件夹引用别名,404页面的路由跳转,路由重定向等。
还没有评论,来说两句吧...