用React Native制作一个简单的游戏引擎


Posted in Javascript onMay 27, 2021

简介

今天我们将学习如何使用React Native制作一个游戏。因为我们使用的是React Native,这个游戏将是跨平台的,这意味着你可以在Android、iOS和网络上玩同一个游戏。然而,今天我们将只关注移动设备。所以我们开始吧。

开始吧

要制作任何游戏,我们需要一个循环,在我们玩的时候更新我们的游戏。这个循环被优化以顺利运行游戏,为此我们将使用 React Native游戏引擎

首先让我们用以下命令创建一个新的React Native应用。

npx react-native init ReactNativeGame

创建项目后,我们需要添加一个依赖项,以便添加游戏引擎。

npm i -S react-native-game-engine

这个命令将把React Native游戏引擎添加到我们的项目中。

那么,我们要做一个什么样的游戏呢?为了简单起见,让我们做一个蛇的游戏,它可以吃食物的碎片并增长身长。

对React Native游戏引擎的简单介绍

React Native Game Engine是一个轻量级的游戏引擎。它包括一个组件,允许我们将对象的数组添加为实体,这样我们就可以对它们进行操作。为了编写我们的游戏逻辑,我们使用了一个系统道具阵列,它允许我们操纵实体(游戏对象),检测触摸,以及许多其他令人敬畏的细节,帮助我们制作一个简单的、功能性的游戏。

让我们在React Native中建立一个蛇形游戏

要制作一个游戏,我们需要一个画布或容器,我们将在其中添加游戏对象。要制作一个画布,我们只需添加一个带有风格的视图组件,像这样。

// App.js     
<View style={styles.canvas}>
</View>

我们可以像这样添加我们的样式。

const styles = StyleSheet.create({
  canvas: {
    flex: 1,
    backgroundColor: "#000000",
    alignItems: "center",
    justifyContent: "center",
  }
});

在画布中,我们将使用 GameEngine 组件和一些来自React Native Game Engine的样式。

import { GameEngine } from "react-native-game-engine";
import React, { useRef } from "react";
import Constants from "./Constants";


