vue实用技巧

一、路由缓存 keepalive

keep-alive 是 Vue 提供的一个抽象组件,用来对组件进行缓存,从而节省性能,由于是一个抽象组件,所以在 v 页面渲染完毕后不会被渲染成一个 DOM 元素。

<keep-alive>
  <router-view></router-view>
</keep-alive>

当组件在  keep-alive 内被切换时组件的 activateddeactivated 这两个生命周期钩子函数会被执行

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。

 

 

参考文章:

Vue 项目里戳中你痛点的问题及解决办法(更新)

vue中前进刷新、后退缓存用户浏览数据和浏览位置的实践

总结vue知识体系之实用技巧

 

 

 

posted @ 2019-12-06 16:49  rachelch  阅读(234)  评论(0编辑  收藏  举报