浅谈vue框架实用技巧,一文带你快速上�
Admin 2021-09-04 群英技术资�
这篇文章给大家分享一些vue框架的实用小技巧,包括数据的双向绑定、使� Mixins、使用动态组件去懒加载组件、使用装饰器优化代码等等,小编觉得挺实用的,因此分享给大家做个参考,接下来一起跟随小编看看吧�
� Vue 项目开发中,很容易产生一些问题,比如代码重复、繁杂等,其� Vue 项目开发中有很多技巧可以使用,本文将列出一些简单且很好用的几个技巧,帮助我们写出漂亮的代码。用到的技术栈� Vue2.0 + TypeScript + vue-property-decorator + ElementUI。将用到以下几个技巧:
先聊聊如何传� 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 就会传给了父组件�
有很多这样的场景,父组件需要传递数据给子组件,且在子组件触发数据更新的时候,马上反馈给父组件,父组件数据更新,单向数据流向子组件,最后子组件更新。通常情况� props + $emit 的方式去更新状态,但是这种处理方式有点笨拙,且不易维护,所以可以通过实现数据的“双向绑定”来提高代码的可维护性。可以通过这以下方式去实现�
� 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 �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 就可以实现数据的“双向绑定”,这样书写代码可以一定程度上减少我们的代码,而且另代码变得更优雅且可维护�
Mixins 可以用于两种场景�
首先写一个公共的 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 抽离一些功能点,通过文件去管理这些功能,这样会比较方便去管理代码�
组件在加载都是同步的,但当页面内容很多,有些组件并不需要一开始就加载出来的比如弹窗类的组件,这些就可以用动态组件,当用户执行了某些操作后再加载出来,这样可以提高主模块加载的性能� � 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 一次,优化性能�
有很多场景想更改 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/ 这种写法�
装饰器增加了代码的可读性,清晰地表达了意图,而且提供一种方便的手段,增加或修改类的功能,比如给类其中的方法提供防抖的功能�
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); }
关于 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的实用技巧大家可以继续关注群英网络其它相关文章�
文本转载自脚本之�
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:[email protected]进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容�
猜你喜欢
排序算法类型有哪些?排序算法类型有冒泡排序、选择排序、插入排序、希尔排序、堆排序、快速排序、归并排序这些,那么用JavaScript怎样实现这些排序算法�?感兴趣的有接下来就跟随小编来学习一下吧�
dva是一个基于redux和redux-saga的数据流,然后为了简化开发体验,dva额外内置了react-router,fetch,可以激烈为一个轻量级的应用框架,这篇文章主要介绍了react dva实现,需要的朋友可以参考下
� React中是不存在双向数据绑定的机制的,需要我们自己对其进行实现。本文主要介绍一下React双向数据绑定,感兴趣的可以了解一�
这篇文章主要给大家介绍了关于JavaScript中常用的3种弹出提示框(alert、confirm、prompt)的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
这篇文章主要给大家分享JSONP原理及使用的内容,很多新手对于JSON可能不是很了解,对此下面小编就给大家来详细的介绍一下,具希望大家阅读完这篇文章能有所收获,下面我们一起来学习一下吧�
推荐内容
联系我们
24小时售后 � 24小时售后TEL�0668-2555666 售前咨询TEL�400-678-4567 投诉建议TEL�0668-2555999 投诉建议邮箱:t[email protected] 信息安全TEL�0668-2555118 域名空间客服 � 公司总机�0668-2555555 公司传真�0668-2555000Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所� 茂名市群英网络有限公�
增值电信经营许可证 : B1.B2-20140078