router

nanoid的使用

​ --生成随机id

引入

yarn add nanoid

使用

import {nanoid} from 'nanoid'var id = nanoid()

路由

1-1 安装依赖

yarn add vue-router

1-2 引入

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import Movie from '../pages/Movie/index.vue'
import Music from '../pages/Music/index.vue'
const routes = [{path:"/music",component:Music},{path:"/movie",component:Movie}
]const router = new VueRouter({routes,mode:"history"
})
export default router;

1-3 在main.js中使用

import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = falsenew Vue({router,render: h => h(App),
}).$mount('#app')

1-4 App.vue

<template><div><router-view></router-view></div>
</template>

全局过滤器

在main.js中挂载在Vue原型上

Vue.filter("handleStr",function(val){if(val.length > 3){val = val.slice(0,3) + '...'}return val
})

element-ui

安装依赖

yarn add element-ui

main.js

....
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
...

全局组件

import Loading from '../components/Loading.vue'
Vue.component("Loading",Loading)

Vuc-cli中的视配

只在手机端

lib-flexible 阿里

1-1 安装依赖

yarn add lib-flexible postcss-pxtorem@5.1.1

1-2 配置文件

新建postcss.config.js

module.exports = {plugins: {'postcss-pxtorem': {rootValue: 75,propList: ['*'],},},
};

1-3 main.js

导入lib-flexible

import 'lib-flexible/flexible.js'

1-4 public/index.html

将此行注释,关闭视口

<meta name="viewport" content="width=device-width,initial-scale=1.0">

1-5 在pc端视配

<template><div id="app">...</div>
</template><script>...
</script><style>
*{margin: 0;padding: 0;
}
#app{width: 10rem;margin: 0 auto;background-color: red;
}
</style>

slot封装动画

// #1 定义一个组件
<template><transition><slot name="fade"></slot></transition>
</template><script>
export default {}
</script><style>
.v-enter,.v-leave-to{opacity: 0;
}
.v-enter-active,.v-leave-active{transition: opacity 4s;
}
</style>
// #2 使用
<template><div class="about"><Fade><h1 slot="fade" v-show="isShow">This is an about page</h1></Fade></div>
</template><script>
import Fade from '../components/Fade.vue'
export default {data() {return {isShow:true}},components:{Fade}
}
</script>

项目初始化

1、rem
2、asssreset.css

1-1 .router-link-active

被选中的路由样式

