vue3组件化开发之可复用性的应用实例详解

目录
  • 自定义指令
    • 基本结构
    • 自定义 v-loading 指令
  • 插件
    • 基本结构
  • 实现一个全局状态管理插件
  • Teleport 传送
  • 相关链接
  • 总结

可复用性也是组件化开发的一个优势,能让代码更加简洁优雅、方便维护。下面主要写了vue3中能体现出复用性的一些API的应用。

自定义指令

指令 (Directives) 是带有 v- 前缀的特殊 attribute。

v-text v-show v-if ... 等是 vue 中内置的一些指令,当这些内置指令无法满足我们的要求时,这时候也可以使用自定义指令

基本结构

const app = Vue.createApp({})
// 注册一个全局自定义指令
app.directive('loading', {
  mounted(el, binding) {},
  updated(el, binding) {},
  // ...
})

一个自定义指令对象可以提供以下的钩子函数

  • created:在绑定元素的 attribute 或事件监听器被应用之前调用。在指令需要附加在普通的 v-on 事件监听器调用前的事件监听器中时,这很有用。
  • beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用。
  • mounted:在绑定元素的父组件被挂载后调用。
  • beforeUpdate:在更新包含组件的 VNode 之前调用。
  • updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用。
  • beforeUnmount:在卸载绑定元素的父组件之前调用
  • unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次。

钩子函数的一些参数

包含两个参数elbindingel 为指令绑定到的元素。这可用于直接操作 DOM。binding包含以下对象:

  • instance:使用指令的组件实例。
  • value:传递给指令的值。例如,在 v-my-directive="1 + 1" 中,该值为 2
  • oldValue:先前的值,仅在 beforeUpdate 和 updated 中可用。无论值是否有更改都可用。
  • arg:传递给指令的参数(如果有的话)。例如在 v-my-directive:foo 中,arg 为 "foo"
  • modifiers:包含修饰符(如果有的话) 的对象。例如在 v-my-directive.foo.bar 中,修饰符对象为 {foo: true,bar: true}
  • dir:一个对象,在注册指令时作为参数传递。

动态指令传递参数

v-mydir:[t]="val" //传递了t参数

t的值可以通过钩子函数的参数binding.arg获取到,val的值 通过binding.value获取到。

自定义 v-loading 指令

先编写一个LoadingIcon.vue组件,内容是加载中的样式。

<template>
  <div class="k_loading_mask">
    <div class="loading-icon">
      <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
        <path fill="currentColor"
          d="M512 64a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V96a32 32 0 0 1 32-32zm0 640a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V736a32 32 0 0 1 32-32zm448-192a32 32 0 0 1-32 32H736a32 32 0 1 1 0-64h192a32 32 0 0 1 32 32zm-640 0a32 32 0 0 1-32 32H96a32 32 0 0 1 0-64h192a32 32 0 0 1 32 32zM195.2 195.2a32 32 0 0 1 45.248 0L376.32 331.008a32 32 0 0 1-45.248 45.248L195.2 240.448a32 32 0 0 1 0-45.248zm452.544 452.544a32 32 0 0 1 45.248 0L828.8 783.552a32 32 0 0 1-45.248 45.248L647.744 692.992a32 32 0 0 1 0-45.248zM828.8 195.264a32 32 0 0 1 0 45.184L692.992 376.32a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0zm-452.544 452.48a32 32 0 0 1 0 45.248L240.448 828.8a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0z">
        </path>
      </svg>
    </div>
    <div class="tips">{{ tips }}</div>
  </div>
</template>
<script setup>
import { ref } from 'vue';

const tips = ref("加载中");
</script>
<style lang="scss">
.loading-icon {
  width: 30px;
  height: 30px;
  color: #fff;

  svg {
    animation: rotating 2s linear infinite;
    display: inline-block;
    width: 100%;
    height: 100%;
  }
}

.k_loading_mask {
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, .6);
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1000;
}

.tips {
  color: #fff;
}
</style>

创建一个js文件src/directives/loading.js,导出自定义指令的对象:

export default {
	mounted(el, binding) {
		// 插入元素
		const app = createApp(LoadingIcon);
		const instance = app.mount(document.createElement("div"));
		el.instance = instance;
		el.appendChild(el.instance.$el);

		el.style.position = "relative";
	},
	updated(el, binding) {

	},
};

根据用户传给指令的参数,动态设置提示文字:

mounted(el, binding){
// ...
	// 提示文字
	if (binding.arg) {
		el.instance.tips = binding.arg;
	}
}

指令绑定的值变化时,设置显示或隐藏loading:

	updated(el, binding) {
		if (!binding.value) {
			el.removeChild(el.instance.$el);
		} else {
			el.appendChild(el.instance.$el);
		}
	},

全局注册自定义指令:

const app = createApp(App);

