微前端系列讲解--应用集成方案(qiankun+umi+vue)_umi vue_无翼之雀的博客-CSDN博客


本站和网页 https://blog.csdn.net/w544924116/article/details/120105320 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

微前端系列讲解--应用集成方案(qiankun+umi+vue)_umi vue_无翼之雀的博客-CSDN博客
微前端系列讲解--应用集成方案(qiankun+umi+vue)
无翼之雀
已于 2022-03-30 14:32:51 修改
4915
收藏
14
分类专栏:
微前端
Ant Design Pro
umi
文章标签:
react
vue
大前端
于 2021-09-24 22:40:12 首次发布
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/w544924116/article/details/120105320
版权
微前端
同时被 3 个专栏收录
3 篇文章
0 订阅
订阅专栏
Ant Design Pro
6 篇文章
1 订阅
订阅专栏
umi
4 篇文章
0 订阅
订阅专栏
1. 微前端项目架构及选型介绍 
1.1. 微前端选型概述
微前端架构是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。考虑到qiankun作为蚂蚁的微前端架构,具备以下特点:①简单。子应用接入像使用接入一个 iframe 系统一样简单,但实际不是 iframe。②能力完备。几乎包含所有构建微前端系统时所需要的基本能力,如样式隔离、js 沙箱、预加载等。③健壮性值得信赖。在蚂蚁内外经受过足够大量的线上系统的考验及打磨。所以,选择qiankun去构建集成应用项目的微前端架构。
1.2. 项目简要
本文配合实战demo讲解微前端项目和集成方案。
【技术选择】
主应用:umi(Ant Design Pro)
子应用:umi(Ant Design Pro)、vue(vue-element-admin)
路由模式:都用hash
【源码地址】qiankun-demohttps://gitee.com/weihui007/qiankun-demo
2. 微前端基础配置
2.1. 主应用qiankun配置(umi项目)
(1)安装插件
yarn add @umijs/plugin-qiankun -D
 (2)注册子应用
插件构建期配置子应用
export default {
qiankun: {
master: {
apps: [
name: 'reactApp', // 唯一 id
entry: 'http://localhost:8091', // html entry
},
name: 'vueApp',
entry: 'http://localhost:8092',
},
],
},
},
};
 (3)装载子应用