export default function App() {
  const BoardSize = Constants.GRID_SIZE * Constants.CELL_SIZE;
  const engine = useRef(null);
  return (
    <View style={styles.canvas}>
      <GameEngine
              ref={engine}
              style={{
                width: BoardSize,
                height: BoardSize,
                flex: null,
                backgroundColor: "white",
              }}
            />
    </View>
);

我们还使用 useRef() React Hook为游戏引擎添加了一个ref,以便日后使用。

我们还在项目的根部创建了一个 Constants.js 文件来存储我们的常量值。

// Constants.js
import { Dimensions } from "react-native";
export default {
  MAX_WIDTH: Dimensions.get("screen").width,
  MAX_HEIGHT: Dimensions.get("screen").height,
  GRID_SIZE: 15,
  CELL_SIZE: 20
};

你会注意到我们正在做一个15乘15的网格,我们的蛇将在那里移动。

这时我们的游戏引擎已经设置好了,以显示蛇和它的食物。我们需要将实体和道具添加到 GameEngine ,但在此之前,我们需要创建一个蛇和食物的组件,在设备上渲染。

创建游戏实体

让我们首先制作蛇。蛇分为两部分,头部和身体(或尾巴)。现在我们将制作蛇的头部,我们将在本教程的后面添加蛇的尾巴。

为了制作蛇的头部,我们将在组件文件夹中制作一个 Head 组件。

正如你所看到的,我们有三个组件: Head , Food ,和 Tail 。我们将在本教程中逐一查看这些文件的内容。

在 Head 组件中,我们将创建一个带有一些样式的视图。

import React from "react";
import { View } from "react-native";
export default function Head({ position, size }) {
  return (
    <View
      style={{
        width: size,
        height: size,
        backgroundColor: "red",
        position: "absolute",
        left: position[0] * size,
        top: position[1] * size,
      }}
    ></View>
  );
}

我们将传递一些道具来设置头部的大小和位置。

我们使用 position: "absolute" 属性来轻松移动头部。

这将呈现一个正方形,我们不打算使用更复杂的东西;一个正方形或长方形的形状代表蛇的身体,一个圆形的形状代表食物。

现在让我们将这条蛇的头部添加到 GameEngine 。

要添加任何实体,我们需要在 GameEngine 中的 entities 道具中传递一个对象。

//App.js
import Head from "./components/Head";


 <GameEngine
        ref={engine}
        style={{
          width: BoardSize,
          height: BoardSize,
          flex: null,
          backgroundColor: "white",
        }}
        entities={{
          head: {
            position: [0, 0],
            size: Constants.CELL_SIZE,
            updateFrequency: 10,
            nextMove: 10,
            xspeed: 0,
            yspeed: 0,
            renderer: <Head />,
          }
        }} 
/>

我们在 entities 道具中传递了一个对象,其关键是头。这些是它定义的属性。

  • position 是一组坐标,用于放置蛇头。
  • size 是设置蛇头大小的值。
  • xspeedyspeed 是决定蛇的运动和方向的值,可以是1、0或-1。注意,当 xspeed 被设置为1或-1时,那么 yspeed 的值必须为0,反之亦然
  • 最后, renderer ,负责渲染该组件
  • updateFrequencynextMove 将在后面讨论。

在添加完 Head 组件后,我们也来添加其他组件。

// commponets/Food/index.js
import React from "react";
import { View } from "react-native";
export default function Food({ position, size }) {
  return (
    <View
      style={{
        width: size,
        height: size,
        backgroundColor: "green",
        position: "absolute",
        left: position[0] * size,
        top: position[1] * size,
        borderRadius: 50
      }}
    ></View>
  );
}

Food 组件与 Head 组件类似,但我们改变了背景颜色和边框半径,使其成为一个圆形。

现在创建一个 Tail 组件。这个可能很棘手。

// components/Tail/index.js

import React from "react";
import { View } from "react-native";
import Constants from "../../Constants";
export default function Tail({ elements, position, size }) {
  const tailList = elements.map((el, idx) => (
    <View
      key={idx}
      style={{
        width: size,
        height: size,
        position: "absolute",
        left: el[0] * size,
        top: el[1] * size,
        backgroundColor: "red",
      }}
    />
  ));
  return (
    <View
      style={{
        width: Constants.GRID_SIZE * size,
        height: Constants.GRID_SIZE * size,
      }}
    >
      {tailList}
    </View>
  );
}

当蛇吃了食物后,我们将在蛇身中添加一个元素,这样我们的蛇就会成长。这些元素将传入 Tail 组件,这将表明它必须变大。

我们将循环浏览所有的元素来创建整个蛇身,附加上它,然后渲染。

在制作完所有需要的组件后,让我们把这两个组件作为 GameEngine 。

// App.js

import Food from "./components/Food";
import Tail from "./components/Tail";


// App.js
const randomPositions = (min, max) => {
    return Math.floor(Math.random() * (max - min + 1) + min);
  };


// App.js

<GameEngine
        ref={engine}
        style={{
          width: BoardSize,
          height: BoardSize,
          flex: null,
          backgroundColor: "white",
        }}
        entities={{
          head: {
            position: [0, 0],
            size: Constants.CELL_SIZE,
            updateFrequency: 10,
            nextMove: 10,
            xspeed: 0,
            yspeed: 0,
            renderer: <Head />,
          },
          food: {
            position: [
              randomPositions(0, Constants.GRID_SIZE - 1),
              randomPositions(0, Constants.GRID_SIZE - 1),
            ],
            size: Constants.CELL_SIZE,
            renderer: <Food />,
          },
          tail: {
            size: Constants.CELL_SIZE,
            elements: [],
            renderer: <Tail />,
          },
        }}

      />

为了保证食物位置的随机性,我们做了一个带有最小和最大参数的 randomPositions 函数。

在 tail ,我们在初始状态下添加了一个空数组,所以当蛇吃到食物时,它将在 elements: 空间中存储每个尾巴的长度。

在这一点上,我们已经成功创建了我们的游戏组件。现在是在游戏循环中添加游戏逻辑的时候了。

游戏逻辑

为了使游戏循环, GameEngine 组件有一个叫 systems 的道具,它接受一个数组的函数。

为了保持一切结构化,我正在创建一个名为 systems 的文件夹,并插入一个名为 GameLoop.js 的文件。

在这个文件中,我们正在导出一个带有某些参数的函数。

// GameLoop.js

export default function (entities, { events, dispatch }) {
  ...

  return entities;
}

第一个参数是 entities ,它包含了我们传递给 GameEngine 组件的所有实体,所以我们可以操作它们。另一个参数是一个带有属性的对象,即 events 和 dispatch 。

移动蛇头

让我们编写代码,将蛇头向正确的方向移动。

在 GameLoop.js 函数中,我们将更新头部的位置,因为这个函数在每一帧都会被调用。

// GameLoop.js
export default function (entities, { events, dispatch }) {
  const head = entities.head;
  head.position[0] += head.xspeed;
  head.position[1] += head.yspeed;
}

我们使用 entities 参数访问头部,在每一帧中我们都要更新蛇头的位置。

如果你现在玩游戏,什么也不会发生,因为我们把 xspeed 和 yspeed 设置为0。如果你把 xspeed 或 yspeed 设置为1,蛇的头部会移动得很快。

为了减慢蛇的速度,我们将像这样使用 nextMove 和 updateFrequency 的值。

const head = entities.head;

head.nextMove -= 1;
if (head.nextMove === 0) {
  head.nextMove = head.updateFrequency;

  head.position[0] += head.xspeed;
  head.position[1] += head.yspeed;
}

我们通过在每一帧中减去1来更新 nextMove 的值为0。当值为0时, if 条件被设置为 true , nextMove 值被更新回初始值,从而移动蛇的头部。

现在,蛇的速度应该比以前慢了。

"游戏结束!"条件

在这一点上,我们还没有添加 "游戏结束!"条件。第一个 "游戏结束!"条件是当蛇碰到墙时,游戏停止运行,并向用户显示一条信息,表明游戏已经结束。

为了添加这个条件,我们使用这段代码。

if (head.nextMove === 0) {
  head.nextMove = head.updateFrequency;
  if (
        head.position[0] + head.xspeed < 0 ||
        head.position[0] + head.xspeed >= Constants.GRID_SIZE ||
        head.position[1] + head.yspeed < 0 ||
        head.position[1] + head.yspeed >= Constants.GRID_SIZE
      ) {
        dispatch("game-over");
      } else {
        head.position[0] += head.xspeed;
        head.position[1] += head.yspeed;
    }

第二个 if 条件是检查蛇头是否触及墙壁。如果该条件为真,那么我们将使用 dispatch 函数来发送一个 "game-over" 事件。

通过 else ,我们正在更新蛇的头部位置。

现在让我们添加 "游戏结束!"的功能。

每当我们派发一个 "game-over" 事件时,我们将停止游戏,并显示一个警告:"游戏结束!"让我们来实现它。

为了监听 "game-over" 事件,我们需要将 onEvent 道具传递给 GameEngine 组件。为了停止游戏,我们需要添加一个 running 道具并传入 useState 。

我们的 GameEngine 应该看起来像这样。

// App.js
import React, { useRef, useState } from "react";
import GameLoop from "./systems/GameLoop";

....
....

const [isGameRunning, setIsGameRunning] = useState(true);

....
....

 <GameEngine
        ref={engine}
        style={{
          width: BoardSize,
          height: BoardSize,
          flex: null,
          backgroundColor: "white",
        }}
        entities={{
          head: {
            position: [0, 0],
            size: Constants.CELL_SIZE,
            updateFrequency: 10,
            nextMove: 10,
            xspeed: 0,
            yspeed: 0,
            renderer: <Head />,
          },
          food: {
            position: [
              randomPositions(0, Constants.GRID_SIZE - 1),
              randomPositions(0, Constants.GRID_SIZE - 1),
            ],
            size: Constants.CELL_SIZE,
            renderer: <Food />,
          },
          tail: {
            size: Constants.CELL_SIZE,
            elements: [],
            renderer: <Tail />,
          },
        }}
        systems={[GameLoop]}
        running={isGameRunning}
        onEvent={(e) => {
          switch (e) {
            case "game-over":
              alert("Game over!");
              setIsGameRunning(false);
              return;
          }
        }}
      />

在 GameEngine 中,我们已经添加了 systems 道具,并通过我们的 GameLoop 函数传入了一个数组,同时还有一个 running 道具和一个 isGameRunning 状态。最后,我们添加了 onEvent 道具,它接受一个带有事件参数的函数,这样我们就可以监听我们的事件。

在这种情况下,我们在switch语句中监听 "game-over" 事件,所以当我们收到该事件时,我们显示 "Game over!" 警报,并将 isGameRunning 状态设置为 false ,以停止游戏。

食用食物

我们已经写好了 "游戏结束!"的逻辑,现在让我们来写一下让蛇吃食物的逻辑。

当蛇吃了食物后,食物的位置应该随机变化。

打开 GameLoop.js ,写下以下代码。

// GameLoop.js

const randomPositions = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1) + min);
};

