vue-day07
1-路由
1.1-嵌套路由
-
定义路由规则
router/index.js
// 3-定义路由规则 const routes=[ // 嵌套路由 { path:'/login', component:Login, children:[ { path:'/login/enterprise', component: Enterprise }, { path:'/login/user', component: User } ] } ]
-
添加导航链接和二级路由出口
pages/Login.vue
<div> <h1> Login组件 </h1> <hr> <router-link class="btn" to="/login/user">普通用户</router-link> <router-link class="btn" to="/login/enterprise">企业用户</router-link> <hr> <!-- 二级路由的占位符 --> <router-view></router-view> </div>
1.2-路由导航守卫
1.2.1-全局守卫
全局前置导航守卫
-
可以监听到所有的页面跳转
-
具备拦截页面跳转的功能
router.beforeEach((to,from,next)=>{ // 需要手动调用next, 否则所有页面将无法跳转 console.log(to); if(to.path==='/order'){ // 可以使用next进行路由重定向 alert('暂无权限'); return next('/home'); } next(); // 设置页面标题 document.title=to.meta.title+"-后台管理系统"; });
全局解析守卫
-
可以监听到所有的页面跳转
-
具备拦截页面跳转的功能
-
是在全局前置守卫执行之后, 才执行
// 全局解析守卫 // to: 即将要前往的路由对象 // from: 即将要离开的路由对象 // next: 路由跳转方法 router.beforeResolve((to,from,next)=>{ console.log('beforeResolve'); next(); });
全局后置钩子
-
不具备拦截页面跳转的功能
-
在页面跳转完成之后, 才执行
// 全局后置钩子 // to: 即将要前往的路由对象 // from: 即将要离开的路由对象 router.afterEach((to, from) => { console.log('afterEach'); })
1.2.2-路由独享守卫
-
只针对某条路由规则起作用
-
具备拦截页面跳转的功能
{ name:'goods', path:'/goods', component:Goods, meta:{ title:'商品管理' }, // 路由独享守卫 beforeEnter: (to, from, next) => { console.log('beforeEnter'); next(); } },
1.2.3-组件内的守卫
-
beforeRouteEnter: 在渲染该组件的对应路由前
export default { beforeRouteEnter:(to, from, next)=>{ // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当守卫执行前,组件实例还没被创建 console.log('beforeRouteEnter'); // vm组件实例, 系统自动注入 next(vm => { // 通过 `vm` 访问组件实例 console.log(vm); }) } }
-
beforeRouteUpdate: 动态路由参数更新时
export default { beforeRouteUpdate (to, from, next) { // 在当前路由改变,但是该组件被复用时调用 // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 // 可以访问组件实例 `this` console.log('beforeRouteUpdate'); next(); } }
-
beforeRouteLeave: 导航离开该组件的对应路由时调用
export default { beforeRouteLeave (to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` console.log('beforeRouteLeave'); next(); } };
1.3-页面滚动处理
-
自动重置页面滚动条的位置
// 4-创建路由对象 const router=new VueRouter({ routes, mode:'hash', linkActiveClass:'active', // 自动重置页面滚动条的位置 scrollBehavior(){ return {x:0,y:0} } });
1.6-使用嵌套路由改造后台管理系统
-
路由文件
router/index.js
// 1-导入路由模块 import Vue from 'vue'; import VueRouter from 'vue-router'; // 2-注册插件 Vue.use(VueRouter); // 3-配置路由规则数组 const Layout=()=>import('./pages/Layout'); const Home=()=>import('./pages/Home'); const Goods=()=>import('./pages/Goods'); const User=()=>import('./pages/User'); const Order=()=>import('./pages/Order'); const Cate=()=>import('./pages/Cate'); const routes=[ // 路由重定向 { path:'/', component:Layout, children:[ { name:'home', path:'/home', component:Home, meta:{ title:'管理中心' } }, { name:'goods', path:'/goods', component:Goods, meta:{ title:'商品管理' }, // 路由独享守卫 beforeEnter: (to, from, next) => { console.log('beforeEnter'); next(); } }, { name:'user', path:'/user', component:User, meta:{ title:'会员管理' } }, { name:'order', path:'/order', component:Order, meta:{ title:'订单管理' } }, { name:'cate', path:'/cate', component:Cate, meta:{ title:'商品分类管理' } } ] } ]; // 4-创建路由对象 const router=new VueRouter({ routes, mode:'hash', linkActiveClass:'active' }); // 导出路由对象 export default router;
-
根组件
App.vue
<template> <!-- 必须有一个唯一的根标签 --> <div id="app"> <!-- 一级路由占位符 --> <router-view></router-view> </div> </template> <script> export default { } </script> <style> *{ padding: 0; margin: 0; box-sizing: border-box; } html,body{ height: 100%; } #app{ height: 100%; } </style>
-
布局组件
Layout.vue
<template> <div class="layout-container"> <div class="left"> <!-- aside侧边栏 --> <Aside /> </div> <div class="right"> <!-- 头部 --> <Header /> <!-- 主体内容 --> <div class="content"> <!-- 二级路由占位符 --> <router-view /> </div> <!-- 底部 --> <Footer /> </div> </div> </template> <script> // 导入组件 import Header from "@/components/Header"; import Footer from "@/components/Footer"; import Aside from "@/components/Aside"; export default { // 注册组件 components: { Header, Footer, Aside } }; </script> <style> .layout-container { height: 100%; display: flex; } .left { width: 226px; height: 100%; background: #000; color: #fff; } /* 导航样式 */ .navbar li { height: 50px; line-height: 50px; text-align: center; } .navbar li:hover { background: #0078b9; cursor: pointer; } /* 定义一个导航高亮类名 */ .active { background: #0078b9; cursor: pointer; } .right { flex: 1; height: 100%; background: #eee; display: flex; flex-direction: column; } .content { flex: 1; background: #fff; margin: 10px; padding: 10px; } </style>
2-axios
2.0-原生js发送ajax请求的步骤
-
创建一个XMLHttpRequest对象
const xhr=new XMLHttpRequest();
-
设置请求行
xhr.open('请求方式','数据接口地址');
-
发送请求
xhr.send();
-
监听服务端的响应
xhr.onreadystatechange=function(){ if(xhr.status===200&&xhr.readyState===4){ // 获取XML console.log(xhr.responseXML); // 获取json或者普通字符串 console.log(xhr.responseText); } }
2.1-axios的介绍
- 第三方的http类库
- 底层基于ES6中promise进行封装的
- 底层依然基于XMLHttpRequest异步对象
2.1.1-安装
npm i axios -S
2.2-axios发送数据请求
2.2.1-get请求
-
通过axios发送get请求
axios({ method: 'GET', // 请求方式 url: '/user', // 接口地址 params:{ // get请求参数 name:'zs', age:20 } }).then(res=>{ // 成功处理函数 console.log(res); })
-
通过axios.get()方法发送get请求
axios.get('数据接口地址',{ // get请求的参数 params:{ name:'zs', age:20 } }).then(res=>{ // 成功处理函数 console.log(res); })
2.2.1-post请求
-
通过axios发送post请求
axios({ method: 'POST', // 请求方式 url: '/user', // 接口地址 data:{ // post请求参数, 请求体 name:'zs', age:20 } }).then(res=>{ // 成功处理函数 console.log(res); })
-
axios.post
axios.post('数据接口地址',{ name:'' // 请求体 }).then(res=>{ // 成功处理函数 console.log(res); })
2.3-拦截器
2.3.1-请求拦截器
-
对所有的请求都会进行拦截
axios.interceptors.request.use(function(config){ console.log(config,'interceptors.request'); // 自定义的请求头 config.headers.auth='abcd'; return config; })
2.3.2-响应拦截器
-
对服务端的每一次响应进行拦截
axios.interceptors.response.use(function(response){ console.log(response,'interceptors.response'); if(response.status===200){ return response.data } return response; });
2.4-axios的全局配置
-
全局配置基础域名(baseURL)
axios.defaults.baseURL='http://localhost:3333'
-
配置请求头
axios.defaults.headers.自定义请求头="请求头内容"
2.5-axios.all()方法
-
all方法不能通过axios.create方法创建的实例对象调用
-
批量发送数据请求
import axios from 'axios'; export default { created(){ // 使用axios.all批量发送数据请求 axios.all([this.getBrand1(),this.getBrand2()]).then(res=>{ console.log(res); }) }, methods:{ async getBrand1(){ const res=await this.$http.get(`/brandDetail/23`); return res; }, async getBrand2(){ const res=await this.$http.get(`/brandDetail/22`); return res; } } };
2.6-axios.create()方法
-
创建一个axios的实例对象
import Vue from 'vue'; import axios from 'axios'; import VueRouter from 'vue-router'; // 创建一个实例 const instance=axios.create({ baseURL:'http://localhost:3333', headers:{ token:'123456abc' } }); // 请求拦击器 instance.interceptors.request.use(function(config){ console.log(config); return config; }); // 响应拦截器 instance.interceptors.response.use(function(response){ console.log(response); return response.data; }); // 将axios的实例挂在到vue的原型对象上 Vue.prototype.$http=instance; // 导出 export default instance;
3-测试数据接口服务器的搭建
-
下载
brand-api-server.zip
-
解压
-
在项目根目录打开命令行, 安装项目依赖
npm i
-
导入数据库备份文件
-
修改项目配置文件, 打开
/db/index.js
const mysql = require('mysql') // 配置文件 const sqlConfig={ host: 'localhost', database: 'brand_db', // 数据库名称 user: 'root', // mysql用户名 port:3306, // 监听端口号 password: 'root', // mysql密码 // 开启执行多条Sql语句的功能 multipleStatements: true }
-
启动项目
- 数据接口服务器访问地址:
http://localhost:3333/
npm start
- 数据接口服务器访问地址: