Vue.js note9(脚手架:数据请求封装&一级路由&二级路由&动态路由传参&路由重定向)

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 Locationwindow的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 在哪里渲染它们。

主要分四步:

  1. 定义 (路由) 组件。
    在这里插入图片描述
    注意:可以使用template模板进行html封装,调用id属性更加方便。
    在这里插入图片描述
  2. 定义路由
    使用component来进行路由映射组件。name属性是命名路由通过一个名称来标识一个路由。
    在这里插入图片描述
  3. 创建 router 实例,然后传 routes 配置。
    在这里插入图片描述
  4. 创建和挂载根实例。
    新建一个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)。
    在这里插入图片描述
<template>
  <div class="nav_div">
    <h1>声明式路由导航</h1>
    <router-link to="/movie">电影</router-link>
    <router-link to="/book">图书</router-link>
    <router-link to="/broadcast">广播</router-link>
    <router-link to="/group">小组</router-link>
    <h1>编程式路由导航</h1>
    <button @click="fun(1)">电影</button>
    <button @click="fun(2)">图书</button>
  </div>
</template>

<script>
export default {
  methods: {
    fun(num) {
      switch (num) {
        case 1:
          // 跳转到电影
          // 使用编程式导航进行跳转
          this.$router.push("/movie");
          break;
        case 2:
          this.$router.push("/book");
          break;
      }
    }
  }
};
</script>

在这里插入图片描述

>> 扩展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-------

<template>
    <div class="er">
    	//路由规则配置时path:“不加斜杠”
        <router-link to="/book/er1">er1</router-link >
        <router-link to="/book/er2">er2</router-link >
        //路由规则配置时path:“加斜杠”
        <router-link to="/er3">er3</router-link >
    </div>
</template>

<style scope>
    .er .router-link-active{
        background: teal;
        color:white;
    }
</style>

到此为止,运行程序,是能够展现出二级页面的。
在这里插入图片描述
但是,却不会自动展示首个二级路由组件的内容。想到了重定向,但有点麻烦,还有没有更简单的方法?可以设置一级路由导航的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.idthis.$route.params.id
    在这里插入图片描述
  • 或者是使用this实例中的this.$route.params.id进行调用
    在这里插入图片描述
动态路由–知识点扩展query传参
  • 路由参数不需要添加内容
    在这里插入图片描述
  • 路由导航绑定参数的方式
    在这里插入图片描述
  • js方式进行参数绑定
    在这里插入图片描述
params与query区别
  • 用法上的:query要用path来引入,params要用name来引入,接收参数都是类似的,分别是this.$route.query.namethis.$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()">返回 &lt;</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页面的路由跳转,路由重定向等。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值