广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Vue项目中常用的实用技巧汇总
  • 139
分享到

Vue项目中常用的实用技巧汇总

2024-04-02 19:04:59 139人浏览 泡泡鱼
摘要

目录前言1. 使用 $attrs 和 $listeners 进行多层级的数据和事件传递2. 实现数据的双向绑定,方便维护数据使用 .sync 实现 Prop 的“双向绑定”使用 mo

前言

Vue 项目开发中,很容易产生一些问题,比如代码重复、繁杂等,其实 Vue 项目开发中有很多技巧可以使用,本文将列出一些简单且很好用的几个技巧,帮助我们写出漂亮的代码。用到的技术栈是 Vue2.0 + typescript +  vue-property-decorator + ElementUI。将用到以下几个技巧:

  • 使用 $attrs 和 $listeners 进行多层级的数据和事件传递
  • 实现数据的双向绑定,方便维护数据
  • 使用 Mixins
  • 使用动态组件去懒加载组件
  • 在组件作用域内的 CSS 中使用 ::v-deep  修改组件样式
  • 使用装饰器优化代码
  • 利用 require.context 去获取项目目录信息

1. 使用 $attrs 和 $listeners 进行多层级的数据和事件传递

先聊聊如何传递 Prop,可以分为静态和动态的 Prop:


<!-- 静态的prop -->
<blog-post title="My journey with Vue"></blog-post>
<!-- 动态的prop -->
<blog-post v-bind:title="post.title"></blog-post>
<!-- 动态的prop传递可以简写成 -->
<blog-post :title="post.title"></blog-post>
<!-- 需要传递多个prop的时候,可以一起写在v-bind上 -->
<blog-post v-bind="{ editable, title: post.title}"></blog-post>

了解了 Props 的传递方式,在看看官方文档是怎么定义 $attrs 的,  在尤大大的文档中这样介绍了 $attrs:

$attrs:  包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件

$attrs  包含了传入到父作用域中没有在 props 声明的其他 props,因此我们可以用 $attrs 去代替那些父组件中不需要的而子组件需要的 props, 通过 v-bind="$attrs" 统一传递给后代。这样就避免了一个个声明然后再一个个传递。


<blog-post v-bind="$attrs"></blog-post>

上面这一行代码就通过 v-bind="$attrs" 的方式将本作用域中不作为 prop 的其他属性传递给了 blog-post 组件。

父组件通过 $attrs 传递给后代组件后,后代组件如果想通过触发事件来更新父组件状态该如何处理?如果一级一级地往上 emit 事件,会不会弄得代码太繁琐复杂了?在 Vue 中可以通过 $listeners 解决这个问题,先看看官方文档关于  $listeners 的说明:

包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

文档中说了 $listeners 包含了父作用域中的事件监听器。意思就是 $listeners 表示了父组件中的事件监听器集合,只要是触发父组件的事件,而不是自己的,就可以用一个 v-on="$listeners"表示。


<!-- 父组件(第一层组件) -->
<componentA @on-change="handleChange" v-bind="{ editable, title: post.title}" />

<!-- 中间层的组件 -->
<Child v-bind="$attrs" v-on="$listeners"/>

<!-- 数据传递的目标组件,事件触发的组件 -->
<div @click="handleClick">{{ title }} </div>
<script>
  export default {
    props: {
      title: String
    }
    handleClick() {
      this.$emit('on-change', 'New Title');
    }
  }
</script>

上面的代码示例中,中间层的组件内通过 v-bind="$attrs" 将其余的 Prop 传递给了 Child 组件,再通过 v-on="$listeners" 绑定父作用域中的事件监听器,一旦 emit 就会传给了父组件。

2. 实现数据的双向绑定,方便维护数据

有很多这样的场景,父组件需要传递数据给子组件,且在子组件触发数据更新的时候,马上反馈给父组件,父组件数据更新,单向数据流向子组件,最后子组件更新。通常情况用 props + $emit 的方式去更新状态,但是这种处理方式有点笨拙,且不易维护,所以可以通过实现数据的“双向绑定”来提高代码的可维护性。可以通过这以下方式去实现:

使用 .sync 实现 Prop 的“双向绑定”

在 v-bind prop的时候添加  .sync 修饰符,赋新值的时候用  this.$emit('update:propName', newValue)


<!-- .sync是 v-on:update这种模式的一种缩写 -->
<Child v-on:update:title="title" />
<!-- 相当于 -->
<Child :title.sync="title" />

如果要更新上述代码中的 title 值,只需要   this.$emit('update:title', '新标题'),完成数据更新。

使用 model 选项

