Greeting,

The Nuggets’ lottery system has been around for a while now, and I don’t know what they’ve been winning, or if they’ve gone through despair like ME, seen through the world, and saved it for the next generation.

This kind of lottery scenario is very common in the event, in order to better catch fish, decided to write a plug-in to solve the repetitive work. Next for everyone to introduce a good palace draw component, please see the officer to move down

On the grid – roll

Grid-roll is a VUE palace component that separates UI and logic, encapsulating logic and palace layouts and letting developers focus only on the UI parts of prizes and buttons.

  • Custom grid number, classic 3×3 or 10×100 is not a problem
  • Draw more function, a click many times lucky draw, bottom of the shuttle ha, ask you thorn not stimulate

The installation

npm i grid-roll -S
yarn add grid-roll
Copy the code

The introduction of

/ * * introduction * /
import { gridRoll, gridStart, gridPrize } from 'grid-roll'
import 'grid-roll/dist/grid-roll.min.css'
Copy the code

practice

Vuecli to build new projects, here we can directly use the nuggets raffle picture link, bring you.

I marked all the prizes in the picture with numbers. These marks are actually the subscripts of the prize array. They correspond to the position of the prize, and the layout is arranged line by line from left to right

Using Grid-roll, we only need to define the styles of the 8 prizes and 1 button, pack them in gridStart and gridPrize, and the gridRoll will automatically adjust them to a 9 grid layout. Here, I prefer to write the prize as data to generate a gridPrize in a loop. Then the style layout basically opens the developer tool and copies the style of the nuggets, so I won’t go into details

Here are the three components:

  • GridRoll: The interval property defines the interval before the palace. By default, there is no interval. Here I see it defined as 6px. And accepts two slots, Button and Prize
  • GridStart: a component dedicated to a button slot
  • GridPrize: A component dedicated to the Prize slot
<gridRoll interval="6px">
    <! - button - >
    <template v-slot:button>
      <gridStart>
        <div class="turntable-item item lottery">
          <div class="lottery-text">Lucky draw</div>
          <div class="text">200 ores once</div>
        </div>
      </gridStart>
    </template>
    <! - the prize - - >
    <template v-slot:prize>
      <gridPrize
        v-for="prize in prizes"
        :key="prize.id"
        :pid="prize.id"
      >
        <div class="turntable-item item">
          <div class="image">
            <img :src="prize.img" alt="" />
          </div>
          <div class="text">{{ prize.text }}</div>
        </div>
      </gridPrize>
    </template>
  </gridRoll>
Copy the code
// Components and styles are introduced here
import { gridRoll, gridStart, gridPrize } from "grid-roll";
import "grid-roll/dist/grid-roll.min.css";
expoet default {
    data () {
        return {
          prizes: [{id: 1.text: "66 ore".img: "https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/32ed6a7619934144882d841761b63d3c~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 2.text: "Random limited badges".img: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/71c68de6368548bd9bd6c8888542f911~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 3.text: "The New Nuggets T-shirt.".img: "https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5bf91038a6384fc3927dee294a38006b~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 4.text: "Bug".img: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0a4ce25d48b8405cbf5444b6195928d4~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 5.text: "Draw two more times to unlock.".img: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/aabe49b0d5c741fa8d92ff94cd17cb90~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 6.text: "Nuggets limited edition cushion".img: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c78f363f41a741ffa11dcc8a92b72407~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 7.text: Hold pillow "Yoyo".img: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/33f4d465a6a9462f9b1b19b3104c8f91~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 8.text: "Draw three more times to unlock.".img: "https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4decbd721b2b48098a1ecf879cfca677~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p",},],}}components: {
        gridRoll,
        gridStart,
        gridPrize,
    },
}
Copy the code

As you can see, all we need to do is to style the buttons and prizes with gridStart and gridPrize, and put them in the gridRoll, without having to worry about the rest of the mess.

The use of the disabled

From the official picture, there is a missing “lock” pattern that needs to be unlocked by the number of times the prize is drawn. In addition to the different styles of prizes, it also skips the unlocked prizes when scrolling. GridPrize also has a corresponding prop to do this.

Here we add a column disabled: True to the “lock” element, and pass it to gridPrize. When the drawing starts, the scroll will skip the prizes whose values are disabled: True

