Vue项目实用技巧整理

Posted haifeng8742

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue项目实用技巧整理相关的知识,希望对你有一定的参考价值。

1,css篇: 全局引入公共的scss或者其他预编译文件  ,主要依赖:sass-resources-loader, 详见我上一篇博客
2. js篇:  
 2.1:props和$emit

巧用修饰符语法糖sync来优雅的更新props ,父子组件的传值prop是很常用的业务,需要在子组件去更新prop的场景也很常见,但是prop是个只读属性,在子组件中直接修改其值因不符合单向数据流的设计,所以我们一般结合$emit来触发父组件的方法, 但是有些场景
只是简单的修改prop中的简单的值, 比如切换显示隐藏,更新type等等, 这时候就可以考虑使用sync修饰符了, 子组件更新prop的值也是必须要通过$emit来触发, 这并没有改变其单向数据流的设计的, 只是触发的方法名前面多了一个 update: ,说白了就是你在父组件中使用了sync, Vue会帮你声明一个method 名字就叫做 update:xxx     所以才免去你的手动添加这么一个方法,  开始就说了这不过是个语法糖 , 具体代码如下:

parent.vue:

<child :title.sync="title"></child>

child.vue:

export defalut {
    props: {
        title: String  
    },
    methods: {
        changeTitle(){
            this.$emit(‘update:title‘, ‘hello‘)
        }
    } 

 

2.2: provide和inject(主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。但是某些时候,或许它能帮助到我们)
  这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。

  简单来说,一个组件将自己的属性通过 provide 暴露出去,其下面的子孙组件 inject 即可接收到暴露的属性

  代码如下: 

App.vue:

export default {
    provide() {
        return {
            app: this
        }
    } 
}

child.vue:

export default {
    inject: [‘app‘],
    created() {
        console.log(this.app) // App.vue实例
    }
}

ps:在 2.5.0+ 版本可以通过设置默认值使其变成可选项:

export default {
    inject: {
        app: {
            default: () => ({})
        }
    },
    created() {
        console.log(this.app) 
    }
}

如果你想为 inject 的属性变更名称,可以使用 from 来表示其来源:

export default {
    inject: {
        myApp: {
            // from的值和provide的属性名保持一致
            from: ‘app‘,
            default: () => ({})
        }
    },
    created() {
        console.log(this.myApp) 
    }
}

2.3:巧用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-if和v-for同时使用报出警告的问题的方法之一了,(之前是通过过滤数据后渲染解决的)
<template v-for="item in 10">
<div v-if="item % 2 == 0" :key="item">{{item}}</div> </template>
2.4:
require.context (自动注册全局组件功能在之前的博客,请移步)
  这个并不是Vue提供的功能, 而是强大的Webpack提供的, 他还有另外一个妙用就是自动引入模块
像 api 文件一般按功能划分模块,在组合时可以使用 require.context 一次引入文件夹所有的模块文件,而不需要逐个模块文件去引入。每当新增模块文件时,就只需要关注逻辑的编写和模块暴露,require.context 会帮助我们自动引入

代码如下: (可以做成插件形式 具体请查看vue插件机制 )  import Request from ‘../service/request‘

let importAll = require.context(‘./modules‘, false, /.js$/) class Api extends Request{ constructor(){ super() //importAll.keys()为模块路径数组 importAll.keys().map(path =>{ //兼容处理:.default获取ES6规范暴露的内容; 后者获取commonJS规范暴露的内容 let api = importAll(path).default || importAll(path) Object.keys(api).forEach(key => this[key] = api[key]) }) } } export default new Api()

路由懒加载(动态chunkName)

路由懒加载作为性能优化的一种手段,它能让路由组件延迟加载。通常我们还会为延迟加载的路由添加“魔法注释”(webpackChunkName),在打包时,该路由组件会被单独打包出来。

 

let router = new Router({
  routes: [
    {
      path:‘/login‘,
      name:‘login‘,
      component: import(/* webpackChunkName: "login" */ `@/views/login.vue`)
    },
    {
      path:‘/index‘,
      name:‘index‘,
      component: import(/* webpackChunkName: "index" */ `@/views/index.vue`)
    },
    {
      path:‘/detail‘,
      name:‘detail‘,
      component: import(/* webpackChunkName: "detail" */ `@/views/detail.vue`)
    }
  ]
})

上面这种写法没问题,但仔细一看它们结构都是相似的,作为一名出色的开发者,我们可以使用 map 循环来解决这种重复性的工作。

const routeOptions = [
  {
    path:‘/login‘,
    name:‘login‘,
  },
  {
    path:‘/index‘,
    name:‘index‘,
  },
  {
    path:‘/detail‘,
    name:‘detail‘,
  },
]

const routes = routeOptions.map(route => {
  if (!route.component) {
    route = {
      ...route,
      component: () => import(`@/views/${route.name}.vue`)
    }
  }
  return route
})

let router = new Router({
  routes
})

在书写更少代码的同时,我们也把“魔法注释”给牺牲掉了。总所周知,代码中没办法编写动态注释。这个问题很尴尬,难道就没有两全其美的办法了吗?

强大的 webpack 来救场了,从 webpack 2.6.0 开始,占位符 [index] 和 [request] 被支持为递增的数字或实际解析的文件名。我们可以这样使用“魔法注释”:

 

const routes = routeOptions.map(route => {
  if (!route.component) {
    route = {
      ...route,
      component: () => import(/* webpackChunkName: "[request]" */ `@/views/${route.name}.vue`)
    }
  }
  return route
})

 

以上是关于Vue项目实用技巧整理的主要内容,如果未能解决你的问题,请参考以下文章

十个html5代码片段,超实用,一定要收藏

小技巧

QT 实用代码片段

十条实用的jQuery代码片段

Vue友们就靠这6个开发技巧了(建议收藏)

springboot项目实用代码整理