vue实用技巧
一、路由缓存 keepalive
keep-alive 是 Vue 提供的一个抽象组件,用来对组件进行缓存,从而节省性能,由于是一个抽象组件,所以在 v 页面渲染完毕后不会被渲染成一个 DOM 元素。
<keep-alive> <router-view></router-view> </keep-alive>
当组件在 keep-alive 内被切换时组件的 activated、deactivated 这两个生命周期钩子函数会被执行
1. 使用参数include/exclude
- include: 字符串或正则表达式。只有匹配的组件会被缓存。
- exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存。
<keep-alive include="a,b"> <router-view></router-view> </keep-alive> <keep-alive exclude="c"> <router-view></router-view> </keep-alive>
include 属性表示只有 name 属性为 a,b 的组件会被缓存,(注意是组件的名字,不是路由的名字)其它组件不会被缓存。exclude 属性表示除了 name 属性为 c 的组件不会被缓存,其它组件都会被缓存。
2. 使用$route.meta 的 keepAlive 属性
需要在 router 中设置 router 的元信息 meta
export default new Router({ routes: [ { path: '/', name: 'Hello', component: Hello, meta: { keepAlive: false // 不需要缓存 } }, { path: '/page1', name: 'Page1', component: Page1, meta: { keepAlive: true // 需要被缓存 } } ] })
在 app.vue 进行区别缓存和不用缓存的页面
<div id="app"> <router-view v-if="!$route.meta.keepAlive"></router-view> <keep-alive> <router-view v-if="$route.meta.keepAlive"></router-view> </keep-alive> </div>
【注意】需要在 router.js 里面修改 scrollBehavior 函数,否则 keep-alive 可能不生效
scrollBehavior (to, from, savedPosition) { if (savedPosition) { return savedPosition; }else{ return { x: 0, y: 0 }; } },
二、ios 键盘换行变为搜索
1、input type="search"
2、input 外面套 form ,必须要有 action , action="javascript: return true"
3、表单提交阻止默认提交事件
<form action="javascript:return true" @submit.prevent="formSubmit"> <input type="search" placeholder="请输入诉求名称" id="search" /> </form>
三、路由参数变化组件不更新
同一 path 的页面跳转时路由参数变化,但是组件没有对应的更新。
原因:主要是因为获取参数写在了created 或者 mounted 路由钩子函数中,路由参数变化的时候,这个生命周期不会重新执行。
解决方案1:watch 监听路由
watch: { // 方法1 监听路由是否变化 '$route' (to, from) { if(to.query.id !== from.query.id){ this.id = to.query.id; this.init();//重新加载数据 } } } //方法2 设置路径变化时的处理函数 watch: { '$route': { handler: 'init', immediate: true } }
解决方案2 :为了实现这样的效果可以给 router-view 添加一个不同的 key ,这样即使是公用组件,只要 url 变化了,就一定会重新创建这个组件。
<router-view :key="$route.fullpath"></router-view>
四、scrollBehavior
使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。
const router = new VueRouter({ routes: [...], scrollBehavior (to, from, savedPosition) { // return 期望滚动到哪个的位置 } })
scrollBehavior 方法接收 to 和 from 路由对象。第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。
与 keepAlive 结合,如果 keepAlive 的话,保存停留的位置:
scrollBehavior(to, from, savedPosition) { if (savedPosition) { return savedPosition } else { if (from.meta.keepAlive) { from.meta.savedPosition = document.body.scrollTop } return { x: 0, y: to.meta.savedPosition || 0 } } }
五、优雅更新props
更新 prop 在业务中是很常见的需求,但在子组件中不允许直接修改 prop ,因为这种做法不符合单向数据流的原则,在开发模式下还会发出警告。因此大多数人会通过 $emit 触发自定义事件,在父组件中接收该事件的传值来更新 prop。
child.vue:
export default{ props: { title: String }, methods: { changeTitle(){ this.$emit('change-title", 'hello'); } } }
parent.vue
<child :title="title" @change-title="changeTitle"></child>
export default{ data(){ return{ title: 'title' } }, methods:{ changeTitle(title){ this.title = title; } } }
这种做法没有问题。但是如果你只是想单纯的更新 prop, 没有其他的操作,那么 sync 修饰符能够让这一切变得特别简单。
parent.vue
<child :title.sync="title"></child>
child.vue
export default{ props:{ title: String }, methods:{ changeTitle(){ this.$emit('update:title', 'hello'); } } }
只需要在绑定属性上添加 .sync ,在子组件内部就可以触发 update:属性名 来更新 prop 。可以看到这种手段确实简洁且优雅,这让父组件的代码减少了一个“没必要的函数”。
六、巧用template
相信 v-if 在开发中是用的最多的指令,那么你一定遇到过这样的场景,多个元素切换,而且切换条件都一样,一般都会使用一个元素包裹起来,在这个元素上做切换。
<div v-if="status==='ok'"> <h1>Title></h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </div>
如果像上面的 div 只是为了切换条件而存在,还导致元素层级嵌套多一层,那么它没有“存在的意义”。
我们都知道在声明页面模板时,所有元素需要放在 <template> 元素内。除此之外,它还能在模板内使用,<template> 元素作为不可见的包裹元素,只是在运行时做处理,最终的渲染结果并不包含它。
<template> <div> <template v-if="status==='ok'"> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </template> </div> </template>
同样的,我们也可以在 <template> 上使用 v-for 指令,这种方式还能解决 v-for 和 v-if 同时使用报出的警告问题。
<template v-for="item in 10"> <div v-if="item % 2 == 0" :key="item">{{item}}</div> </template>
template 使用 v-if,
template 使用 v-for。
参考文章: