Loading [MathJax]/jax/output/CommonHTML/config.js
部署DeepSeek模型,进群交流最in玩法!
立即加群
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【流莺书签】基础组件(Button,Overlay,Dialog,Message)

【流莺书签】基础组件(Button,Overlay,Dialog,Message)

作者头像
一尾流莺
发布于 2022-12-10 02:59:05
发布于 2022-12-10 02:59:05
81100
代码可运行
举报
运行总次数:0
代码可运行

写在前面

项目地址

👉👉项目预览地址,可以直接设置为浏览器主页或者桌面快捷方式进行使用

源码地址

完全开源,大家可以随意研究,二次开发。当然还是十分欢迎大家点个Star⭐⭐⭐

👉👉源码链接(gitee)       👉👉源码链接(github)

简介

本文记录了流莺书签封装的部分基础组件,包括

Button

Overlay

Dialog

Message

由于本项目是为了练手,所以在某些组件中可能也添加了一些实际并没有用到的功能,接下来将逐个介绍这些组件的属性,方法,以及一些设计思路.

除了一些特殊的样式,文章不会大量贴出CSS代码,由于我SASS功底不是很好,CSS代码看起来也是比较臃肿😣😣😣,感兴趣的同学可以自行查看源码

目录结构

基本就是一个组件的.vue文件和一个对应的index.ts,index.ts存放一些基础数据,类型声明等

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
├── src 
     ├── assets      // 存放静态资源
     ├── baseComponents  // 基础组件
         └──Button    // 按钮组件
         │    └──Button.vue
         └── Message    // 弹窗组件
              ├──Message.vue
              └──index.ts
                 ......

Button

展示

先来看效果,可以看到就是鼠标移入移出的时候会有一个动画

属性
  • title 按钮的文字
  • backgroundColor 鼠标移入的颜色
  • useAnimation 是否启用动画设计思路/亮点 🌝按钮的背景颜色使用了vue3新增特性,直接在css中绑定了props的变量backgroundColor,不了解新特性的小伙伴可以前往官网查看哟

🌝通过动态绑定class来启用动画,因为css中是给类名animation写的hover事件,所以如果类名不存在了,动画自然不生效了

代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <div class="wh-button-box">
    <div class="btn">
      <a :class="{animation:useAnimation}" href="#">{{title}}</a>
    </div>
  </div>
</template>

<script lang='ts'>
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'Wh-button',
  props: {
    title: {
      type: String,
      default: '按钮',
    },
    backgroundColor: {
      type: String,
      default: 'rgba(16, 143, 111, 0.3)',
    },
    useAnimation: {
      type: Boolean,
      default: false,
    },
  },
  setup() {
    return {};
  },
});
</script>

<style lang='scss'>
//此处省略部分CSS代码,详情请查看源码
.wh-button-box {
  .btn {
    &amp;:hover .animation::before {
      transform: skewX(45deg) translateX(200%);
    }
    &amp;:hover .animation {
      background: v-bind('state.color');
    }
  }
}
</style>
组件中使用

正常传入属性使用即可,这里使用双标签纯属个人习惯😁😁

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<wh-button @click="onConfirm"  title='确认' :use-animation="true" :background-color="`rgba(160, 21, 114, 0.3)`"></wh-button>
<wh-button @click="onCancle" title='取消' :use-animation="true"></wh-button>

Overlay

展示

先看效果

属性
  • show 是否启用遮罩层
  • zIndex 遮罩层的z轴坐标
  • closeOnClickModal 是否可以通过点击遮罩层关闭内容设计思路/亮点 🌝使用了vue3的新特性teleport,这个组件的作用是把里面的内容插入到指定的节点当中,我这里是插入在body里了

🌝添加了0.3秒的一个过渡效果,这样显得平滑一点,这里需要注意的是vue3中的transition类名发生了一些小变化,我刚开始写的时候没注意到,结果过渡效果就没生效,查了半天才发现v-enter变成了v-enter-form, v-leave变成了v-leave-form,整体的使用方式还是跟以前一样,更多具体的变动请移步vue3官网

🌝遮罩层一般都结合其他组件使用,比如Dialog,所以这里设置了一个属性,来配置是否可以通过点击遮罩层来关闭Dialog,需要配置closeOnClickModaltrue,并执行父组件的一个close方法

代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <!-- 传送门  此处Dom节点会被插在body里 -->
  <teleport to='body'>
    <!-- 过渡动画  添加了0.3s的淡入淡出  显得更加平滑 -->
    <transition name="base">
      <!-- 遮罩层 -->
      <div class="overly" :style="`z-index:${zIndex}`" v-if="show" @click='handleClick'></div>
    </transition>
  </teleport>