export default function (entities, { events, dispatch }) {
  const head = entities.head;
  const food = entities.food;

  ....
  ....
  ....
  if (
        head.position[0] + head.xspeed < 0 ||
        head.position[0] + head.xspeed >= Constants.GRID_SIZE ||
        head.position[1] + head.yspeed < 0 ||
        head.position[1] + head.yspeed >= Constants.GRID_SIZE
      ) {
        dispatch("game-over");
      } else {

     head.position[0] += head.xspeed;
     head.position[1] += head.yspeed;

     if (
          head.position[0] == food.position[0] &&
          head.position[1] == food.position[1]
        ) {

          food.position = [
            randomPositions(0, Constants.GRID_SIZE - 1),
            randomPositions(0, Constants.GRID_SIZE - 1),
          ];
        }
  }

我们添加了一个 if ,以检查蛇头和食物的位置是否相同(这将表明蛇已经 "吃 "了食物)。然后,我们使用 randomPositions 函数更新食物的位置,正如我们在上面的 App.js 。请注意,我们是通过 entities 参数来访问食物的。

控制蛇

现在让我们来添加蛇的控制。我们将使用按钮来控制蛇的移动位置。

要做到这一点,我们需要在画布下面的屏幕上添加按钮。

// App.js

import React, { useRef, useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import { GameEngine } from "react-native-game-engine";
import { TouchableOpacity } from "react-native-gesture-handler";
import Food from "./components/Food";
import Head from "./components/Head";
import Tail from "./components/Tail";
import Constants from "./Constants";
import GameLoop from "./systems/GameLoop";
export default function App() {
  const BoardSize = Constants.GRID_SIZE * Constants.CELL_SIZE;
  const engine = useRef(null);
  const [isGameRunning, setIsGameRunning] = useState(true);
  const randomPositions = (min, max) => {
    return Math.floor(Math.random() * (max - min + 1) + min);
  };
  const resetGame = () => {
    engine.current.swap({
      head: {
        position: [0, 0],
        size: Constants.CELL_SIZE,
        updateFrequency: 10,
        nextMove: 10,
        xspeed: 0,
        yspeed: 0,
        renderer: <Head />,
      },
      food: {
        position: [
          randomPositions(0, Constants.GRID_SIZE - 1),
          randomPositions(0, Constants.GRID_SIZE - 1),
        ],
        size: Constants.CELL_SIZE,
        updateFrequency: 10,
        nextMove: 10,
        xspeed: 0,
        yspeed: 0,
        renderer: <Food />,
      },
      tail: {
        size: Constants.CELL_SIZE,
        elements: [],
        renderer: <Tail />,
      },
    });
    setIsGameRunning(true);
  };
  return (
    <View style={styles.canvas}>
      <GameEngine
        ref={engine}
        style={{
          width: BoardSize,
          height: BoardSize,
          flex: null,
          backgroundColor: "white",
        }}
        entities={{
          head: {
            position: [0, 0],
            size: Constants.CELL_SIZE,
            updateFrequency: 10,
            nextMove: 10,
            xspeed: 0,
            yspeed: 0,
            renderer: <Head />,
          },
          food: {
            position: [
              randomPositions(0, Constants.GRID_SIZE - 1),
              randomPositions(0, Constants.GRID_SIZE - 1),
            ],
            size: Constants.CELL_SIZE,
            renderer: <Food />,
          },
          tail: {
            size: Constants.CELL_SIZE,
            elements: [],
            renderer: <Tail />,
          },
        }}
        systems={[GameLoop]}
        running={isGameRunning}
        onEvent={(e) => {
          switch (e) {
            case "game-over":
              alert("Game over!");
              setIsGameRunning(false);
              return;
          }
        }}
      />
      <View style={styles.controlContainer}>
        <View style={styles.controllerRow}>
          <TouchableOpacity onPress={() => engine.current.dispatch("move-up")}>
            <View style={styles.controlBtn} />
          </TouchableOpacity>
        </View>
        <View style={styles.controllerRow}>
          <TouchableOpacity
            onPress={() => engine.current.dispatch("move-left")}
          >
            <View style={styles.controlBtn} />
          </TouchableOpacity>
          <View style={[styles.controlBtn, { backgroundColor: null }]} />
          <TouchableOpacity
            onPress={() => engine.current.dispatch("move-right")}
          >
            <View style={styles.controlBtn} />
          </TouchableOpacity>
        </View>
        <View style={styles.controllerRow}>
          <TouchableOpacity
            onPress={() => engine.current.dispatch("move-down")}
          >
            <View style={styles.controlBtn} />
          </TouchableOpacity>
        </View>
      </View>
      {!isGameRunning && (
        <TouchableOpacity onPress={resetGame}>
          <Text
            style={{
              color: "white",
              marginTop: 15,
              fontSize: 22,
              padding: 10,
              backgroundColor: "grey",
              borderRadius: 10
            }}
          >
            Start New Game
          </Text>
        </TouchableOpacity>
      )}
    </View>
  );
}
const styles = StyleSheet.create({
  canvas: {
    flex: 1,
    backgroundColor: "#000000",
    alignItems: "center",
    justifyContent: "center",
  },
  controlContainer: {
    marginTop: 10,
  },
  controllerRow: {
    flexDirection: "row",
    justifyContent: "center",
    alignItems: "center",
  },
  controlBtn: {
    backgroundColor: "yellow",
    width: 100,
    height: 100,
  },
});

除了控制之外,我们还添加了一个按钮,以便在前一个游戏结束时开始一个新的游戏。这个按钮只在游戏没有运行时出现。在点击该按钮时,我们通过使用游戏引擎的 swap 函数来重置游戏,传入实体的初始对象,并更新游戏的运行状态。

现在说说控制。我们已经添加了可触摸物体,当按下这些物体时,就会派发将在游戏循环中处理的事件。

// GameLoop.js
....
....
 export default function (entities, { events, dispatch }) {
    const head = entities.head;
    const food = entities.food;

  if (events.length) {
    events.forEach((e) => {
      switch (e) {
        case "move-up":
          if (head.yspeed === 1) return;
          head.yspeed = -1;
          head.xspeed = 0;
          return;
        case "move-right":
          if (head.xspeed === -1) return;
          head.xspeed = 1;
          head.yspeed = 0;
          return;
        case "move-down":
          if (head.yspeed === -1) return;
          head.yspeed = 1;
          head.xspeed = 0;
          return;
        case "move-left":
          if (head.xspeed === 1) return;
          head.xspeed = -1;
          head.yspeed = 0;
          return;
      }
    });
  }

....
....
});

在上面的代码中,我们添加了一个 switch 语句来识别事件并更新蛇的方向。

还在听我说吗?很好!唯一剩下的就是尾巴了。

尾巴功能

当蛇吃了食物后,我们希望它的尾巴能长出来。我们还想在蛇咬到自己的尾巴或身体时发出一个 "游戏结束!"的事件。

让我们来添加尾巴逻辑。

// GameLoop.js

const tail = entities.tail;

....
....

....

    else {
      tail.elements = [[head.position[0], head.position[1]], ...tail.elements];
      tail.elements.pop();

      head.position[0] += head.xspeed;
      head.position[1] += head.yspeed;

      tail.elements.forEach((el, idx) => {
        if (
          head.position[0] === el[0] &&
          head.position[1] === el[1] 
        )
          dispatch("game-over");
      });
      if (
        head.position[0] == food.position[0] &&
        head.position[1] == food.position[1]
      ) {
        tail.elements = [
          [head.position[0], head.position[1]],
          ...tail.elements,
        ];

        food.position = [
          randomPositions(0, Constants.GRID_SIZE - 1),
          randomPositions(0, Constants.GRID_SIZE - 1),
        ];
      }
    }

为了使尾巴跟随蛇的头部,我们要更新尾巴的元素。我们通过将头部的位置添加到元素数组的开头,然后删除尾巴元素数组上的最后一个元素来实现这一目的。

在这之后,我们写一个条件,如果蛇咬了自己的身体,我们就分派 "game-over" 事件。

最后,每当蛇吃了食物,我们就用蛇头的当前位置来追加蛇尾的元素,以增加蛇尾的长度。

下面是 GameLoop.js 的完整代码。

// GameLoop.js

import Constants from "../Constants";
const randomPositions = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1) + min);
};
  export default function (entities, { events, dispatch }) {
    const head = entities.head;
    const food = entities.food;
    const tail = entities.tail;
  if (events.length) {
    events.forEach((e) => {
      switch (e) {
        case "move-up":
          if (head.yspeed === 1) return;
          head.yspeed = -1;
          head.xspeed = 0;
          return;
        case "move-right":
          if (head.xspeed === -1) return;
          head.xspeed = 1;
          head.yspeed = 0;
          // ToastAndroid.show("move right", ToastAndroid.SHORT);
          return;
        case "move-down":
          if (head.yspeed === -1) return;
          // ToastAndroid.show("move down", ToastAndroid.SHORT);
          head.yspeed = 1;
          head.xspeed = 0;
          return;
        case "move-left":
          if (head.xspeed === 1) return;
          head.xspeed = -1;
          head.yspeed = 0;
          // ToastAndroid.show("move left", ToastAndroid.SHORT);
          return;
      }
    });
  }
  head.nextMove -= 1;
  if (head.nextMove === 0) {
    head.nextMove = head.updateFrequency;
    if (
      head.position[0] + head.xspeed < 0 ||
      head.position[0] + head.xspeed >= Constants.GRID_SIZE ||
      head.position[1] + head.yspeed < 0 ||
      head.position[1] + head.yspeed >= Constants.GRID_SIZE
    ) {
      dispatch("game-over");
    } else {
      tail.elements = [[head.position[0], head.position[1]], ...tail.elements];
      tail.elements.pop();
      head.position[0] += head.xspeed;
      head.position[1] += head.yspeed;
      tail.elements.forEach((el, idx) => {
        console.log({ el, idx });
        if (
          head.position[0] === el[0] &&
          head.position[1] === el[1] 
        )
          dispatch("game-over");
      });
      if (
        head.position[0] == food.position[0] &&
        head.position[1] == food.position[1]
      ) {
        tail.elements = [
          [head.position[0], head.position[1]],
          ...tail.elements,
        ];

        food.position = [
          randomPositions(0, Constants.GRID_SIZE - 1),
          randomPositions(0, Constants.GRID_SIZE - 1),
        ];
      }
    }
  }
  return entities;
}