使用路由绑定的方式
export default {
routes: [
// 配置子应用reactApp关联的路由
name: 'react子应用',
path: '/subreact',
microApp: 'reactApp',
},
// 配置子应用vueApp关联的路由
name: 'vue子应用',
path: '/subvue',
microApp: 'vueApp',
},
],
};
2.2. 子应用qiankun配置
2.2.1. vue项目
(1)入口文件main.js
子应用需要在自己的入口文件导出 bootstrap、mount、unmount 三个生命周期钩子,以供主应用在适当的时机调用。
bootstrap:只会在子应用初始化的时候调用一次,下次子应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
mount:应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法。
unmount:应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载子应用的应用实例
// 声明一个变量,可以用于卸载
let instance = null
// 挂载到自己的html中,基座会拿到这个挂载后的html插入进去
function render(props = {}) {
const { container } = props
instance = new Vue({
router,
store,
render: h => h(App)
}).$mount(container ? container.querySelector('#app') : '#app')
// 独立运行
if (!window.__POWERED_BY_QIANKUN__) {
render()
// 子组件的协议,必须暴露三个函数
export async function bootstrap(props) {
console.log('bootstrap函数:', props)
export async function mount(props) {
console.log('mount函数:', props)
render(props)
export async function unmount(props) {
console.log('unmount函数:', props)
instance.$destroy()
instance = null
(2)配置文件vue.config.js
除了代码中暴露出相应的生命周期钩子之外,为了让主应用能正确识别子应用暴露出来的一些信息,子应用的打包工具需要增加如下配置
//修改打包配置
configureWebpack: {
output: {
//输出暴露的名称,假设名称为vueApp
library: 'vueApp', //输出暴露的类型
libraryTarget: 'umd'
},
//允许跨域
devServer: {
headers: {
'Access-Control-Allow-Origin': '*'
},
2.2.2. react项目(umi项目)
(1)安装 qiankun 插件 @umijs/plugin-qiankun
$ npm i @umijs/plugin-qiankun  
# 或者
$ yarn add @umijs/plugin-qiankun
(2)插件注册(config.ts)
export default {
qiankun: {
slave: {}
(3)配置运行时生命周期钩子(可选)
插件会自动为你创建好 qiankun 子应用需要的生命周期钩子,但是如果你想在生命周期期间加一些自定义逻辑,可以在子应用的 src/app.ts 里导出 qiankun 对象,并实现每一个生命周期钩子,其中钩子函数的入参 props 由主应用自动注入。
export const qiankun = {
// 应用加载之前
async bootstrap(props) {
console.log('bootstrap函数:', props)
},
// 应用 render 之前触发
async mount(props) {
console.log('mount函数:', props)
},
// 应用卸载之后触发
async unmount(props) {
console.log('unmount函数:', props)
2.3. 主子应用实现通信配置
2.3.1. 主应用umi项目
(1)向umi子应用通信
 ① 新建src->app.ts文件
import { useState } from 'react';
export function useQiankunStateForSlave() {
const [projectId, setProjectId] = useState<string>('');
return { projectId, setProjectId };
② 在组件中使用qiankunStateForSlave
import { useModel } from 'umi';
export function ProComp() {
const { setProjectId } = useModel('@@qiankunStateForSlave');
const onChangePro = () => {
setProjectId('123');
};
return <button onClick={onChangePro}>更改项目信息</button>;
(2)向vue子应用通信
 ① 新建src->action.ts文件
import { initGlobalState } from 'qiankun';
const initialState = {
// 初始化数据
projectId: ''
};
// 初始化 state
const actions = initGlobalState(initialState);
export default actions;
② 在组件中使用actions
import actions from '@/actions';
export function ProComp() {
const onChangePro = () => {
actions.setGlobalState({ projectId: '123' });
};
return <button onClick={onChangePro}>更改项目信息</button>;
2.3.2. 子应用vue项目
使用qiankun 官方提供的通信方式 - Actions 通信去实现
(1)新建src->actions.js文件
function emptyAction() {
//设置一个actions实例
// 提示当前使用的是空 Action
console.warn('Current execute action is empty!')
class Actions {
// 默认值为空 Action
actions = {
onGlobalStateChange: emptyAction,
setGlobalState: emptyAction
/**
* 设置 actions
*/
setActions(actions) {
this.actions = actions
/**
* 映射,注册观察者函数,响应 globalState 变化
*/
onGlobalStateChange(...args) {
return this.actions.onGlobalStateChange(...args)
/**
* 映射,设置 globalState
*/
setGlobalState(...args) {
return this.actions.setGlobalState(...args)
const actions = new Actions()
export default actions
(2)入口文件main.js
在mounted的生命周期里注入actions实例
import actions from './actions'
export async function mount(props) {
actions.setActions(props) //注入actions实例
render(props)
(3)使用范例
<template>  
  <div>  
    <div>这是子应用</div>  
    <p>接收到的消息: {{mes}}</p>  
    <button @click= "btnClick">点击向父应用发送消息</button>  
  </div>  
</template>  
<script>  
import actions from '../actions'//导入实例  
export default {  
  data() {  
    return {  
      mes: '',  
    }  
  },  
  mounted() {  
    actions.onGlobalStateChange((state) => { //监听全局状态  
      this.mes = state  
    }, true);  
  },  
  methods:{  
    btnClick(){  
      actions.setGlobalState({ info: '123'})//改变全局状态  
    }  
  }  
}  
</script>  
2.3.3. 子应用umi项目
使用useModel钩子函数 
import { useModel } from 'umi';
function MyPage() {
const masterProps = useModel('@@qiankunStateFromMaster');
return <div>{JSON.stringify(masterProps)}</div>;
3. 微前端项目集成方案
本文利用微前端架构主要实现如下功能:
把不同项目(子应用)集成到一个平台(主应用)。
【顶部导航栏】可包含主应用页面以及各个子应用,子应用可以是任何技术栈(demo中子应用为react和vue)。
【侧边菜单导航栏】可以是主应用页面的子菜单,也可以是子应用的菜单。
【主内容区域】即为页面主要展示区域。若当行了选择的是子应用,即为子应用展示区域。
具体实现效果如下图:
3.1. 主应用改造
主应用为antd pro项目。菜单模式设置为mix(混合菜单),记得切割菜单,即配置splitMenus为true。通过上述配置结合路由配置,即可实现上述平台布局(顶部全局导航+侧边菜单导航混合)。
路由数据结构(routes.ts)参考如下:
export default [
name: '欢迎', // 主应用页面1,在顶部全局导航展示
path: '/welcome',
icon: 'smile',
component: './Welcome',
},
name: '管理页', // 主应用页面2,在顶部全局导航展示
path: '/admin',
icon: 'crown',
access: 'canAdmin',
component: './Admin',
routes: [ // 二级菜单,在侧边菜单导航展示
name: '二级管理页',
path: '/admin/sub-page',
icon: 'smile',
component: './Welcome',
},
],
},
name: 'react子应用', // 子应用1,在顶部全局导航展示
path: '/subreact',
microApp: 'reactApp',
routes: [ // 子应用1的菜单,在侧边菜单导航展示
name: 'Welcome',
icon: 'smile',
path: '/subreact/Welcome',
},
],
},
name: 'vue子应用', // 子应用2,在顶部全局导航展示
path: '/subvue',
microApp: 'vueApp',
routes: [ // 子应用2的菜单,在侧边菜单导航展示
name: 'Example',
icon: 'table',
path: '/subvue/example',
routes: [
name: 'Table',
icon: 'table',
path: '/subvue/example/table',
},
],
},
],
},
];
3.2. 子应用改造
根据window.__POWERED_BY_QIANKUN__判断子应用是不是从qiankun运行环境进来的,进行两套环境改造。如果独立运行,则走原来的逻辑,否则需要走改造后的逻辑。 
3.2.1. 布局改造
如果子应用是从qiankun运行环境进入,即window.__POWERED_BY_QIANKUN__为true,则去除子应用头部和导航菜单布局。
umi子应用:删除掉所有的自带界面,将ProLayout布局组件设置pure为true。 
vue子应用(vue-element-admin): 用条件语句v-if、v-else判断,如果是qiankun环境,则只保留主内容区域。
3.2.2. 登录逻辑改造
把登录权限打通,主应用登录后,切换到子应用不需要再进行登录校验,实现免登录功能。
比如主应用是通过cookie验证用户登录的,当子应用是从qiankun环境进入,则通过对应的cookie判断是否有登录,若已登录则跳过登录直接进入对应页面,若没登录或者登录失效则传值给父应用告诉父应用需要重新登录,然后父应用跳转登录页(可在响应拦截中进行父子应用通讯,实现接口回传token失效等原因告诉父应用需要跳转登录页)。
3.2.3. 其它改造
(1)子应用为vue项目需要判断qiankun环境把路由加上前缀
一般需要修改2个地方:①路由表加上前缀;②路由守卫判断如果没有前缀需加上前缀(用于子应用内部需要做路由跳转) 
TIPS:前缀指在主应用中跳转子应用设定的path值。
①参考如下:
如果是qiankun环境,则给路由数据的path(路径)和redirect(重定向)值加上前缀。这样就可以和主应用项目对应的菜单导航栏的跳转路径保持一致。
if (window.__POWERED_BY_QIANKUN__) {
routesData.map(item => {
if (item.path.includes('/')) {
item.path = '/subvue' + item.path
if (item.redirect) {
item.redirect = '/subvue' + item.redirect
return item
})
②参考如下:
如果是qiankun环境,则通过路由守卫 beforeEach对路由跳转前进行判断拦截,如果,跳转的地址没有加有前缀,则加上。否则,会出现404找不到页面。
if (window.__POWERED_BY_QIANKUN__) {
  router.beforeEach((to, from, next) => {
    if (!to.path.includes('subvue')) {
      next({
        path: '/subvue' + to.path,
        query: to.query
      })
    } else {
      next()
    }
  })
(2)其它
除上述提到的,可以根据自身业务需求进行一些改造,常见的有网络请求封装改造、菜单按钮展示改造以及资源加载路径改造等等。 
4. 应用集成逻辑图
仅以umi版本为例,展示如下
【推荐文章】
antd pro项目使用qiankun,loading加载页不消失https://blog.csdn.net/w544924116/article/details/120164997antd pro(ProLayout) mix混合菜单不生效https://blog.csdn.net/w544924116/article/details/120211891Error: Module “xxx“ does not exist in container. / antd pro v5启用qiankun报错 / 同时使用mfsu和qiankun报错https://blog.csdn.net/w544924116/article/details/120123331引用window自定义变量以及ts在window上自定义变量数据类型报错的解决方案https://blog.csdn.net/w544924116/article/details/120251686
感谢您读完本文!如果本文对您有帮助,请点个赞呗,您的点赞是对我最大的支持和认可!
我的公众号:大前端教程,欢迎关注,会定期更新前端知识,希望能帮到您。
无翼之雀
关注
关注
10
点赞
14
收藏
打赏
知道了
评论
微前端系列讲解--应用集成方案(qiankun+umi+vue)
1. 微前端架构介绍微前端架构是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。考虑到qiankun作为蚂蚁的微前端架构,具备以下特点:①简单。微应用接入像使用接入一个 iframe 系统一样简单,但实际不是 iframe。②能力完备。几乎包含所有构建微前端系统时所需要的基本能力,如样式隔离、js 沙箱、预加载等。③健壮性值得信赖。在蚂蚁内外经受过足够大量的线上系统的考验及打磨。所以,选择qiankun去构建集成应用项目的微
复制链接
扫一扫
专栏目录
umiJS
03-21
umiJS
项目实战之aiguibin-protal-gateway集成门户
AIguibin的博客
01-24
47
本项目为个人门户,意在把自己学到的东西通过实战的方式复习总结起来。整合多个前端微服务实现登陆功能,配合后端微服务根据登录人的权限,展示不同的前端微服务。
参与评论
您还未登录,请先
登录
后发表或查看评论
Umi4搭建vue项目(vue3)
YanHSama的博客
07-04
1824
umi4创建vue项目
使用umi4+qiankun 搭建微前端项目
最新发布
瑾白芨的博客
02-15
220
首先新建空文件夹在里面新建master 文件, 使用一下命令创建主应用;当项目初始化完成后使用打开页面 项目创建成功重复以上步骤 创建子应用appA, appB;
在vue项目上使用阿里qiankun ——项目部署篇(三)
前端李小白的博客
08-08
967
qiankun官方文档部署教程
官方文档写的也挺详细的,这里我主要以统一身份认证与盐田综管部署举例说明,我部署的服务器地址http://192.168.8.27:8077
首先要注意的是,我们主应用和子应用都是使用history模式,路由记得设置base,vue.config.js也要记得设置publicPath。
引用文档的原话:
部署之后注意三点:
1、activeRule不能和微应用的真实访问路径一样,否则在主应用页面刷新会直接变成微应用页面。
2、微应用的真实访问路径就是微应用的entry,entr
convue是基于vite和vue3的vite插件,可为您提供一系列快速开发项目的经验,类似于nuxt和umi.js。-JavaScript开发
05-26
convue convue是基于vite和vue3的vite插件,可为您提供一系列快速开发项目的经验,类似于nuxt和umi。
convue convue是基于vite和vue3的vite插件,为您提供了一组快速开发项目的经验,类似于nuxt和umi.js.参考文档:https://ziping-li.github.io/convue/。
动机和优势umi.js目前不支持vue,并且nuxt尚未完全支持vue3和vite。
convue是vite的插件,它更接近于正式的vue基础生态系统,并且可以与其他基础库完美集成。
convue只是一个开发者
@umijs/plugin-qiankun
weixin_43758377的博客
03-23
1823
主应用
第一步:配置插件
export default {
plugins: [
'@umijs/plugin-qiankun', // 1.8 version
master: { ...masterOptions },
},
],
],
};
第二步:配置子应用
子应用的配置方式(二选一):
export default {
plugins: [
'@umijs/plugin-qiankun'
微前端——qiankun
to_prototy的博客
12-07
148
微前端-qiankun案例以及应用之间通信
基于umijs/plugin-qiankun 的微前端 配置(vue+umi)
weixin_45701199的博客
04-22
3627
qiankun + umi 配置
微前端umi + qiankun从搭建到部署的实践
Mine____的博客
07-01
2116
近期在项目中需要使用qiankun实现微前端的微服务化,分享记录一下搭建的过程以及遇到的问题
项目框架
整体为umi搭建的主应用,两个子应用均为create-react-app搭建,进入系统,菜单main为主应用页面,点击菜单sub-react切换第一个子应用,菜单sec-sub切换第二个子应用,
项目根目录下是主应用,child文件夹下为子应用sub-react,sec-sub,搭建后的初始目录结构如下:
主应用配置
非umi搭建主应用
主应用负责导航的渲染和登录态的下发,为子应用提供一个挂载的容器
微前端实践-实现React(umi框架)的子系统集成
astonishqft的博客
02-23
3190
问题引入
最近在公司遇到了一个需求,别的团队的同事想将他们用 React 编写的工程作为子系统集成到我们已有的系统中,React 工程是基于 umi 框架编写的,我们的主系统是基于 jquery 框架实现的。其实他们本来是已经实现了 React 作为子系统集成到我们的主系统中的,但是他们是借助于 iframe 实现页面嵌入的,后来因为用户体验不佳、存在安全性问题等因素而不得不放弃这种方式的集成了。...
双Umi项目使用qiankun嵌套步骤
weixin_42027605的博客
08-03
1471
双Umi项目使用qiankun嵌套步骤
写在前面
官方文档写的简简单单却暗藏玄机,所以从使用者的角度来说感觉有一些会被忽略的点没有被重点突出,所以记录一下我用双Umi项目进行主/子应用的嵌套。我最开始参考的文章是:AntdPro(主)+Umi使用qiankun搭建主/子应用: link. 是可以成功,但是当我使用umi的时候,把子应用放在主应用中一个组件的子路由中激活的时候出现了问题,所以记录一下搭建步骤。
准备
主应用为Umi项目, 子应用为Umi项目。默认各位巨佬已经创建umi项目与安装qiankun插
vue-cli-plugin-qiankun:适用于微前端千库应用程序的vue-cli3插件
05-05
* vue-cli-plugin-qiankun*
An Vue-cli3 Plugin for micro-frontend qiankun application
结合 qiankun 快速生成微前端应用的脚手架插件
Features
qiankun 接入,子应用打包配置接入
修改 qiankun 官网 demo 中 vue 子应用 public 下静态资源加载不出来的问题
主应用和子应用中基础的路由处理
demo 中增加了父子组件之间通信的示例
IE下的兼容显示(关闭jsSandbox,fetch 增加 pollyfill)
Demo
Setup
主应用生成方式
vue create portal
cd portal
vue add vue-cli-plugin-qiankun-portal
子应用生成方式
vue create demo1
cd demo1
vue add vue-
微前端 umi-qiankun
weixin_43924896的博客
06-21
1057
主应用一定要配置
qiankun: {
master: {
},
},
此时,一定要有apps的配置,至少是个[] 否则会报错
而微应用要配置:
qiankun: {
slave: {},
},
microAppMain:antd pro of vue + qiankun搭建的主应用
05-29
microAppMain
antd pro of vue + qiankun,子应用请参考
账号:admin/admin
安装依赖
npm install
开发模式运行
npm run serve
编译项目
npm run build
Lints and fixes files
npm run lint
使用vite-plugin-qiankun插件, 将应用快速接入乾坤(vue3 vite)
weixin_47541876的博客
01-12
381
微前端qiankun使用vite-plugin-qiankun接入Vite子应用(vue3 vite)
vue.js 脚手架
07-31
该代码为vue脚手架源码,也可以自己搭建,步骤简单,点击dev.bat即运行
umi4+vue3项目中添加iconfont图标
wangzhicheng0304的博客
09-09
662
现在这个项目用的是umi4+vue3,之前一直用是的umi+react,所以想换下vue来开发,这个项目算是第一次使用vue,因为用umi习惯了,所以还是用它,加上umi4也支持vue了,umi4的配置有点不一样了,所以与vue3一起都是摸索着开发。页面上应该有显示的图标了,当然也可以不用Font class引入,直接下载到本地,应该也是可以的,我就没有去试了,欢迎大家去尝试。我放了一个umi+vue的demo在github上,大家可以看看。下面还是开始讲我是怎么添加iconfont上的图标的。
umi+qiankun微前端(2022/3/7 百分百成功搭建)
luweisixsix的博客
03-07
2373
umi + qiankun 微前端的基本搭建
umi项目中qiankun插件的使用
weixin_44941425的博客
09-28
289
微前端qiankun在umi中的使用
前端使用qiankun搭建微应用框架
sg_knight的专栏
04-24
1437
1、主应用配置
1.1 安装qiankun插件
yarn add @umijs/plugin-qiankun -D
1.2 在主应用中配置子应用
在配置文件config中配置qiankun相关参数
//config.ts
import micro from './micro';
const { REACT_APP_ENV } = process.env;
export default defineConfig({
qiankun: micro[REACT_APP_E...
“相关推荐”对你有帮助么?
非常没帮助
没帮助
一般
有帮助
非常有帮助
提交
无翼之雀
CSDN认证博客专家
CSDN认证企业博客
码龄10年
暂无认证
36
原创
9万+
周排名
179万+
总排名
13万+
访问
等级
762
积分
165
粉丝
180
获赞
24
评论
417
收藏
私信
关注
热门文章
umi3.5新特性之提速方案mfsu
14104
react函数式组件传值之子传父
14089
引用window自定义变量以及ts在window上自定义变量数据类型报错的解决方案
9400
Centos(Linux)升级git最新版本
9347
GitLab服务器修改管理员用户root密码
8782
分类专栏
Ant Design Pro
6篇
umi
4篇
微前端
3篇
JS
8篇
git
5篇
GitLab
8篇
react
11篇
TS
1篇
ES6
1篇
自动化部署
2篇
Linux
5篇
服务器搭建
4篇
centos
3篇
NodeJs
1篇
最新评论
react函数式组件传值之子传父
webs9527:
你这不是父传子一个方法吗,然后子去修改父的值。
antd pro(ProLayout) mix混合菜单不生效
booxiong:
增加一个参数而已
gitlab+gitlab-runner实现前端项目自动化构建部署(CI/CD、Linux、Centos7)
Daniel_jianer:
不太理解 build后的静态资源在哪里
我gitlab ng 全部都是本地搭建的
没有虚拟机
react函数式组件传值之子传父
蓝willy:
感谢感谢,没用过react不知道怎么传函数,这篇文章真的帮了我大忙,非常感谢!!!
react函数式组件传值之子传父
m0_62106552:
应该可以直接掉函数,就不需要事件了
您愿意向朋友推荐“博客详情页”吗?
强烈不推荐
不推荐
一般般
推荐
强烈推荐
提交
最新文章
for循环、for of、for in、forEach、map、filter、every、some、reduce遍历的用法(区别)
JS双击触发2次单击问题解决方案/js区分单击和双击/连续点击事件
localstorage封装(增加缓存前缀、有效时间、数据类型处理等)--实战必备
2021年36篇
目录
目录
分类专栏
Ant Design Pro
6篇
umi
4篇
微前端
3篇
JS
8篇
git
5篇
GitLab
8篇
react
11篇
TS
1篇
ES6
1篇
自动化部署
2篇
Linux
5篇
服务器搭建
4篇
centos
3篇
NodeJs
1篇
目录
评论
被折叠的 条评论
为什么被折叠?
到【灌水乐园】发言
查看更多评论
添加红包
祝福语
请填写红包祝福语或标题
红包数量
红包个数最小为10个
红包总金额
红包金额最低5元
余额支付
当前余额3.43元
前往充值 >
需支付:10.00元
取消
确定
下一步
知道了
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝
规则
hope_wisdom 发出的红包
打赏作者
无翼之雀
你的鼓励将是我创作的最大动力
¥2
¥4
¥6
¥10
¥20
输入1-500的整数
余额支付
(余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付
您的余额不足,请更换扫码支付或充值
打赏作者
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额
抵扣说明:
1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。
余额充值