Vue 之学会编写可复用性模块

发布于 2024-08-22 19:43:16 字数 4084 浏览 5 评论 0

在 Vue 项目中,每一个页面都可以看作是由大大小小的模块构成的,即便是一行代码、一个函数、一个组件都可以看作是一个个自由的模块。那么提高代码的复用性的关键便在于编写可复用的模块,也就是编写可复用的代码、函数和组件等

封装成一个函数

除了使用变量的赋值缓存使用来解决数据的重复读取外,我们在开发过程中重复性更多的也许是功能点的重复,比如

<tempalte>
  <div>
    <input type="text" v-model="str1">
    <input type="text" v-model="str2">
    <div>{{ str1.slice(1).toUpperCase() }}</div>
    <div>{{ str2.slice(1).toUpperCase() }}</div>
  </div>
</template>

上述代码的重复功能点在于截取输入框中第二个字符开始到最后的值并把它们转化成大写字母,像这样很简单的操作虽然重复使用也不会出现太大的问题,但是如果是代码量较多的操作呢?重复书写相同功能的代码是一种不经过大脑思考的行为,我们需要对其进行优化,这里我们可以把功能点封装成一个函数:

export default {
  methods: {
    sliceUpperCase(val) {
      return val.slice(1).toUpperCase()
    }
  }
}

如此我们只要在用到该方法的地方调用即可,将值传入其中并返回新值。当然像在双花括号插值和 v-bind 表达式中重复的功能点我们可以封装成过滤器比较合适

// 单文件组件注册过滤器
filters: {
  sliceUpperCase(val) {
    return val.slice(1).toUpperCase()
  }
}

// 全局注册过滤器
Vue.filter('sliceUpperCase', function (val) {
  return val.slice(1).toUpperCase()
})

然后在 html 中使用 管道 符进行过滤

<div>{{ str1 | sliceUpperCase }}</div>
<div>{{ str2 | sliceUpperCase }}</div>

这样我们就把重复的功能性代码封装成了函数,而不管是过滤器还是正常的方法封装,其本质都是函数的封装

封装成一个组件

相比较于函数的封装,规模更大一点的便是组件的封装,组件包含了模板、脚本以及样式的代码,在实际开发中组件的使用频率也是非常大的,我们项目中的每一个页面其实都可以看作是一个父组件,其可以包含很多子组件,子组件通过接收父组件的值来渲染页面,父组件通过响应子组件的回调来触发事件

封装一个组件主要包含两种方式,一种是最常见的整体封装,用户通过改变数据源来呈现不同的页面状态,代码结构不可定制化。例如

<div>
  <my-component data="我是父组件传入子组件的数据"></my-component>
</div>

另一种便是自定义封装,也就是插槽(slot),我们可以开放一部分槽位给父组件,使其能够进行一定程度的定制化,例如

<div>
  <my-component data="我是父组件传入子组件的数据">
    <template slot="customize">
      <span>这是定制化的数据</span>
    </template>
  </my-component>
</div>

myComponent 组件中我们便可以接收对应的 slot

<div class="container">
  <span>{{ data }}</span>
  <slot name="customize"></slot>
<div>

这里我们通过定义 slot 标签的 name 值为 customize 来接收父组件在使用该组件时在 template 标签上定义的 slot="customize" 中的代码,不同父组件可以定制不同的 slot 代码来实现差异化的插槽。最终渲染出来的代码如下

<div>
  <div class="container">
    <span>我是父组件传入子组件的数据</span>
    <span>这是定制化的数据</span>
  </div>
</div>

这样我们就完成了一个小型组件的封装,将共用代码封装到组件中去,页面需要引入的时候直接使用 import 并进行相应注册即可,当然你也可以进行全局的引入

import myComponent from '../myComponent.vue'

// 全局
Vue.component('my-component', myComponent)

封装成一个插件

在某些情况下,我们封装的内容可能不需要使用者对其内部代码结构进行了解,其只需要熟悉我们提供出来的相应方法和 api 即可,这需要我们更系统性的将公用部分逻辑封装成插件,来为项目添加全局功能,比如常见的 loading 功能、弹框功能等

Vue 提供给了我们一个 install 方法来编写插件,使用该方法中的第一个 Vue 构造器参数可以为项目添加全局方法、资源、选项等。比如我们可以给组件添加一个简单的全局调用方法来实现插件的编写

/* toast.js */
import ToastComponent from './toast.vue' // 引入组件

let $vm

export default {  
  install(Vue, options) {
    
    // 判断实例是否存在
    if (!$vm) {      
      const ToastPlugin = Vue.extend(ToastComponent); // 创建一个“扩展实例构造器”
      
      // 创建 $vm 实例
      $vm = new ToastPlugin({        
        el: document.createElement('div')  // 声明挂载元素      
      });      
      
      document.body.appendChild($vm.$el); // 把 toast 组件的 DOM 添加到 body 里
    } 
    
    // 给 toast 设置自定义文案和时间
    let toast = (text, duration) => {
      $vm.text = text;
      $vm.duration = duration;
      
      // 在指定 duration 之后让 toast 消失
      setTimeout(() => {
        $vm.isShow = false;  
      }, $vm.duration);
    }
    
    // 判断 Vue.$toast 是否存在
    if (!Vue.$toast) {      
      Vue.$toast = toast;    
    }    
    
    Vue.prototype.$toast = Vue.$toast; // 全局添加 $toast 事件
  }
}

成功编写完插件的 JS 脚本后,我们在入口文件中需要通过 Vue.use() 来注册一下该插件:

import Toast from '@/widgets/toast/toast.js'

Vue.use(Toast); // 注册 Toast

最后我们在需要调用它的地方直接传入配置项使用即可,比如:

this.$toast('Hello World', 2000);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

0 文章
0 评论
24 人气
更多

推荐作者

qq_E2Iff7

文章 0 评论 0

Archangel

文章 0 评论 0

freedog

文章 0 评论 0

Hunk

文章 0 评论 0

18819270189

文章 0 评论 0

wenkai

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文