import loading from "./directives/loading.js";
app.directive("loading",loading);

使用 v-loading 指令:

<template>
        <div v-loading="showLoading" class="loading-box"></div>
        <div v-loading:[tipsLoading]="showLoading" class="loading-box2">
          一些内容...
        </div>
</template>

<script setup>
const showLoading = ref(true);
const tipsLoading = ref("请稍后");
const close = () => {
  showLoading.value = !showLoading.value;
}
</script>

插件

插件是自包含的代码,通常向 Vue 添加全局级功能。它可以是公开 install() 方法的 object,也可以是 function

每当插件被添加到应用程序中时,如果它是一个对象,就会调用 install 方法。如果它是一个 function,则函数本身将被调用。在这两种情况下,它都会收到两个参数:由 Vue 的 createApp 生成的 app 对象和用户传入的选项。

基本结构

导出一个对象,里面包含 install 方法。

export default {
  install: (app, options) => {
    // ...
  }
}

使用插件

在使用 createApp() 初始化 Vue 应用程序后,通过调用 use() 方法将插件添加到应用程序中。

const app = createApp(App);

app.use(plugin);

实现一个全局状态管理插件

在小型项目中,使用vuex 全局状态管理工具,容易让代码变得冗余复杂,那如果还需要全局的状态管理,这时候就可以自己通过插件的方式实现一个mini版本的全局状态管理。

新建minstore.js

import { reactive } from 'vue';

const state = reactive({
  str: '字符串',
});

const minstore = {
  state,
};

export default {
  install: (app) => {
    app.provide('minstore', minstore);
  },
};

main.js安装这个插件:

import minstore from './minstore/minstore.js';

const app = createApp(App);
app.use(minstore).mount('#app');

组件中使用minstore

const minstore = inject('minstore');
console.log(minstore.state);
<p>{{ minstore.state.str }}</p>

Teleport 传送

先来看一个案例:

        <div style="position: relative;">
          <div class="model" style="position:absolute">模态框</div>
        </div>

内层模态框的定位,是相对于父级的,如果想让它相对于body定位在全局弹出模态框的话,实现起来可能很麻烦。

Teleport 提供了一种干净的方法,允许我们控制在 DOM 中哪个父节点下渲染了 HTML。

使用 <teleport>to 属性,让Vue “将这个 HTML 传送body标签下。

        <div style="position: relative;">
          <teleport to='body'>
            <div v-show="showModel" class="model" style="position:absolute">模态框</div>
          </teleport>
        </div>

此时,HTML被插入到body标签下,模态框的定位就相对于body标签。

相关链接

vue3组件化开发常用API

代码demo地址 github.com/kongcodes/v…

从0开始vue3项目搭建

总结

