Bingo介绍
NutBingo组件是由京东平台开发的抽奖组件库,基于 NutUI 的抽奖组件库,助力营销活动和小游戏场景。
官方参考文档
github库
特性
- 12 个抽奖组件(大转盘、跑马灯、九宫格、刮刮卡、神秘大礼盒、摇奖机、砸金蛋、红包雨、摇一摇、娃娃机、摇骰子、你藏我猜)
- 基于京东APP 10.0 视觉规范
- 详尽的文档和示例
- 支持 TypeScript
- 灵活的自定义设置
注:目前官方的组件库只支持h5,目前官方描述小程序还在适配中
集成到微信小程序
本项目同样是采用京东的nutui-taro 4.x框架集成vue3开发微信小程序;
NutUI-Vue 组件库,基于 Taro,使用 Vue 技术栈开发小程序应用,开箱即用,帮助研发快速开发用户界面,提升开发效率,改善开发体验。
从现有的文档内未找到有关小程序的集成方案,本方案就集成微信小程序中使用进行了尝试,发现基础功能通过修改后,基本上能够使抽奖类组件集成在nut-taro框架中运行;
nutui-taro 4.x官方参考文档
安装nutbingo
本文以npm安装为示例,官方也推存:“我们推荐使用 NPM 或 YARN 方式安装,不推荐在页面中直接引入的用法”
npm下安装
# Vue3
npm i @nutui/nutui-bingo
安装提示完毕后,在package.json文件中能看到组件版件信息,即表示安装到项目中
"@nutui/nutui-bingo": "^1.0.7",
npm使用示例
import { createApp } from "vue";
import App from "./App.vue";
import NutBig from "@nutui/nutui-bingo";
import "@nutui/nutui-bingo/dist/style.css";
createApp(App).use(NutBig).mount("#app");
注:这种方式将导入所有组件
推荐按需使用按需加载
import { createApp } from "vue";
import App from "./App.vue";
import { Turntable } from "@nutui/nutui-bingo";
import "@nutui/nutui-bingo/dist/style.css";
createApp(App).use(Turntable).mount("#app");
小程序项目引入
在app.ts中加入抽奖营销组件,如:Marquee(跑马灯)
import { createApp } from 'vue'
import './app.scss'
// npm i --sever @nutui/nutui-bingo
import { Marquee } from "@nutui/nutui-bingo"
import "@nutui/nutui-bingo/dist/style.css";
const app = createApp({});
app.use(Marquee );
export default app
创建小程序页面
从命令行进入到系统盘符,再进入到项目保存的目录中,比如:gwApp,执行taro命令创建draw小程序页面
$ taro create --name draw
👽 Taro v3.6.1
✔ 创建文件: D:\Workspaces\taro\gwApp\src\pages\draw\index.vue
✔ 创建文件: D:\Workspaces\taro\gwApp\src\pages\draw\index.config.ts
✔ 创建页面 draw 成功!
在VSCode中打开页面,删除无关的自动创建的代码,复制Nut-Bigo官方的Marquee跑马灯组件示例代码;
<template>
<nutbig-marquee
:prize-list="prizeList"
:prize-index="prizeIndex"
:speed="100"
:circle="40"
@start-turns="startTurns"
@end-turns="endTurns"
>
</nutbig-marquee>
</template>
<script>
import { ref, reactive, toRefs } from 'vue';
import { Dongdong } from '@nutui/icons-vue-taro';
import NutBig from '@nutui/nutui-bingo';
export default {
name: 'draw',
components: {
Dongdong,
NutBig
},
setup() {
// 转盘上要展示的奖品数据
const prizeList = ref([
{
id: "xiaomi",
prizeName: "小米手机",
prizeImg:
"https://img14.360buyimg.com/imagetools/jfs/t1/104165/34/15186/96522/5e6f1435E46bc0cb0/d4e878a15bfd9362.png",
},
{
id: "blue",
prizeColor: "rgb(251, 219, 216)",
prizeName: "蓝牙耳机",
prizeImg:
"https://img13.360buyimg.com/imagetools/jfs/t1/91864/11/15108/139003/5e6f146dE1c7b511d/1ddc5aa6e502060a.jpg",
},
{
id: "thanks",
prizeName: "谢谢参与",
prizeImg:
"https://img11.360buyimg.com/imagetools/jfs/t1/96116/38/15085/5181/5e6f15d1E48e31d30/71353b61dff705d4.png",
},
{
id: "apple",
prizeName: "apple watch",
prizeImg:
"https://img11.360buyimg.com/imagetools/jfs/t1/105385/19/15140/111093/5e6f1506E48bd0dfb/829a98a8cdb4c27f.png",
},
{
id: "fruit",
prizeColor: "rgba(246, 142, 46, 0.5)",
prizeName: "迪士尼苹果",
prizeImg:
"https://img11.360buyimg.com/imagetools/jfs/t1/108308/11/8890/237603/5e6f157eE489cccf1/26e0437cfd93b9c8.png",
},
{
id: "thanks",
prizeName: "谢谢参与",
prizeImg:
"https://img11.360buyimg.com/imagetools/jfs/t1/96116/38/15085/5181/5e6f15d1E48e31d30/71353b61dff705d4.png",
},
{
id: "fish",
prizeName: "海鲜套餐",
prizeImg:
"https://img14.360buyimg.com/imagetools/jfs/t1/90507/38/15165/448364/5e6f15b4E5df0c718/4bd4c3d375eec312.png",
},
{
id: "thanks",
prizeName: "谢谢参与",
prizeImg:
"https://img11.360buyimg.com/imagetools/jfs/t1/96116/38/15085/5181/5e6f15d1E48e31d30/71353b61dff705d4.png",
},
]);
// 转盘样式的选项
const styleOpt = reactive({
prizeItem: {},
startStyle: {},
contentBg: {
background: "rgb(255, 231, 149)",
},
});
// 中奖的奖品的index(此数据可根据后台返回的值重新赋值)
const prizeIndex = ref(0);
const startTurns = () => {
const index = Math.floor(Math.random() * prizeList.value.length);
prizeIndex.value = index;
};
const endTurns = () => {
console.log("中奖了");
};
return {
prizeList,
styleOpt,
prizeIndex,
startTurns,
endTurns,
};
}
}
</script>
此时代码已经编写完成,但编译是不通过的,默认情况下nut-bingo是不支持直接在nut-taro框架中使用的,强行运行会提示在 nut-taro的目录下模块包中是找不到bigMarquee,注意此bigMarquee多了big前缀,是无法找到对应组件的。
PS D:\Workspaces\taro\gwApp> cnpm run dev:weapp
> gwapp@1.0.0 dev:weapp
> npm run build:weapp -- --watch
> gwapp@1.0.0 build:weapp
> taro build --type weapp --watch
👽 Taro v3.6.1
Tips:
1. 预览模式生成的文件较大,设置 NODE_ENV 为 production 可以开启压缩。
Example:
$ set NODE_ENV=production && taro build --type weapp --watch
2. 建议开启持久化缓存功能,能有效提升二次编译速度,详情请参考: https://docs.taro.zone/docs/config-detail#cache。
✖ Webpack
Compiled with some errors in 401.55ms
⚠️ Warnings:
at HarmonyImportSpecifierDependency.getLinkingErrors (D:\Workspaces\taro\gwApp\node_modules\.store\webpack@5.69.0\node_modules\webpack\lib\dependencies\HarmonyImportDependency.js:160:8)
ModuleDependencyWarning: export 'bigMarquee' (imported as '__unplugin_components_0') was not found in '@nutui/nutui-taro' (possible exports: ActionSheet, Address, AddressList, Animate, Audio, AudioOperate, Avatar, AvatarGroup, Backtop, Badge, Barrage, Button, Calendar, CalendarItem, Card, Cascader, Category, CategoryPane, Cell, CellGroup, Checkbox, CheckboxGroup, CircleProgress, Col, Collapse, CollapseItem, Comment, ConfigProvider, Countdown, Countup, DatePicker, Dialog, Divider, Drag, Ecard, Elevator, Ellipsis, Empty, FixedNav, Form, FormItem, Grid, GridItem, Image, ImagePreview, Indicator, InfiniteLoading, Input, InputNumber, Invoice, Layout, List, Locale, Menu, MenuItem, Navbar, Noticebar, Notify, NumberKeyboard, Overlay, Pagination, Picker, Popover, Popup, Price, Progress, PullRefresh, Radio, RadioGroup, Range, Rate, Row, Searchbar, ShortPassword, SideNavbar, SideNavbarItem, Signature, Skeleton, Sku, Step, Steps, Sticky, SubSideNavbar, Swipe, Swiper, SwiperItem, Switch, TabPane, Tabbar, TabbarItem, Table, Tabs, Tag, Textarea, TimeDetail, TimePannel, TimeSelect, Toast, Tour, TrendArrow, Uploader, Video, Watermark, default, install, version)
✖ Errors:
resolve '@nutui/nutui-taro/dist/packages/bigmarquee/style' in 'D:\Workspaces\taro\gwApp\src\pages\draw'
Parsed request is a module
using description file: D:\Workspaces\taro\gwApp\package.json (relative path: ./src/pages/draw)
Field 'browser' doesn't contain a valid alias configuration
resolve as module
D:\Workspaces\taro\gwApp\src\pages\draw\node_modules doesn't exist or is not a directory
D:\Workspaces\taro\gwApp\src\pages\node_modules doesn't exist or is not a directory
D:\Workspaces\taro\gwApp\src\node_modules doesn't exist or is not a directory
looking for modules in D:\Workspaces\taro\gwApp\node_modules
existing directory D:\Workspaces\taro\gwApp\node_modules\@nutui\nutui-taro
using description file: D:\Workspaces\taro\gwApp\node_modules\@nutui\nutui-taro\package.json (relative path: .)
using description file: D:\Workspaces\taro\gwApp\node_modules\@nutui\nutui-taro\package.json (relative path: ./dist/packages/bigmarquee/style)
nutui-bingo适配修改
因为官方目前还在做nutui-bingo组件的小程序适配方案,但我们为了使Marquee跑马灯组件能在nutui-taro框架中集成使用,需自行进行适配修改;
首先我们通过编译错误,我们了解到bigMarquee在@nutui/nutui-taro模块包中不存在
ModuleDependencyWarning: export 'bigMarquee' (imported as '__unplugin_components_0') was not found in '@nutui/nutui-taro' ....
....
resolve '@nutui/nutui-taro/dist/packages/bigmarquee/style' in 'D:\Workspaces\taro\gwApp\src\pages\draw'
....
根据提示我们进入到node_modules/@nutui/nutui-taro/dist/packages/,并未发现bigmarquee包目录,实际不存在;
bigMarquee是如何生成的,我们实际配置的是Marquee组件名称。
通过全局搜索,在项目下的components.d.ts文件中找到bigMarquee,同时发现所有引用的nutui-taro组件均在该配置文件中有自动生成,其中的NutbigMarquee组件从导入的’@nutui/nutui-taro’包中引用了’bigMarquee’
....
NutbigMarquee: typeof import('@nutui/nutui-taro')['bigMarquee']
NutCell: typeof import('@nutui/nutui-taro')['Cell']
....
也就是该NutbigMarquee组件指向的bigMarquee名称,是taro在编译时通过小程序页面的使用nut标签,在components.d.ts中生成的对应组件名称,在由nutui-taro根据app.ts中app.use(Marquee)加载的组件名称进行匹配,但是其它引入组件则没有big前缀,如:Cell。通过对比组件的标签用法,我们发现标签前缀不同;并且Marquee组件理因是’@nutui/nutui-bingo’模块下的,而非’@nutui/nutui-taro’模块下,因此该bigMarquee名称生成是错误的;
<!-- nutui-taro组件 -->
<nut-cell>
<!-- nutui-bingo组件 -->
<nutbig-marquee>
通过进一步对nutui-taro的组件名生成方式研究,其实该组件名称是通过小程序项目下的config/index.js配置文件内的函数逻辑生成;
const NutUIResolver = () => {
return (name) => {
if (name.startsWith('Nut')) {
const partialName = name.slice(3);
return {
name: partialName,
from: '@nutui/nutui-taro',
sideEffects: `@nutui/nutui-taro/dist/packages/${partialName.toLowerCase()}/style`
}
}
}
}
const config = {
...
mini: {
miniCssExtractPluginOption: {
ignoreOrder: true,
},
webpackChain(chain) {
chain.plugin('unplugin-vue-components').use(Components({
resolvers: [NutUIResolver()]
}))
},
...
}
...
}
原来小程序中的组件名生成是通过NutUIResolver()函数,判断子组件name的前3位为Nut,在通过name.slice(3)截取剩余字符内容为需要的子组件名称,并且告知框架该组件来源于from表示的模块包名,并引入sideEffects表示的模块样式;
基本了解组件编译流程后,bigMarquee的来源,就是因为页面中使用的是组件标签,slice(3)截取后变成了big-marquee,小程序页面在编译的时间,通过页面的组件标签转换成bigMarquee后在nutui-taro框架模块下找不到该子组件,因此也导致编译不通过;
对NutUIResolver()函数进入改造,使改造后生成的子组件名称,适配标签;
const NutUIResolver = () => {
return (name) => {
if (name.startsWith('Nutbig')) {
const partialName = name.slice(6);
return {
name: partialName,
from: '@nutui/nutui-bingo',
sideEffects: `@nutui/nutui-bingo/dist/packages/${partialName.toLowerCase()}/style`
}
} else if (name.startsWith('Nut')) {
const partialName = name.slice(3);
return {
name: partialName,
from: '@nutui/nutui-taro',
sideEffects: `@nutui/nutui-taro/dist/packages/${partialName.toLowerCase()}/style`
}
}
}
}
对组件名为nutbig开头,重新按slice(6)位截取,使其能正常的匹配到app.use(Marquee)加载的组件名,成功将Marquee组件捆绑到小程序页面标签上;from指向正确的@nutui/nutui-bingo模块包,sideEffects指向不变(注:实际nutui-bingo模块下的打包子模块组件目录中并没有style);
增加nutui-bingo子组件style样式配置
默认安装nutui-bingo组件后,在@nutui/nutui-bingo/dist/packages/marquee文件夹下是没有style对应的样式引入文件,需要手动创建,可以参考@nutui/nutui-taro/dist/packages下的子组件内的style.mjs,在当前marquee文件下创建一个相同的style.mjs文件
import '../../styles/variables.scss';
import './index.scss';
增加上面的引入scss样式文件,从而使sideEffects通够成功匹配到style样式引入文件
我们来看报bigMarquee样式引入失败时的提示
resolve '@nutui/nutui-taro/dist/packages/bigmarquee/style' in 'D:\Workspaces\taro\gwApp\src\pages\draw'
通过对项目下config/index.js的NutUIResolver()函数进入改造后,会重新匹配@nutui/nutui-taro/dist/packages/marquee/style样式引入文件,此时文件已经存在,则保证能够通过taro的编译较验;
执行Taro编译
在VSCode的终端命令行窗口执行cnpm run dev:weapp
PS D:\Workspaces\taro\gwApp> cnpm run dev:weapp
> gwapp@1.0.0 dev:weapp
> npm run build:weapp -- --watch
> gwapp@1.0.0 build:weapp
> taro build --type weapp --watch
👽 Taro v3.6.1
Tips:
1. 预览模式生成的文件较大,设置 NODE_ENV 为 production 可以开启压缩。
Example:
$ set NODE_ENV=production && taro build --type weapp --watch
2. 建议开启持久化缓存功能,能有效提升二次编译速度,详情请参考: https://docs.taro.zone/docs/config-detail#cache。
✔ Webpack
Compiled successfully in 329.67ms
→ Watching... [2023/3/10 14:05:56]
成功通过编译;
NutbigMarquee组件引用名
再次打开项目下的components.d.ts文件,正常生成NutbigMarquee组件,并且从正确的’@nutui/nutui-bingo’导入’Marquee’;
....
NutbigMarquee: typeof import('@nutui/nutui-bingo')['Marquee']
NutCell: typeof import('@nutui/nutui-taro')['Cell']
....
运行小程序抽奖
打开微信小程序开发工具,加载项目目录,成功加载编译后的页面;
到此成功将untui-bingo下的跑马灯组件集成到了小程序中;