</template>

<script lang='ts'>
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'Overlay',
  props: {
    show: {
      type: Boolean,
      default: false,
    },
    zIndex: {
      type: Number,
      default: 2000,
    },
    closeOnClickModal: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['close'],
  setup(props, { emit }) {
    const handleClick = () => {
      if (props.closeOnClickModal) {
        emit('close');
      }
      return;
    };
    return {
      handleClick,
    };
  },
});
</script>

<style lang='scss'>
//此处省略部分CSS代码,详情请查看源码
//淡入淡出
.base-enter-active,
.base-leave-active {
  transition: all 0.3s ease;
}
.base-enter-to,
.base-leave-from {
  opacity: 1;
}
.base-enter-from,
.base-leave-to {
  opacity: 0;
}
</style>
组件中使用

配置close-on-click-modaltrue并传入一个close方法,就可以点击遮罩层关闭其他组件了(如Dialog),需要在close方法中手动的设置:show绑定的属性为false.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<overlay :show='dialogVisible' @close='onCancle' :close-on-click-modal='true'></overlay>

Dialog

展示

先看效果,点击的那个黄色圆圈是录屏软件自带的,不是我写的🤦‍♂️🤦‍♂️🤦‍♂️

属性
  • dialogVisible 是否展示弹窗
  • title 标题
  • width 宽度
  • top 距离顶部的位置设计思路/亮点 🌝和遮罩层绑定同一个值,可以在关闭弹窗的同时关闭遮罩层,也可以给遮罩层传递一个close方法,通过点击遮罩层关闭弹窗

🌝使用teleport将弹窗插入到.Dialog(class='Dialog')中,至于为什么要插入到这里,只是为了练习封装一个用来生成节点的hooks

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//创建DOM节点的hook函数 在body中插入一个自定义class的div节点 
//setup函数在执行时等同于created 所以没必要写入生命周期
import { onUnmounted } from 'vue';
const useDOMCreate = (nodeId: string): HTMLDivElement => {
  // 生成一个div的节点
  const node = document.createElement('div');
  // 给赋值一个class
  node.className = nodeId;
  // 在body中插入div节点
  document.body.appendChild(node);
  // 在组件卸载的时候移除dom节点
  onUnmounted(() => {
    document.body.removeChild(node);
  });
  return node;
};
export default useDOMCreate;

🌝使用transition添加了一个淡入淡出的过渡,并且有20px的位移,视觉效果更好

🌝组件本身分为三个部分,header就是一个标题,body部分是一个插糟,可以通过父组件添加一些内容进来,

footer部分是两个button,执行父组件的确认和取消回调.

代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <!-- 遮罩层 -->
  <overlay :show='dialogVisible' @close='onCancle' :close-on-click-modal='true'></overlay>
  <!-- 传送门  此处Dom节点会被插在.Dialog里 -->
  <teleport to='.Dialog'>
    <div class="dialog-box" v-bind='$attrs'>
      <!-- 过渡动画  添加了0.3s的淡入淡出  并且有20px的移动 显得更加平滑 -->
      <transition name="dialog">
        <div class="dialog-content" v-if='dialogVisible' :style="`width:${width};margin-top:${top}`">
          <!-- Dialog组件header部分 -->
          <div class="dialog-header">
            <h5 class="dialog-title">{{title}}</h5>
          </div>
          <!-- Dialog组件内容插槽 -->
          <slot>
          </slot>
          <!-- Dialog组件footer部分 -->
          <div class="dialog-footer">
            <wh-button @click="onConfirm" class="footer-btn" title='确认' :use-animation="true" :background-color="`rgba(160, 21, 114, 0.3)`"></wh-button>
            <wh-button @click="onCancle" class="footer-btn" title='取消' :use-animation="true"></wh-button>
          </div>
        </div>
      </transition>
    </div>
  </teleport>
</template>

<script lang='ts'>
//此处省略文件引用,详情请查看源码
export default defineComponent({
  components: {
    Overlay,
    WhButton,
  },
  name: 'Dialog',
  props: {
    dialogVisible: {
      type: Boolean,
      default: false,
    },
    title: {
      type: String,
      default: '提示',
    },
    width: {
      type: String,
      default: '400px',
    },
    top: {
      type: String,
      default: '15vh',
    },
  },
  emits: ['cancle', 'confirm'],
  setup(props, { emit }) {
    // 创建dom节点 .Dialog
    useDOMCreate('Dialog');
    // 关闭Dialog
    const onCancle = () => {
      emit('cancle');
    };
    const onConfirm = () => {
      emit('confirm');
    };
    return {
      onCancle,
      onConfirm,
    };
  },
});
</script>