到此这篇关于vue3组件化开发之可复用性应用的文章就介绍到这了,更多相关vue3可复用性应用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解vue.js组件化开发实践

    前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎么实现,技术选型自然成为了第一个问题.鉴于目前web前端mvvm框架以及组件化开发方式的流行,决定技术栈采用:vue + es6 + 组件化. 这里首先简单说下web前端组件化开发方式的历程: 最早的组件化结构,代码结构可能如下: - lib/components/calendar |- calendar.css |-

  • Vue组件化开发思考

    一般说到组件,我首先想到的是弹窗,其他就大脑空白了. 因为觉得这个是在项目中最常用的功能,提取出来方便复用的才是组件- 然而我才发现这个想法是有问题的. 我发觉可能从意识上把Vue的组件和UI库的组件(弹窗之类的)混淆了... 缘起于最近的一个表单开发,页面上有2个是联动菜单的选项. 首先想到的是,这个样式和选择地址的那个联动菜单,完全一样哈- (废话,同一个项目 当然要保持ui风格的相同啊!) 不过差别在于 我这个是 一个1级 一个2级, 地址那个是4级的. 然后我就想着把那个地址的组件引进来

  • vue3.0 CLI - 2.6 - 组件的复用入门教程

    我的 github 地址 - vue3.0Study- 阶段学习成果都会建立分支. ========================== 定义一个基础组件 这个基础组件,是导航条中 可以复用 的基础组件 单个导航. 基础组件[导航组件]基础的功能是能够显示文字,单击的交互方式.明确任务目标之后,进行开发. 在 component 目录下新建 Base 目录,Base 下新建文件 TopNav.vue.加入如下代码: <template> <div class="topnav&q

  • vue3组件化开发之可复用性的应用实例详解

    目录 自定义指令 基本结构 自定义 v-loading 指令 插件 基本结构 实现一个全局状态管理插件 Teleport 传送 相关链接 总结 可复用性也是组件化开发的一个优势,能让代码更加简洁优雅.方便维护.下面主要写了vue3中能体现出复用性的一些API的应用. 自定义指令 指令 (Directives) 是带有 v- 前缀的特殊 attribute. v-text v-show v-if ... 等是 vue 中内置的一些指令,当这些内置指令无法满足我们的要求时,这时候也可以使用自定义指令

  • vue3组件化开发常用API知识点总结

    目录 组件化思想 组件通讯 $props $emits $parent $attrs proviede & inject 插槽 slot 渲染作用域 作用域插槽 v-model 表单组件 自定义组件 改变默认参数 样式绑定相关 class style 总结 组件化思想 为什么使用组件化开发? 当前前端比较流行的 Vue React 等框架,都会通过编写组件来完成业务需求,也就是组件化开发.包括小程序开发也会用到组件化开发的思想. 分析组件化思想开发应用程序: 将一个完整页面拆分成很多个小组件 每

  • vue组件中使用props传递数据的实例详解

    在 Vue 中,父子组件的关系可以总结为 props向下传递,事件向上传递.父组件通过 props 给子组件下发数据,子组件通过事件给父组件发送消息.看看它们是怎么工作的.  一.基本用法 组件不仅仅是要把模板的内容进行复用,更重要的是组件间要进行通信. 在组件中,使用选项props 来声明需要从父级接收的数据, props 的值可以是两种, 一种是字符串数组,一种是对象. 1.1 字符串数组: <div id="app4"> <my-component4 messa

  • IOS 开发中画扇形图实例详解

    IOS 开发中画扇形图实例详解 昨天在做项目中,遇到一个需要显示扇形图的功能,网上搜了一下,发现code4app里面也没有找到我想要的那种类似的效果,没办法了,只能自己学习一下如何画了. 首先我们需要了解一个uiview的方法 -(void)drawRect:(CGRect)rect 我们知道了这个方法,就可以在自定义UIView的子类的- (void)drawRect:(CGRect)rect里面绘图了,关于drawrect的调用周期,网上也是一找一大堆,等下我会整理一下,转载一篇供你们参考.

  • Android 开发中使用Linux Shell实例详解

    Android 开发中使用Linux Shell实例详解 引言 Android系统是基于Linux内核运行的,而做为一名Linux粉,不在Android上面运行一下Linux Shell怎么行呢? 最近发现了一个很好的Android Shell工具代码,在这里分享一下. Shell核心代码 import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.

  • 微信小程序 开发MAP(地图)实例详解

    微信小程序 开发MAP(地图)实例详解 在创建MAP(地图)前,请各位小伙伴们认真的去了解微信小程序开发的说明. https://mp.weixin.qq.com/debug/wxadoc/dev/component/map.html#map 了解完MAP(地图)里的属性之后,接下来我们就来创建一个简单的MAP(地图)控件. 第一步:肯定是创建项目.起项目名.项目地址 PS:我这里以index的文件为名 第二步:我们来写 index.wxml 文件的代码 WXML文件代码: <map id=&quo

  • Vue组件全局注册实现警告框的实例详解

    外部引入 <link href="https://cdn.bootcss.com/animate.css/3.5.2/animate.min.css" rel="stylesheet"> <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> <script

  • java开发Activiti进阶篇流程实例详解

    目录 1.流程实例 1.1 什么是流程实例 1.2 业务管理 1.3 流程实例的挂起和激活 1.3.1 全部流程挂起 1.3.2 单个实例挂起 1.流程实例 1.1 什么是流程实例 流程实例(ProcessInstance)代表流程定义的执行实例 一个流程实例包括了所有的运行节点,我们可以利用这个对象来了解当前流程实例的进度等信息 例如:用户或者程序安装流程定义的内容发起了一个流程,这个就是一个流程实例 1.2 业务管理 ​流程定义部署在Activiti后,我们就可以在系统中通过Activiti

  • vue3.0中的watch侦听器实例详解

    目录 前言 侦听器和计算属性的区别 vue3如何使用watch呢? 基本使用 监听多个响应式数据 侦听reactive定义的响应式数据 监听reactive定义的响应式数据的某一个属性 配置选项用法 总结 前言 虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器.这就是为什么 Vue 通过watch选项提供了一个更通用的方法,来响应数据的变化.当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的. 侦听器和计算属性的区别 计算属性里不可以做异步操作,侦听器可以做异步操作

  • Monaco Editor开发SQL代码提示编辑器实例详解

    目录 安装 简易 SQL 编辑器 相关功能 获取选中代码 替换选中代码 处理光标位置 自定义 SQL 库表提示,并保留原有 SQL 提示 编辑器 resize 编辑器设置主题 SQL 代码格式化 右键菜单汉化 记得销毁编辑器对象哦 踩坑 如何快速去看懂 Monaco Editor 安装 安装依赖,这里请注意版本 yarn add monaco-editor@0.29.1 yarn add monaco-editor-webpack-plugin@5.0.0 配置 webpack 插件 // vu

随机推荐