model 是2.2.0+ 新增的选项,一个组件上的 v-model 默认会利用名为 value  的 Prop  和名为 input 的事件, 而 model 选项可以规定 Prop 名称和事件名称来实现 v-model,好处是在实现 v-model 的同时也避免了 Prop 和事件名的冲突。


<!-- 父组件 -->
<Model v-model="checked"/>

<!-- Model组件 -->
<div @click="handleClick">
  <p>自定义组件的 v-model</p>
  checked {{checked}}
</div>
<script lang="ts">
export default {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  methods: {
    handleClick() {
      this.$emit('change', !this.checked);
    }
  }

在上述代码中,只需要在 model 选项中添加 prop 和 event,就可以实现了 v-model。而在 Vue + TS 项目中 vue-property-decorator 中提供了 Model 的装饰器,需要这么写:


@Model('change', { type: Boolean }) readonly checked!: boolean
handleClick() {
  this.$emit('change', !this.checked);
}

只需要通过 .sync 和 model 就可以实现数据的“双向绑定”,这样书写代码可以一定程度上减少我们的代码,而且另代码变得更优雅且可维护。

3. 使用 Mixins

Mixins 可以用于两种场景:

  1. 利用它去抽取成组件内的公共代码加强代码复用,不要在全局内套来套去,最好在组件内或者页面中使用。
  2. 利用它去分离功能点,有时候会遇到一种情况,就是业务功能很多导致写起来的 Vue 文件行数很多,导致代码很难以维护,功能点代码不好追踪。可以通过抽取功能代码的方式,让这个庞大的 Vue 文件更好维护。

首先写一个公共的 mixin 文件, 把高复用的状态和函数写进去。


export default class CommonMixins extends Vue{
    public paginations = {
        pageSize: 20,
        total: 0,
        currentPage: 1,
    }
    handleChangePageSize (pageSize: number, cb: Function) {
        this.paginations.pageSize = pageSize;
        cb();
    }
    handleChangePageNum (currentPage: number, cb: Function) {
        this.paginations.currentPage = currentPage;
        cb();
    }
}

vue-property-decorator 提供了 Mixins 的装饰器,在业务页面中引入 Mixin 只需要往里 Mixins 传入 , 可以传多个,表示混入多个 Mixin。


<script lang="ts">
import { Component, Mixins } from 'vue-property-decorator';
import CommonMixins from "./common-mixin";
import PermissionMixins from "./permission-mixin";
@Component({})
export default class Parent extends Mixins(CommonMixins, PermissionMixins) {
}
</script>

如果只需要一个的话,也可以直接继承


<script lang="ts">
import { Component, Mixins } from 'vue-property-decorator';
import CommonMixins from "./common-mixin";
@Component({})
export default class Parent extends CommonMixins {
}
</script>

在遇到功能点多,代码量大的页面时,我们可以利用 Mixin 抽离一些功能点,通过文件去管理这些功能,这样会比较方便去管理代码。

4. 使用动态组件去懒加载组件

组件在加载都是同步的,但当页面内容很多,有些组件并不需要一开始就加载出来的比如弹窗类的组件,这些就可以用动态组件,当用户执行了某些操作后再加载出来,这样可以提高主模块加载的性能, 在 Vue 中可以使用 component 动态组件, 依 is 的值,来决定哪个组件被渲染。


<template>
  <div>
    主页面 <br/>
    <button @click="handleClick1">点击记载组件1</button><br/>
    <button @click="handleClick2">点击记载组件2</button><br/>
    <component :is="child1"></component>
    <component :is="child2"></component>
  </div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component({})
export default class AsyncComponent extends Vue {
  public child1:Component = null;
  public child2:Component = null;
  handleClick1() {
    this.child1 = require('./child1').default;
  }
  handleClick2() {
    this.child2 = require('./child2').default;
  }
}
</script>

示例代码中,只有当点击的时候才会去加载组件。component 还可以配合 v-show 去控制显示和隐藏,这样这个component 只会 mounted 一次,优化性能。

5. 在组件作用域内的 CSS 中使用 ::v-deep  修改组件样式

有很多场景想更改 UI 组件样式,然后怕影响别人的使用,加上 scoped 后又不能生效,可以使用  ::v-deep 深度作用选择器去修改组件作用域内的 CSS 的样式。在 CSS 中我们可以使用 >>> 操作符,但在预处理器中的写法就要用 /deep/ 或 ::v-deep。


<style scoped>
>>> .ivu-tabs-tabpane {
        background: #f1f1f1;
    }
</style>
<style lang="scss" scoped>
/deep/ .ivu-tabs-tabpane {
        background: #f1f1f1;
    }
</style>
<style lang="scss" scoped>
::v-deep .ivu-tabs-tabpane {
        background: #f1f1f1;
    }
</style>

::v-deep 和 /deep/ 作用是一样的,但不推荐使用 /deep/, 在 vue3.0 中将不支持 /deep/ 这种写法。

6. 使用装饰器优化代码

装饰器增加了代码的可读性,清晰地表达了意图,而且提供一种方便的手段,增加或修改类的功能,比如给类其中的方法提供防抖的功能。


import debounce from 'lodash.debounce';
export function Debounce(delay: number, config: object = {}) {
  return (target: any, prop: string) => {
    return {
      value: debounce(target[prop], delay, config),
    };
  };
}

这样的好处是使用起来非常方便,另外增加了代码的可读性。


@Debounce(300)
onIdChange(val: string) {
  this.$emit('idchange', val);
}

7. 利用 require.context 去获取项目目录信息

关于 require.context,webpack 文档是这么描述的:

可以给这个函数传入三个参数:一个要搜索的目录,一个标记表示是否还搜索其子目录, 以及一个匹配文件的正则表达式
WEBpack 会在构建中解析代码中的 require.context() 。如果想引入一个文件夹下面的所有文件,或者引入能匹配一个正则表达式的所有文件,这个功能就会很有帮助

根据这个提示,我们可以引用到一个文件夹下面的所有文件,由此可以利用获取的文件信息去做一些操作,比如在注册组件的时候,原本我们注册组件的时候需要一个个引入并且一个个注册,而且后面想加新的,又要再写上,现在可以通过 require.context 去优化这一段代码。


// import WmsTable from './wms-table/table/index';
import Table from './table/index.vue';
import CustomHooks from './custom-hooks/custom-hooks-actions/index';
import SFilter from './s-filter/filter-fORM';
import WButton from './button/index';
import CreateForm from './createForm/create-form/CreateForm.vue';
import Action from './table/action-table-column.vue';
import DetailItem from './detail-item.vue';


Vue.component('w-filter', SFilter);
Vue.component('w-button', WButton);
Vue.component('custom-hooks', CustomHooks);
Vue.component('create-form', CreateForm);
Vue.component('w-table', Table);
Vue.component('w-table-action', Action);
Vue.component('zonetime-date-picker', ZonetimeDatePicker);
Vue.component('detail', DetailItem);

注册全局组件的时候,不需要一个一个 import,和一个个去注册,使用 require.context 可以自动导入模块,这样的好处在于,当我们新建一个组件,不用自己再去手写注册,而在一开始就帮我们自动完成。


const contexts = require.context('./', true, /\.(vue|ts)$/);
export default {
  install (vm) {
    contexts.keys().forEach(component => {
      const componentEntity = contexts(component).default;
      if (componentEntity.name) {
        vm.component(componentEntity.name, componentEntity);
      }
    });
  }
};

总结

本文介绍了在 Vue 实战中经常用到的一些技巧,这些技巧的目的都是为了提升开发效率,比如简单地实现双向数据绑定和数据跨级传递等,另外也可以提高代码的可维护性、可读性,比如很实用的装饰器和利用 Mixin 拆分代码和管理功能点。

到此这篇关于Vue项目中常用的实用技巧汇总的文章就介绍到这了,更多相关Vue项目常用技巧内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

引用

  • require.context
  • Vue 官方文档

--结束END--

本文标题: Vue项目中常用的实用技巧汇总

本文链接: https://www.lsjlt.com/news/129988.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Vue项目中常用的实用技巧汇总
    目录前言1. 使用 $attrs 和 $listeners 进行多层级的数据和事件传递2. 实现数据的双向绑定,方便维护数据使用 .sync 实现 Prop 的“双向绑定”使用 mo...
    99+
    2022-11-12
  • Vue项目中常用的实用技巧总结
    本篇内容主要讲解“Vue项目中常用的实用技巧总结”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue项目中常用的实用技巧总结”吧!目录前言 使用 $attrs 和 $listeners 进行多层...
    99+
    2023-06-20
  • Android ListView常用小技巧汇总
    ListView在我们Android项目中的地位是有目共睹的,相信几乎每一个App中都有它的身影。 ListView主要是用列表形式来加载数据,在特定情况下需要实现一些特殊功能:如刷新数据,加载数据,实现动画效果等。 作为我们常用的...
    99+
    2022-06-06
    技巧 listview Android
  • Vue项目常用的技巧有哪些
    本篇内容介绍了“Vue项目常用的技巧有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. 使用 $attrs 和 $listeners ...
    99+
    2023-07-04
  • 一些常用的Python爬虫技巧汇总
    Python爬虫:一些常用的爬虫技巧总结 爬虫在开发过程中也有很多复用的过程,这里总结一下,以后也能省些事情。 1、基本抓取网页 get方法 import urllib2 url "http://w...
    99+
    2022-06-04
    爬虫 常用 技巧
  • Vue项目中实用小技巧有哪些
    这篇文章将为大家详细讲解有关Vue项目中实用小技巧有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。需求一:为路径配置别名在开发过程中,我们经常需要引入各种文件,如图片...
    99+
    2022-10-19
  • Z-BLOG常用技巧汇总(月光博客)
    高效能的日志搜索   用途:搜索是非常消耗系统资源的动作,而且对于多关键字搜索和模糊搜索,处理起来也非常麻烦,这里提供了一个非常高效而实用的搜索方法,就是使用Google的站内搜索技术,当你的日志被Google索引了大部...
    99+
    2022-06-12
    常用技巧
  • vue管理系统项目中的一些核心技能汇总
    目录前言1. Axios 拦截器和二次封装1.1 Axios 请求和响应拦截器。1.2 Axios 二次封装2. Vuex 的数据持久化3. 路由守卫和动态路由的挂载3.1 路由守卫...
    99+
    2022-11-13
  • Python matplotlib实用绘图技巧汇总
    前言 在日常的业务数据分析 ,可视化是非常重要的步骤。这里总结了matplotlib常用绘图技巧,希望可以帮助大家更加更加高效的、美观的显示图表。作者:北山啦 Matplotli...
    99+
    2022-11-12
  • 22个Vue优化技巧(项目实用)
    目录代码优化 v-for 中使用 key v-if/v-else-if/v-else 中使用 key合理的选择 v-if 和 v-show 使用简单的 计算属性functional ...
    99+
    2022-11-12
  • Vue项目中常用的工具函数总结
    目录前言一、自定义聚焦指令1、方式一2、方式二3、方式三二、输入框防抖1、需求2、思路3、代码实现三、关键字高亮1、需求2、思路3、代码演示四、格式化Excel表格中存储的时间1、需...
    99+
    2022-11-12
  • vue项目中less的一些使用小技巧
    目录前言 一、样式穿透 1.  什么是样式穿透?2.  如何使用? 二、混入 1.  什么是混入? 2.  如何使用?三、 less自动化导入...
    99+
    2022-11-12
  • MySQL使用的常见问题解决与应用技巧汇总
    前言 在MySQL日常开发或者是维护中,有一些问题或是故障往往是难以避免的,如丢失密码、表损坏。在此总结一下常见的问题,以备今后所需。 一、 忘记 MySQL 的 root 密码 1. 登录到数据库所在的...
    99+
    2022-10-18
  • Laravel使用Queue队列的技巧汇总
    Laravel 队列为不同的后台队列服务提供统一的 API,例如 Beanstalk,Amazon SQS,Redis,甚至其他基于关系型数据库的队列。队列的目的是将耗时的任务延时处理,比如发送邮件,从而大幅度缩短 Web 请求和相应的时间...
    99+
    2023-09-02
    laravel php 开发语言
  • vue项目中一定会用到的性能优化技巧
    目录引言性能优化标准Lighthouse通用常规优化手段通用性能优化分析FCP(First Contentful Paint)LCP(Largest Contentful Paint...
    99+
    2022-11-13
  • Android编程常用技巧实例总结
    本文实例讲述了Android编程常用技巧。分享给大家供大家参考,具体如下: 1. 登录的时候,如果输入有误,则输入框左右震动,表示输入有误 在res下准备一个anim文件夹,里...
    99+
    2022-06-06
    技巧 Android
  • Python常用的爬虫技巧总结
    用python也差不多一年多了,python应用最多的场景还是web快速开发、爬虫、自动化运维:写过简单网站、写过自动发帖脚本、写过收发邮件脚本、写过简单验证码识别脚本。 爬虫在开发过程中也有很多复用的过程...
    99+
    2022-06-04
    爬虫 常用 技巧
  • vue项目中常用解决跨域的方法总结(CORS和Proxy)
    目录一、什么是跨域?二、如何解决跨域?总结一、什么是跨域? 跨域问题的出现是因为浏览器的同源策略问题。所谓同源就是必须有以下三个相同点:协议相同、主机相同、端口相同。如果其中有一项不...
    99+
    2022-12-08
    vue解决跨域的方法 vue解决跨域的几种办法 2022年vue跨域解决
  • 管理Angular项目的实用技巧有哪些
    这篇文章主要介绍“管理Angular项目的实用技巧有哪些”,在日常操作中,相信很多人在管理Angular项目的实用技巧有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”管理...
    99+
    2022-10-19
  • vue实战中的一些实用小魔法汇总
    能让你首次加载更快的路由懒加载,怎么能忘? 路由懒加载可以让我们的包不需要一次把所有的页面的加载进来,只加载当前页面的路由组件就行。 举个🌰,如果这样写,加载的时候会...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作