<style lang='scss'>
//此处省略部分CSS代码,详情请查看源码
.dialog-enter-active,
.dialog-leave-active {
  transition: all 0.3s ease;
}
.dialog-enter-to,
.dialog-leave-from {
  opacity: 1;
}
.dialog-enter-from,
.dialog-leave-to {
  transform: translateY(-20px);
  opacity: 0;
}
</style>
组件中使用

正常传入属性使用即可,form组件作为内容插入,有关form组件可以点击这里查看我的另一篇文章

👉👉流莺书签-基础组件介绍(Form,Input)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- 添加单个书签的弹窗 -->
<Dialog :dialog-visible='isShowAddMarkDialog' @cancle='onCancle' @confirm='onConfirm' title='添加书签'>
  <wh-from ref='form'>
    </wh-from>
</Dialog>

Message

展示

先看效果,这里只展示了默认的情况,其实还有其他颜色的

属性
  • id 标识
  • type 类型
  • message 内容
  • duration 延迟消失的时间
  • offsetNumber 偏移量 设计思路/亮点 🌝使用transition添加了过渡效果,视觉效果拉满,淡入淡出,并且移动一个身位,通过传入的类型属性来绑定class达成不同颜色的效果

🌝使用的时候可以传入一个配置对象,或者一个字符串,如果是字符串最终还是会转换为对象

🌝使用fixed定位,距离顶部的偏移量通过message的数量来计算,所有的message存放在一个数组中,新增和移除一条message的时候就相应的操作数组,再根据 数组的长度 * 一个固定的高度 ,就可以算出每一条message的偏移量

🌝给实例添加一个销毁的方法,在transitionafter-leave周期中触发这个方法,在这个方法中操作数组删除数据,并修改props中的offsetNumber来造成视图的刷新.具体的查看下方代码以及源码.

代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//Message.vue
<template>
  <!-- 过渡效果 淡入淡出 并且移动一个身位 -->
  <transition name='message' @after-leave="$emit('destroy')">
    <div :class="classes" v-show='visiable' :style='styles' class="message">
      {{message}}
    </div>
  </transition>
</template>

<script lang='ts'>
//此处省略文件引用,详情请查看源码
export default defineComponent({
  name: 'Message',
  props: {
    id: {
      type: String,
      default: '',
    },
    type: {
      type: String as PropType<MessageType>,
      default: 'default',
    },
    message: {
      type: String,
      default: '这是一条提示',
    },
    duration: {
      type: Number,
      default: 2000,
    },
    offsetNumber: {
      type: Number,
      default: 0,
    },
  },
  setup(props) {
    const classes = computed(() => ['message-' + props.type]);
    const visiable = ref(false);
    let timer: any = null;
    const startTimer = () => {
      timer = setTimeout(() => {
        visiable.value = false;
      }, props.duration);
    };
    const styles = computed(() => {
      return { top: `${(props.offsetNumber - 1) * 55 + 20}px` };
    });
    // 组件渲染完了显示
    onMounted(() => {
      visiable.value = true;
      // 开启定时器
      startTimer();
    });
    onUnmounted(() => {
      clearTimeout(timer);
    });
    return {
      classes,
      visiable,
      styles,
    };
  },
});
</script>

<style lang='scss'>
//此处省略部分CSS代码,详情请查看源码
.message-enter-active,
.message-leave-active {
  transition: all 0.3s ease;
}
.message-enter-to,
.message-leave-from {
  opacity: 1;
}
.message-enter-from,
.message-leave-to {
  transform: translate(-50%,-100%);
  opacity: 0;
}
</style>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//index.ts
import Message from './Message.vue';
import { createVNode, render, VNode, reactive, computed } from 'vue';
// 类型
export type MessageType = 'success' | 'error' | 'default';
//一条消息的数据
export interface MessageOptions {
  id?: string;
  type?: MessageType;
  message?: string;
  duration?: number;
  offsetNumber?: number;
}

export type MessageParams = MessageOptions | string;
export type MessageList = MessageOptions[];