结语

现在你的第一个React Native游戏已经完成了你可以在自己的设备上运行这个游戏来玩。我希望你能学到一些新的东西,也希望你能与你的朋友分享。

谢谢你的阅读,祝你有个愉快的一天。

The post How to build a simple game in React Native appeared first onLogRocket Blog .

以上就是用React Native构建一个简单的游戏的详细内容,更多关于React Native游戏的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
javascript 防止刷新,后退,关闭
Aug 07 Javascript
在JS中解析HTML字符串示例代码
Apr 16 Javascript
javascript实现跨域的方法汇总
Jun 25 Javascript
jQuery右侧选项卡焦点图片轮播特效代码分享
Sep 05 Javascript
EasyUI的doCellTip实现鼠标放到单元格上提示单元格内容
Aug 24 Javascript
bootstrap实现每隔5秒自动轮播效果
Dec 20 Javascript
js实现兼容PC端和移动端滑块拖动选择数字效果
Feb 16 Javascript
基于Vuejs和Element的注册插件的编写方法
Jul 03 Javascript
全面介绍vue 全家桶和项目实例
Dec 27 Javascript
浅谈Vue数据响应
Nov 05 Javascript
详解微信小程序中var、let、const用法与区别
Jan 11 Javascript
JS操作JSON常用方法(10w阅读)
Dec 06 Javascript
Vue实现动态查询规则生成组件
QT与javascript交互数据的实现
May 26 #Javascript
小程序实现筛子抽奖
详解vue身份认证管理和租户管理
ES6 解构赋值的原理及运用
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
js Proxy的原理详解
May 25 #Javascript
You might like
全国FM电台频率大全 - 30 宁夏回族自治区
2020/03/11 无线电
php学习之流程控制实现代码
2011/06/09 PHP
php上传中文文件名乱码问题处理方案
2015/02/03 PHP
thinkPHP导出csv文件及用表格输出excel的方法
2015/12/30 PHP
PHP删除数组中指定下标的元素方法
2018/02/03 PHP
php反射学习之依赖注入示例
2019/06/14 PHP
PHP命名空间用法实例分析
2019/09/04 PHP
ThinkPHP 5.x远程命令执行漏洞复现
2019/09/23 PHP
laravel框架与其他框架的详细对比
2019/10/23 PHP
JavaScript脚本语言在网页中的简单应用
2007/05/13 Javascript
Jquery+WebService 校验账号是否已被注册的代码
2010/07/12 Javascript
定义JavaScript二维数组采用定义数组的数组来实现
2012/12/09 Javascript
简单的两种Extjs formpanel加载数据的方式
2013/11/09 Javascript
jquery数组过滤筛选方法grep()简介
2014/06/06 Javascript
Bootstrap面板使用方法
2017/01/16 Javascript
JavaScript基于面向对象实现的猜拳游戏
2018/01/03 Javascript
超出JavaScript安全整数限制的数字计算BigInt详解
2018/06/24 Javascript
Vue路由history模式解决404问题的几种方法
2018/09/29 Javascript
详解vue-cli3多环境打包配置
2019/03/28 Javascript
构建Python包的五个简单准则简介
2015/06/15 Python
Python设计模式之模板方法模式实例详解
2019/01/17 Python
css3 伪类选择器快速复习小结
2019/09/10 HTML / CSS
Discard Protocol抛弃协议的作用是什么
2015/10/10 面试题
商务日语毕业生自荐信
2013/11/23 职场文书
技术总监岗位职责
2013/12/05 职场文书
小型女装店的创业计划书
2014/01/09 职场文书
家长评语大全
2014/01/22 职场文书
初中同学聚会感言
2014/02/11 职场文书
竞选文艺委员演讲稿
2014/04/28 职场文书
党员政治学习材料
2014/05/14 职场文书
祖国在我心中演讲稿(小学生)
2014/09/23 职场文书
党员剖析材料范文
2014/12/18 职场文书
2015财务年终工作总结范文
2015/05/22 职场文书
就业推荐表院系意见
2015/06/05 职场文书
领导新年致辞2016
2015/07/29 职场文书
使用 DataAnt 监控 Apache APISIX的原理解析
2022/07/07 Servers