Vue使用高级技巧

1,918 阅读2分钟

vue开发几乎很简单,但是有很多优化的写法你可以就不知道


1,require.context()


一个webpack的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块,在前端工程中,如果遇到从一个文件夹引入很多模块的情况,可以使用这个api,它会遍历文件夹中的指定文件,然后自动导入,使得不需要每次显式的调用import导入模块


语法:

/** * directory {String} -说明需要检索的目录 * useSubdirectories {Boolean} -是否遍历文件的子目录 * regExp {RegExp} - 匹配文件的正则 **/require.context(directory, useSubdirectories = false, regExp = /^.//);


场景:

1,开发vue项目的时候一般都会开发很多自定义的全局组件,


一般写法是:这样的话如果我们封装了50个组件,那么就意味我们要写50个相同的组件引入语句,50个注册语句,大量的重复代码:



如果使用require.context那么就可以是下面这个样子,这样我们可以无限的在components文件下添加组件,自动注册成全局的

const files = require.context('@/components', true, /^\.\/(\w*\/)+index\.(vue|js)$/)​export default {  install (Vue) {    files.keys().forEach((path) => {      const type = this.typeof(path, files(path))      // 针对3中不同的组件设计模式提供不同的组件注册策略      switch (type) {        case 'component':          this.installComonent(Vue, files(path));        break;        case 'componentGroup':          this.instalGroupComponent(Vue, files(path));        break;        case 'serveApi':            this.installServeApi(Vue, files(path));        break;      }    })  },  typeof (path, file) {    if (path.lastIndexOf('.js') === -1) {      return 'component'    } else {      if (file.default.install) {        return 'serveApi'      } else {        return 'componentGroup'      }    }  },  instalGroupComponent (Vue, file) {    const components = file.default    Object.keys(components).forEach((name) => {      Vue.component('Nb'+name, components[name])    })  },  installComonent (Vue, file) {    const options = file.default    const name = options.name    Vue.component('Nb'+name, options)  },  installServeApi (Vue, file) {    Vue.use(file.default)  }}



2,开发一个svg图标组件,可能需要很多svg文件,需要通过webpack打包,如果全部一个一个引入的话,会比较麻烦,如果使用context api的话可以直接读取文件夹下的所有svg图标


2,watch


场景:


1,立即执行

表格初始进来需要调查询接口 fetchList(),然后筛选条件的值发生改变会重新查询

created(){
  this.fetchList()
},
watch: {
  'filters.type' () {
    this.fetchList()
  }
}


可以直接利用 watch 的immediate和handler属性简写

watch: {
  'filters.type': {
    handler: 'getList',
    immediate: true
  }
}


2,深度监听,

有时候我们可能需要监听整个对象,还是上面那个例子,上面我们针对一个对象中的某个属性进行监听,但是这个对象中有很多属性,任何一个属性的改变我们都需要重新发起请求,那么我们可以利用watch的deep属性进行深度监听,也就是监听复杂的数据类型

watch:{
  filters: {
    handler(newVal,oldVal){
      this.getList()
    },
    deep:true,
    immediate: true
  }
}


3,mixins

有些组件有些重复的 js 逻辑,比如我们常用的上啦加载更多,而上啦触底事件就是我们每个需要上啦加载功能页面都需要重复去写的逻辑,这部分东西我们都可以使用mixins来实现




4,Vue.nextTick


2.1.0 新增 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM


这个api的使用场景主要是为替代updated生命周期,有时候我们可能需要在数据更新后操作新的dom,但是updated生命周期是更新后执行,但是无法确定是那个属性的改变触发的更新,而nextTick是可以写在某个属性改变的后面,这么我们就可以知道是那个属性的改变了,功能其实和react,setState函数的第二个参数



4, Vue.filter 全局过滤器


过滤器的目的主要为了对数据格式进行转换(银行卡号格式化,货币格式化,日期格式化,...)


那么我用computed计算属性也可以呀,为什么要用filter,答案就是computed不能接受参数只能针对某一个vue内部属性进行转换,而filter可以接受参数


场景:时间戳转化成年月日这是一个公共方法,所以可以抽离成过滤器使用

// 使用​
// 在双花括号中{{ message | capitalize }}// 在 `v-bind` 中<div v-bind:id="rawId | formatId"></div>
// 全局注册
Vue.filter('stampToYYMMDD', (value) =>{
  // 处理逻辑
})​​​

// 局部注册
filters: {
  stampToYYMMDD: (value)=> {
    // 处理逻辑
  }
}

​// 多个过滤器全局注册
// /src/common/filters.js
let dateServer = value => value.replace(/(\d{4})(\d{2})(\d{2})/g, '$1-$2-$3') 
export { dateServer }​

// /src/main.js
import * as custom from './common/filters/custom'
Object.keys(custom).forEach(key => Vue.filter(key, custom[key]))



4, css 局部样式


Vue中style标签的scoped属性表示它的样式只作用于当前模块,是样式私有化.


渲染的规则/原理:

给HTML的DOM节点添加一个 不重复的data属性 来表示 唯一性

在对应的 CSS选择器 末尾添加一个当前组件的 data属性选择器来私有化样式


问题:

使用了scoped属性后,我们组件内部的样式无法在外部被控制,(也就是改不了样式,... 我要疯了咋没反应


解决方案:deep属性

.result-tab /deep/ {
 .nav-bar {
    a {
      flex: initial;
      height: 50px;
      font-size: 36px;
      margin-left: 40px;
      line-height: 100px;
      height: auto;
    }
  }
  .result-content {
    padding: 0 40px;
  }
}


关注公众号,看跟多优质文章