// 存放所有的message实例  用来计算偏移量
const instances = reactive<VNode[]>([]);
const offsetNumber = computed(() => instances.length + 1);
const createMessage = (options: MessageParams) => {
  // 如果参数是string类型,就把它转换为options对象
  if (typeof options === 'string') {
    options = {
      message: options,
    };
  }
  // 把组件创建为虚拟节点  也就是一个组件实例
  const vnode = createVNode(Message, {
    ...options,
    offsetNumber: offsetNumber.value,
  });

  // 创建一个容器
  const container = document.createElement('div');

  // 把实例渲染到容器里
  render(vnode, container);
  // 将渲染后的结果 放到body上
  // 因为会多一个div 所以插入第一个孩子
  // 为什么不直接放到body里,要创建一个容器再取里面的内容呢   为了销毁组件 如果直接放在body里,就清空所有节点了
  document.body.appendChild(container.firstElementChild!);
  instances.push(vnode);
  // 给实例添加一个销毁方法
  vnode.props!.onDestroy = () => {
    instances.shift();
    instances.forEach((item: any) => {
      item.component.props.offsetNumber -= 1;
    });
    // 移除dom
    render(null, container);
  };
};

export default createMessage;
组件中使用

函数式调用,传入配置对象,或者传入一个字符串即可

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//此处省略文件引用
createMessage({ type: 'success', message: '添加标签成功!' });

写在最后

请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.

✅认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式

✅认为我部分代码过于老旧,可以提供新的API或最新语法

✅对于文章中部分内容不理解

✅解答我文章中一些疑问

✅认为某些交互,功能需要优化,发现BUG

✅想要添加新功能,对于整体的设计,外观有更好的建议

最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧

链接整合

🔊项目预览地址(GitHub Pages):👉👉https://alanhzw.github.io

🔊项目预览备用地址(自己的服务器):👉👉http://warbler.duwanyu.com

🔊源码地址(gitee):👉👉https://gitee.com/hzw_0174/WarblerHomepage

🔊源码地址(github):👉👉https://github.com/alanhzw/WarblerHomepage

🔊项目整体介绍:👉👉https://cloud.tencent.com/developer/article/2190018

🔊流莺书签-从零搭建一个Vite+Vue3+Ts项目:👉👉https://cloud.tencent.com/developer/article/2190014

🔊流莺书签-基础组件介绍(Form,Input):👉👉https://cloud.tencent.com/developer/article/2190015

🔊流莺书签-基础组件(Button,Overlay,Dialog,Message):👉👉https://cloud.tencent.com/developer/article/2190017

🔊流莺书签-业务组件介绍:👉👉暂无