.router-link-active{color: #ff2d51;}

1-2 动态显示tabbar

​ – 在路由配置中增加一条meta属性

const routes = [{path: '/films',name: 'Films',component:Films,meta:{isNav:true}},{path: '/article',name: 'Article',component:Article,meta:{isNav:true}},{path: '/center',name: 'Center',component:Center,meta:{isNav:true}},{path:"/movie/:id",name:'MovieDetail',component:MovieDetail}
]

通过v-if动态显示

<tab-bar v-if="this.$route.meta.isNav"></tab-bar>

1-3 跳转回前一个页面

this.$router.back()

1-4轮播

yarn add vue-preview
import VuePreview from 'vue-preview'
Vue.use(VuePreview)

vant ui的按需导入

1-1 安装依赖

yarn add vant babel-plugin-import

1-2 配置babel.config.js

module.exports = {presets: ['@vue/cli-plugin-babel/preset'],plugins: [["import", {"libraryName": "vant","libraryDirectory": "es","style": true}]]
}

1-3 配置main.js

import {Button} from 'vant'
Vue.use(Button)

router-view实现动画

<template><div><div class="cover" v-if="isShow"></div><transition @before-enter="handleBeforeEnter"@enter="handleEnter"><slot></slot></transition></div>
</template><script>
/*
.v-enter              @before-enter
.v-ernter-active      @enter
.v-enter-to           @after-enter
*/export default {data() {return {isShow:false}},methods:{handleBeforeEnter(){this.isShow = true},handleEnter(){setTimeout(() => {this.isShow = false}, 200);}}}
</script><style>.v-enter-active{animation: animate 2s linear;}@keyframes animate {0%{opacity: 0;transform: translateY(0px);}50%{opacity: .5;transform: translateY(20px);}100%{opacity: 1;transform: translateY(0px);}}.cover{width: 100%;height: 100%;background-color: #fff;position: fixed;z-index: 10;}
</style>

嵌套路由

1-1 router.js

 {path: '/films',name: 'Films',component:Films,meta:{isNav:true},children:[{path:"nowPlaying",component:NowPlaying}]},

1-2 index.vue

需要加入router-view

<template>...<div class="container"><!-- 装载父路由下的子路由的对应 --><router-view></router-view></div>
</template>

异步路由

​ --又称路由懒加载

{path: '/about',name: 'About',// 异步路由component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
},

怎么减少首屏渲染时间

1、使用异步路由

页面跳转和生命周期

​ --面试常客

页面跳转

1-1 A页面初次加载

beforeCreate(){console.log('beforeCreate');
},
created(){console.log('created');
},
beforeMount(){console.log('beforeMount');
},
mounted(){console.log('mounted');
},

1-2 A->B

从A页面跳转到B页面

A页面触发以下生命周期

beforeDestroy(){console.log('beforeDestroy');
},
destroyed(){console.log('destroyed');
}

1-3 B–>A

从B页面回到A页面

A页面触发以下生命周期

beforeCreate(){console.log('beforeCreate');
},
created(){console.log('created');
},
beforeMount(){console.log('beforeMount');
},
mounted(){console.log('mounted');
},

upDate

beforeUpdate , beforeUpdate执行需要满足以下两个条件

1、data中的数据更新的时候
2、模板中要使用data中的数据

destroyed

# A页面 --> b页面
b页面执行以下生命周期:1.beforeCreate       B
2.created           B
3.beforeMount       B
4.beforeDestroy     A
5.destroyed         A
6.mounted           B

DOM和生命周期

只能在mounted生命周期中获取DOM

缓存的进一步封装

localStorage.setItem() 函数会将对象或者数组全部转换成字符串的形式

所以可以对缓存进行判断,使用 JSON.stringifyJSON.parse 分别处理数据

const setLocalStorage = (key , value) => {if(value instanceof Array || value instanceof Object){value = JSON.stringify(value)}localStorage.setItem(key , value)
}const getLocalStorage = (key) =>{var val = localStorage.getItem(key)var reg = /^[[{].*[\]}]/if(reg.test(val)){val = JSON.parse(val)}return val
}

axios

跨域

安装依赖

yarn add axios-jsonp

axios格式

import axios from 'axios'
import jsonpAdapter from 'axios-jsonp'axios({url:"",adapter: jsonpAdapter,
}).then(res => console.log(res)
)

腾讯地图api需要在最后加上 &output=jsonp

https://apis.map.qq.com/ws/location/v1/ip?key=L6UBZ-JSLCU-FRAVA-4DBQG-V5WC5-2RBJ4&output=jsonp

地址值的放置

http://47.108.197.28:3000/top/playlist?limit=1&offset=1

在小程序中

wx.request({})

axios中

import axios from 'axios'axios({url:"http://47.108.197.28:3000/top/playlist",method:"get",params:{limit:1}
}).then(res=>{console.log(res)
})

Vuex

import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({state: {},mutations: {},actions: {},modules: {}
})

1、state

​ --state中存放的是数据

state: {num:10
}
this.$store.state

2、mutation

​ --mutation中的函数第一个默认参数是state

​ --连接方式 commit

mutations: {add(state){console.log(state);state.num++;}
},
this.$store.commit('add')

3、actions

​ --actions中的函数第一个默认值是上下文

​ --连接方式 dispatch

actions: {addNum(ctx){console.log(ctx);ctx.commit("add")}
},
this.$store.dispatch('a')

keep-alive

使用keep-alive之后,路由切换的时候,生命周期函数不会重复的触发
组件不会被销毁,而是被缓存起来。当加载到对应的路由页面,缓存的组件会被加载

路由组件的两个生命周期函数

/* 路由组件被激活时触发。 */
activated(){console.log('activated')
}
/* 路由组件失活时触发。 */
deactivated(){console.log('deactivated')
}

路由守卫

全局路由守卫

router.beforeEach((to , from ,next)=>{console.log(to);    // 要跳转的路由console.log(from);  // 起点路由next();
})

Login_guard(Vue&koa)

一、登录页面

<template><div><el-form:model="ruleForm"status-icon:rules="rules"ref="ruleForm"label-width="100px"class="demo-ruleForm"><!-- props为了规则校验 rules --><el-form-item label="用户名" prop="username"><el-input  type="text" v-model.number="ruleForm.username"></el-input></el-form-item><el-form-item label="密码" prop="pass"><el-inputtype="password"v-model="ruleForm.pass"autocomplete="off"></el-input></el-form-item><el-form-item label="确认密码" prop="checkPass"><el-inputtype="password"v-model="ruleForm.checkPass"autocomplete="off"></el-input></el-form-item><el-form-item><el-button type="primary" @click="submitForm('ruleForm')">提交</el-button><el-button @click="resetForm('ruleForm')">重置</el-button></el-form-item></el-form></div>
</template>
<script>
export default {// beforeRouteEnter () {//   /* 在局部守卫中获取不到this *///   console.log(1);// },data() {var checkUsername = (rule, value, callback) => {if (!value) {return callback(new Error("用户名不能为空"));}else{callback();}};var validatePass = (rule, value, callback) => {if (value === "") {callback(new Error("请输入密码"));} else {if (this.ruleForm.checkPass !== "") {this.$refs.ruleForm.validateField("checkPass");}callback();}};var validatePass2 = (rule, value, callback) => {if (value === "") {callback(new Error("请再次输入密码"));} else if (value !== this.ruleForm.pass) {callback(new Error("两次输入密码不一致!"));} else {callback();}};return {ruleForm: {pass: "",checkPass: "",username: "",},rules: {pass: [{ validator: validatePass, trigger: "blur" }],checkPass: [{ validator: validatePass2, trigger: "blur" }],username: [{ validator: checkUsername, trigger: "blur" }],},};},methods: {submitForm(formName) {this.$refs[formName].validate((valid) => {if (valid) {// alert("submit!");// console.log(this.ruleForm);// console.log(username,pass);/* 发送http请求 */this.loginHttp()} else {console.log("error submit!!");return false;}});},resetForm(formName) {this.$refs[formName].resetFields();},loginHttp(){var {username , pass} = this.ruleFormthis.$http({method: 'post',url:'http://localhost:8000/login',data:{username,pass}}).then(res=>{console.log(res.data);if(res.data.code == 200){this.$message({message:res.data.msg,type:"success",duration:1000})this.$router.push('/home')}else{this.$message({message:res.data.msg,type:"warning",duration:1000})}})}}};
</script>

二、后台代码

const koa = require("koa");
const app =  new koa();
const koaBody = require("koa-body");
const router = require("koa-router")();
const cors = require("koa2-cors");/* username=cheng  pass=123456 */console.log(ctx.request.body);var {username , pass } = ctx.request.bodyif(username == "cheng" && pass == "123456"){ctx.cookies.set("loginAuth",true,{/* httpOnly:false   设置前端可读 */httpOnly:false})ctx.body = {code:200,msg:"登录成功"}}else{ctx.body = {code:400,msg:"登录失败,用户名或密码错误"}}
})
/* 后端配置cookie可以实现跨域访问 */
app.use(cors({origin:ctx =>{return ctx.headers.origin},credentials:true
}));
app.use(koaBody());
app.use(router.routes());
app.listen(8000);

三、配置cookie跨域访问

3-1 配置后端cookie可以访问

/* 后端配置cookie可以实现跨域访问 */
app.use(cors({origin:ctx =>{return ctx.headers.origin},credentials:true
}));

3-2 配置前端跨域访问cookie

import axios from 'axios'
/* 设置前端跨域访问cookie */
axios.defaults.withCredentials = true
axios.defaults.crossDomain = true

3-3 vue上获取cookie

安装依赖

yarn add vue-cookie

配置main.js

import VueCookie from 'vue-cookie'
Vue.use(VueCookie)

在页面中获取cookie

mounted() {console.log(this.$cookie.get('loginAuth'));
}

3-4 路由守卫

​ --没有登录的情况下,不能进入其它页面

​ --已经登录的情况下,直接进入首页

var vm = new Vue();
router.beforeEach((to,from,next)=>{console.log(vm.$cookie.get('loginAuth'));var isLogin = vm.$cookie.get('loginAuth')if(to.path == "/login"){/* 1、登录页面,如果cookie显示登录了直接进入home页面,如果没有登录,正产执行login页的逻辑 */if(isLogin){router.push('/home')}else{next()}}else{/* 2、在其他页面,如果登录正常显示,没有登录则停留在login页面 */if(isLogin){next()}else{router.push('/login')}}
})

懒加载

1、图片懒加载

1、安装依赖
yarn add vue-lazyload
2、在main.js中进行配置import VueLazyLoad from 'vue-lazyload'Vue.use(VueLazyLoad,{preLoad:1.3,loading:require('@/assets/loading.gif')
})
3、使用(将:src替换成v-lazy)
<template><div class="home"><div  v-for="item of playlists" :key="item.id"><img  class="item" v-lazy="item.coverImgUrl" alt=""><p>{{item.name}}</p></div></div>
</template>

2、axios拦截器

​ --实现loading的加载效果

1、在vuex中定义一条isShowLoading    -->  设置加载条是否显示export default new Vuex.Store({state: {isSowLoading:true},
})
2、main.js// 配置 请求拦截 和 响应拦截
// 添加请求拦截器
axios.interceptors.request.use(function (config) {// 在发送请求之前做些什么store.state.isSowLoading = truereturn config;
});// 添加响应拦截器
axios.interceptors.response.use(function (response) {// 2xx 范围内的状态码都会触发该函数。// 对响应数据做点什么store.state.isSowLoading = falsereturn response;
});
3、App.vue设置loading<template><div id="app"><Loading v-if="this.$store.state.isShowLoading"/><router-view/></div>
</template>

3、上拉刷新

vant-ui 中整合了小程序中的 onBottom 和 onLoad

<template><div class="home"><van-listclass="home"v-model="loading":finished="finished"finished-text="没有更多了"@load="onLoad"><van-cell @click="handleClick(item.id)" v-for="item of playlists" :key="item.id"><img class="item" v-lazy="item.coverImgUrl" alt=""><p>{{item.name}}</p></van-cell></van-list></div>
</template><script>
export default {name: 'Home',data() {return {playlists:[],loading:false,finished:false}},mounted() {},methods: {onLoad(){setTimeout(()=>{var offset = this.playlists.lengthconsole.log(1);this.axios.get(`http://47.108.197.28:3000/top/playlist?offset=${offset}&limit=20`).then(res =>{var playlists = this.playlists.concat(res.data.playlists)this.playlists = playliststhis.loading = false})},500)},handleClick(id){this.$router.push(`detail?id=${id}`)}},
}
</script><style scoped>.item{width: 150px;height: 150px;}.home{display: flex;justify-content: space-between;flex-wrap: wrap;}.van-cell{width: 150px;}.home >>> .van-list__loading{position: fixed;bottom: 0;left: 50%;transform:translateX(-50%);}
</style>

4、路由滚动记录当前滚动条位置问题

​ 在路由设置中,重置滚动条的x,y

const router = new VueRouter({...scrollBehavior (to , from , savedPosition) {if( to.path == "/detail"){return {x:0,y:0} // 让页面出于顶部}else{return savedPosition    // 让页面出于记录点}}
})

Vue路由跳转的bug

项目中遇到如下报错内容:Uncaught (in promise) Error: Redirected when going from “/XXX” to “/XXX” via a navigation guard.

原因:vue-路由版本更新产生的问题,导致路由跳转失败抛出该错误,但并不影响程序功能

在main.js中改变push原型

import Router from 'vue-router'
const originalPush = Router.prototype.push
Router.prototype.push = function push(location, onResolve, onReject) {if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)return originalPush.call(this, location).catch(err => err)
}

VueRouter导入相关推荐

  1. vue-router导入视图文件方式与打包参数的差异

    vue-cli-service在打包webpack项目时,由于vue router导入视图文件的写法不同,打包的参数npm run build:dev | npm run build:prod引起的页 ...

  2. vue-router 的基本使用

    vue-router 的基本使用 1. 什么是 vue-router vue-router 是 vue.js 官方给出的路由解决方案.它只能结合 vue 项目进行使用,能够轻松的管理 SPA 项中组件 ...

  3. Vue.js-Day05【安装路由(vue-router)、如何使用vue-router、404配置、激活class、动态路由、编程式导航、路由嵌套、路由元信息、导航拦截】

    Vue.js实训[基础理论(5天)+项目实战(5天)]博客汇总表[详细笔记] 目   录 1.单页面应用 1.1.多页面应用 1.2.单页面应用 1.3.vue-router 2.安装vue-rout ...

  4. vue --- 使用vue-router获取带参数的路由

    希望的效果如下: 2个路由: 点击如下 步骤. 使用 router-link 来指定路由路径 在router.js中指定 路径的 事件处理函数(对应的组件) 创建对应的组件 router-link 找 ...

  5. vue-router 路由跳转

    vue-router 1.为什么要路由 2.路由配置 3.使用路由 1.为什么要路由 1. 用于组件与组件之间的跳转 2. 页面跳转 3. 参数传值 2.路由配置 main.vue content.v ...

  6. Vue2:官方路由 Vue-Router 3.x

    前端路由 前端路由:根据不同的url地址,页面上展示不同的内容(根据url地址的不同分发到不同的组件.) SPA 介绍 spa 是 single page application 简写,意思是单页面应 ...

  7. angularjs 让当前路由重新加载_Vuerouter(路由)

    Vue-router(路由) 01 一.什么是路由? 说起路由你想起了什么? 路由器,那路由器是用来做什么的,你有没有想过? - 路由时决定数据包从来源到目的地的路径: - 将输入端的数据转移到合映射 ...

  8. Luffy之Xadmin以及首页搭建(轮播图,导航)

    1. 首页 1.1 轮播图 admin站点配置支持图片上传 pip install Pillow 默认情况下,Django会将上传的图片保存在本地服务器上,需要配置保存的路径.我们可以将上传的文件保存 ...

  9. Vue — 第七天(vue-cli-案例)

    资料获取地址: github: https://gitee.com/wang_yu5201314/VUE_vuecli SSH: git@gitee.com:wang_yu5201314/VUE_vu ...

最新文章

  1. CSS:响应式下的折叠菜单(条纹式)
  2. Deep Learning 中文翻译
  3. Linux中3个文件查找相关命令
  4. 张帅用赢球庆生 搭档斯托瑟晋级澳网女双八强
  5. 【使用指南】WijmoJS 前端开发工具包
  6. XDOJ-1002-小W的塔防(dp)
  7. 水滴公司更新招股书:发行价区间为10-12美元
  8. Selenium alert 弹窗处理
  9. 【学习总结】Git学习-参考廖雪峰老师教程十-自定义Git
  10. 【转载】]基于RedHatEnterpriseLinux V7(RHEL7)下SPEC CPU 2006环境搭建以及测试流程 介绍、安装准备、安装、config文件以及运行脚本介绍...
  11. [XHTML Tutorial] 走向XHTML标准 (4)(XHTML Syntax)
  12. Hark的数据结构与算法练习之地精(侏儒)排序
  13. 组态王总结之——数据库功能
  14. 手机详情 html代码生成器,dede源码最新版手机移动端静态生成模块插件
  15. Pyhton爬小说实例解析笔记——爬虫基础
  16. android 倒影图片的生成
  17. 给你三个必须要学C语言的理由!
  18. 铁流:中国突破半导体新工艺研发
  19. 加速应用开发 | Firebase Summit 2021 精彩回顾
  20. linux 配置 ftp 服务器以及 ftp 客户端登录

热门文章

  1. 【USACO Open11】forgot
  2. centos7 mini 版虚拟机基础安装配置 (含网络)
  3. 手机点餐系统概述_点餐管理系统测试.概要.docx
  4. 中秋之夜——随笔杂谈
  5. MySQL学习博客第一篇
  6. 《七十七天》中逼真到你无法察觉的奇妙特效
  7. Linux下poky编译1
  8. IT方面学习交流群推荐
  9. 《Image-to-Image Translation with Conditional Adversarial Networks》文章翻译
  10. iso管理体系认证条件