<gridPrize
                    v-for="prize in prizes"
                    :key="prize.id"
                    :pid="prize.id"
                    :disabled="prize.disabled"
                  >
Copy the code

Now that we’re basically done with the static style, how do I trigger the draw

Lucky draw

The raffle behavior is provided by the gridPrize startRoll function, which gets an instance of gridRoll by ref and defines a handleLottery method to trigger the startRoll function. Then attach the handleLottery to the lottery button

<gridRoll interval="6px" ref="dial">
<! -- Bind events -->
<gridStart>
    <div
      @click="handleLottery"
      class="turntable-item item lottery"
    >
Copy the code
methods: {
    async handleLottery() {
      const value = 1;
      /** * return a Promise instance, internally to prevent multiple triggers of the draw logic, * resolve will pass a Boolean, proceed false, end return true */
      const b = await this.$refs.dial.startRoll(value);
      if (b) {
        alert(
          ` 🎉 smoke to youThe ${this.prizes.find((prize) => prize.id === value).text}`
        );
      } else {
        console.warn("Hold your horses."); }}},Copy the code

Also keep in mind that when the sweepstakes scroll, there is a selected style, and the gridPrize scope slot provides an isSelect value to determine whether to scroll to the current prize, which is used to do some style switching

<! -- disabled is true, skip -->
<gridPrize
    v-for="prize in prizes"
    :key="prize.id"
    :pid="prize.id"
    :disabled="prize.disabled"
  >
  <! -- isSelect is used to determine whether to scroll to the current prize -->
    <template v-slot="{ isSelect }">
Copy the code

9 grid raffle already works (GIF frame drop problem, to see the full demo can click the link at the end

The prize to unlock

No matter how many times you draw the nine squares, the two on the right are still locked, so one small change is needed

  1. Maintain a completeNumber to count the number of draws
  2. Move the “data” to the calculated property
  3. Handler lottery completeNumber++ after extraction is complete
// The whole js specific code, lottery method simple a few lines of code to achieve
export default {
  name: "App".data() {
    return {
      completeNumber: 0}; },computed: {
    prizes() {
      return[{id: 1.text: "66 ore".img: "https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/32ed6a7619934144882d841761b63d3c~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 2.text: "Random limited badges".img: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/71c68de6368548bd9bd6c8888542f911~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 3.text: "The New Nuggets T-shirt.".img: "https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5bf91038a6384fc3927dee294a38006b~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 4.text: "Bug".img: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0a4ce25d48b8405cbf5444b6195928d4~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 5.text:
            this.completeNumber >= 2
              ? Lego Ocean Ship
              : ` draw againThe ${2 - this.completeNumber}Time to unlock `.img: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/aabe49b0d5c741fa8d92ff94cd17cb90~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p".disabled: this.completeNumber < 2}, {id: 6.text: "Nuggets limited edition cushion".img: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c78f363f41a741ffa11dcc8a92b72407~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 7.text: Hold pillow "Yoyo".img: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/33f4d465a6a9462f9b1b19b3104c8f91~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p"}, {id: 8.text:
            this.completeNumber >= 3
              ? "Switch"
              : ` draw againThe ${3 - this.completeNumber}Time to unlock `.img: "https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4decbd721b2b48098a1ecf879cfca677~tplv-k3u1fbpfcp-no-mark:0:0:0:0.aweb p".disabled: this.completeNumber < 3,},]; }},components: {
    gridRoll,
    gridStart,
    gridPrize,
  },
  methods: {
    async handleLottery() {
      const value = 1;
      const b = await this.$refs.dial.startRoll(value);
      if (b) {
        alert(
          ` 🎉 smoke to youThe ${this.prizes.find((prize) => prize.id === value).text}`
        );
        this.completeNumber++;
      } else {
        console.warn("Hold your horses."); ,}}}};Copy the code

Small tips

In a real business situation, the interface will be called to get the lottery information before startRoll. For better interaction, gridPrize provides a continueRoll method to start scrolling without waiting for the interface to finish before starting the lottery.

conclusion

As you can see from this article, grid-roll allows us to focus only on the style of the prize button and the prize data, as well as a simple lottery function, and this is the basic feature. See the documentation below for more details. In the demo, it was too boring to only transfer the prize with ID 1 each time, so I added a custom lottery function for everyone to manipulate behind the scenes

Preview online Demo Page

The project address

The grid – roll address