🔊我的博客:👉👉https://www.duwanyu.com

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
matplotlib 入门使用指南
1. pyplot模块 1.1. color的值 blue 1.2. Marker的值 point marker 1.3. LineStyles的值 solid line style 例子: 'b' # blue markers with default shape 'ro' # red circles 'g-' # green solid line '--' # dashed line with default color 'k^:' # black triangle_up mark
syy
2020/04/07
9920
Matplotlib使用笔记
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
村雨遥
2019/09/09
5750
python学习之matplot
import matplotlib.pyplot as plt import numpy as np import pandas as pd from mpl_toolkits.mplot3d import Axes3D import matplotlib.gridspec as gridspec from matplotlib import animation
py3study
2020/01/08
8010
Matplotlib新手上路(中)
接上回继续 一、多张图布局(subplot) 1.1 subplot布局方式 import matplotlib.pyplot as plt plt.figure() plt.subplot(3, 2, 1) # 3行2列的第1张图 plt.plot([0, 1], [0, 1]) plt.subplot(322) # 等效于plt.subplot(2,2,2) 3行2列的第2张图 plt.plot([1, 1], [0, 2]) plt.plot([0, 2], [1, 1]) plt.sub
菩提树下的杨过
2018/03/28
7540
Matplotlib新手上路(中)
matplotlib入门
MATlAB是美国MathWorks公司出品的商业数学软件,用于数据分析、无线通信、深度学习、量化金融与风险管理、机器人,控制系统等领域。MATLAB在数值计算方面首屈一指,也是使用最广泛的科研绘图软件之一。优点:编程效率高 便于矩阵计算。缺点:循环效率低 封装性不好。
用户2225445
2022/11/12
4.5K0
matplotlib入门
pycharm使用matplotlib绘图学习笔记「建议收藏」
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/174663.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/27
5140
Matplotlib
Matplotlib 官网 此篇笔记参考来源为《莫烦Python》 安装同之前所述,参考《Python初学基础》 基本使用 2.1 基本用法 import matplotlib.pyplot as plt import numpy as np x = np.linspace(-1, 1, 50) #使用np.linspace定义x:范围是(-1,1);个数是50 y = 2*x + 1 plt.figure() #定义一个图像窗口 plt.plot(x, y) plt.show()
闪电gogogo
2018/05/28
1.2K0
matplotlib安装及使用
matplotlib是基于python语言的开源项目,旨在为python提供一个数据绘图包。我将在这篇文章中介绍matplotlib API的核心对象,并介绍如何使用这些对象来实现绘图。实际上,matplotlib的对象体系严谨而有趣,为使用者提供了巨大的发挥空间。用户在熟悉了核心对象之后,可以轻易的定制图像。matplotlib的对象体系也是计算机图形学的一个优秀范例。即使你不是python程序员,你也可以从文中了解一些通用的图形绘制原则。matplotlib使用numpy进行数组运算,并调用一系列其他的python库来实现硬件交互。matplotlib的核心是一套由对象构成的绘图API。
狼啸风云
2023/10/07
5390
matplotlib安装及使用
Matplotlib可视化Pyplot Tutorial
MATLAB, and pyplot, have the concept of the current figure and the current axes. All plotting commands apply to the current axes. The function gca() returns the current axes (a matplotlib.axes.Axes instance), and gcf() returns the current figure (matplotlib.figure.Figure instance).
用户2183996
2018/06/28
6580
Python数据分析之matplotlib(提高篇)
matplotlib核心剖析(http://www.cnblogs.com/vamei/archive/2013/01/30/2879700.html#commentform)
AI异构
2020/07/29
6580
Python数据分析之matplotlib(提高篇)
Python数据分析Matplotlib
1.2 使用matplotlib.pyplot中的annotate()函数标注文字
荣仔_最靓的仔
2021/02/02
3.6K0
Python数据分析Matplotlib
python matplotlib各种绘图类型完整总结
plot([x], y, [fmt], [x2], y2, [fmt2], …, **kwargs)
Twcat_tree
2022/12/05
6K0
python matplotlib各种绘图类型完整总结
matplotlib相关图形绘制(一)
  折线图用于显示随时间或有序类别而变化的趋势。折线图其实是由多个点连接在一起得到了,当点足够多的时候,折线图就变成了平滑的曲线。
朱小五
2020/03/05
1.1K0
matplotlib相关图形绘制(一)
Python如何使用Matplotlib的作图
Matplotlib官网 如果想了解更多可查看官网。 import numpy as np import matplotlib.pyplot as plt %matplotlib inline #写了这个就可以不用写plt.show() plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签 plt.rcParams['axes.unicode_minus']=False #用来正常显示负号 X = np.linspace(0, 2*np.pi,1
Python研究者
2020/09/28
1.4K0
Python如何使用Matplotlib的作图
Matplotlib Pyplot教程
最近自己经常遇到matplotlib的OO API和pyplot包混乱不分的情况,所以抽时间好好把matplotlib的文档读了一下,下面是大概的翻译和总结。很多基础的东西还是要系统地掌握牢固哇~~另外一篇翻译是
曲奇
2021/12/14
7370
Matplotlib Pyplot教程
Python数据分析实战(3)Python实现数据可视化
数据可视化是指将数据放在可视环境中、进一步理解数据的技术,可以通过它更加详细地了解隐藏在数据表面之下的模式、趋势和相关性。
cutercorley
2020/08/31
4.6K0
数据分析画图:50道练习玩转matplotlib
Matplotlib 是 Python 的绘图库。它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案,也可以和图形工具包一起使用。和Pandas、Numpy并称为数据分析三兄弟。友情提示:代码虽好,自己动手才算学到。
Datawhale
2020/02/21
8820
python通过Matplotlib绘制常见的几种图形
使用matplotlib对几种常见的图形进行绘制 Matplotlib官网 如果想了解更多可查看官网。 import numpy as np import matplotlib.pyplot as plt %matplotlib inline #写了这个就可以不用写plt.show() plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签 plt.rcParams['axes.unicode_minus']=False #用来正常显示负号 X
Python研究者
2021/08/23
8940
Matplotlib 1.4W+字基础教程来了(收藏吃灰去吧~~)
参考:Rougier N P, Droettboom M, Bourne P E, et al. Ten Simple Rules for Better Figures[J]. PLOS Computational Biology【IF 4.7】, 2014, 10(9).感兴趣戳:https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4161295/pdf/pcbi.1003833.pdf
DataCharm
2021/02/22
1.5K0
Matplotlib 1.4W+字基础教程来了(收藏吃灰去吧~~)
Python基础(十二) | 还不会python绘图?两万字博文教你Matplotlib库(超详细总结)
https://matplotlib.org/api/_as_gen/matplotlib.pyplot.plot.html#matplotlib.pyplot.plot
timerring
2022/10/08
2.5K0
Python基础(十二) | 还不会python绘图?两万字博文教你Matplotlib库(超详细总结)
相关推荐
matplotlib 入门使用指南
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验