1.数组里面的相同对象去重
reduce()方法接收一个函数作为累加器,数组中的每个值从左到右开始缩减,最终计算为一个值
语法:
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
let arr = [{id:1},{id:2},{id:3},{id:1}]
const hash = {}
arr = arr.reduce((item, next) => { hash[next.id] ? '' : hash[next.id] = true && item.push(next)
return item
}, [])
2.公共方法放入mixins中
在mixins文件中提取公共的方法或者数据
在需要使用公共方法的组件中引入mixins: [mixins]
3.在进行增删改查操作之后刷新页面重新获取列表
使用provide与inject
作用:可以用于父组件向子孙组件传递数据,主要用于刷新vue组件
使用方法:provide在父组件中返回要传给下级的数据,inject在需要使用这个数据的子辈组件或者孙辈等下级组件中注入数据
在app.vue中
<template>
<div
id="app"
>
<router-view
v-if="isRouterAlive"
/>
</div>
</template>
<script>
export default {
name: 'App',
components: {
MergeTipDialog,
BreakNetTip
},
data () {
return {
isShow: false,
isRouterAlive: true
},
// 父组件中返回要传给下级的数据
provide () {
return {
reload: this.reload
}
},
methods: {
reload () {
this.isRouterAlive = false
this.$nextTick(() => {
this.isRouterAlive = true
})
}
}
}
</script>
在需要刷新组件的子组件中引入
//引用vue reload方法
inject: ['reload'],
methods: {
async xxx () {
this.reload()
}
}
4.vue-router中的导航钩子
5.vuex模块化
6.解决vue路由跳转相同的地址,即在当前路由下重复当前路由报错
const routerPush = VueRouter.prototype.push
VueRouter.prototype.push = function push (location) {
return routerPush.call(this, location).catch(error => error)
}
const VueRouterReplace = VueRouter.prototype.replace
VueRouter.prototype.replace = function replace (to) {
return VueRouterReplace.call(this, to).catch(err => err)
}
7.解决vue跳转相同路由时–刷新这个路由
当你重复点击相同的导航,跳转同一个路由,只会跳转一次,重复点击不会刷新
解决方法:
//在路由跳转的时候加上一个时间戳
this.$router.push({
name:"...",
query:{
t: Date.now(),
},
})
然后在router-view
上加上key属性,值为这个时间戳:
<router-view :key="$route.query.t" />
8.nextTick
nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数
https://www.jianshu.com/p/a7550c0e164f
9.节流与防抖
节流函数封装
// 函数的节流适合多次时间按时间做平均分配触发
// 使用场景: 窗口调整,页面滚动,拖拽功能,抢购疯狂点击
function throttle(callback, wait) {
let start = 0;
// 返回的是一个函数
return function(e) {
let now = Date.now()
if (now - start >= wait){
// 将this指向事件源对象
callback.call(this, e)
start = now
}
}
}
使用节流
<script>
window.addEventListener('scroll', throttle(function(e){
console.log(Date.now())
}, 500))
</script>
防抖函数封装
// 使用场景:表单输入
// 函数防抖
function debounce(callback, wait) {
let timeId = null;
return function(e) {
if(timeId !== null) {
clearInterval(timeId)
}
timeId = setTimeout(()=> {
callback.call(this, e)
// 重置定时器变量
timeId = null
}, wait)
}
}
<script>
let input = document.querySelector('input')
input.onkeydown = debounce(function(e) {
console.log(e.keyCode);
},1000)
</script>
10.想修改vant样式,使用sass-loader 下使用 /deep/ 失效,则使用::v-deep代替
.type-4{
width: 100%;
::v-deep img{
width: 100% !important;
}
}
11.使用computed计算属性进行传参
需求,根据传递过来的宽高比,进行宽高的重新计算
computed:{
imgWD(o){
return function(o){
return {
width:'370px',
height:370*(1/o) + 'px'
}
}
}
}
<div :style="imgWD(item.crown)" class="img-detail">
<image resize='stretch' class="itemPhoto" :src="imgUrl + item.photoName"></image>
</div>
12.封装axios
13.keepAlive的使用
https://www.cnblogs.com/mary-123/p/11248178.html
14.grid布局
https://wudi98.blog.csdn.net/article/details/93379228?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.control&dist_request_id=c8b220c5-016f-461e-ab43-f264a6e7207b&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.control
15.微信小程序云开发踩坑点
当要修改数据库中数据的状态,使用数据库原生的update方法没法修改成功,会导致stas里update状态为零修改失败,必须使用云函数去修改状态,如收藏,点赞状态的改变
16.关于“异步加载css”的相关思考,以及实现方式
https://blog.csdn.net/weixin_38129930/article/details/101444305
17.[‘1’, ‘2’, ‘3’].map(parseInt)
输出为[1,NaN,NaN]
//注意点: Number()和parseInt()的区别
18.defer, async作用的区别分析
https://segmentfault.com/a/1190000017257370?utm_source=tag-newest
19.跨域问题
原因:浏览器的同源策略导致跨域,当请求接口的协议,域名和端口号与被请求的协议,域名,端口号不同时,就会产生跨域问题
https://segmentfault.com/a/1190000015597029
20.cookie和session的区别
https://www.cnblogs.com/l199616j/p/11195667.html
21.vue全局前置守卫引起的死循环与解决方法
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
}
)
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。
每个守卫方法接收三个参数:
-
to: Route
: 即将要进入的目标 路由对象 -
from: Route
: 当前导航正要离开的路由 -
- 一定要调用该方法来
next: Function
resolve
这个钩子。执行效果依赖
next
方法的调用参数。
next()
: 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。next(false)
: 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到from
路由对应的地址。next('/')
或者next({ path: '/' })
: 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向next
传递任意位置对象,且允许设置诸如replace: true
、name: 'home'
之类的选项以及任何用在router-link
的to
prop 或router.push
中的选项。next(error)
: (2.4.0+) 如果传入next
的参数是一个Error
实例,则导航会被终止且该错误会被传递给router.onError()
注册过的回调。
确保要调用 next
方法,否则钩子就不会被 resolved
错误方法:
如果sessionStorage有token,并且如果即将要进入的目标路径是登陆页,就跳转到/dashboard页,如果是其它的页面,就进入
如果sessionStorage没有token 就进入登陆页
这样会引起死循环,因为每次路径变化时,会再次执行前置导航守卫
router.beforeEach((to,from,next) =>{
if (sessionStorage.getItem("token")) {
if(to.path === "/login"){
next({path:"/dashboard"})
}
else{
alert("1")
next()
}
}else{
next({path: "/login"}) // 会再次执行前置导航守卫,因为路径变化
}
})
正确方法:
router.beforeEach((to, from, next) => {
let token = window.sessionStorage.getItem('token');
if (to.path != '/login' && !token) {
next({
path: '/login'
})
} else {
if (to.path == '/login' && token) {
next('/dashboard')
} else {
next()
}
}
})