Node.js+Vue.js全栈开发王者荣耀手机端官网和管理后台(一)

news2025/1/17 8:57:23

文章目录

  • 【全栈之巅】Node.js+Vue.js全栈开发王者荣耀手机端官网和管理后台(一)
    • 工具安装和环境搭建
    • 初始化项目
    • 基于ElementUI的后台管理基础界面搭建
    • 创建分类(客户端)
    • 创建分类(服务端)
    • 分类列表
    • 分类编辑
    • 分类删除
    • 子分类

【全栈之巅】Node.js+Vue.js全栈开发王者荣耀手机端官网和管理后台(一)


工具安装和环境搭建

node.js下载安装

之前已经安装过

npm比较慢,可以配置淘宝镜像,可自行搜索配置。
这里我是安装并且使用yarn

mongodb安装

在这里插入图片描述

初始化项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

基于ElementUI的后台管理基础界面搭建

在这里插入图片描述在这里插入图片描述

views/Main.vue

<template>
  <el-container style="height: 100vh">
    <el-aside width="200px" style="background-color: rgb(238, 241, 246)">
      <el-menu :default-openeds="['1', '3']">
        <el-submenu index="1">
          <template slot="title"
            ><i class="el-icon-message"></i>导航一</template
          >
          <el-menu-item-group>
            <template slot="title">分组一</template>
            <el-menu-item index="1-1">选项1</el-menu-item>
            <el-menu-item index="1-2">选项2</el-menu-item>
          </el-menu-item-group>
          <el-menu-item-group title="分组2">
            <el-menu-item index="1-3">选项3</el-menu-item>
          </el-menu-item-group>
          <el-submenu index="1-4">
            <template slot="title">选项4</template>
            <el-menu-item index="1-4-1">选项4-1</el-menu-item>
          </el-submenu>
        </el-submenu>
        <el-submenu index="2">
          <template slot="title"><i class="el-icon-menu"></i>导航二</template>
          <el-menu-item-group>
            <template slot="title">分组一</template>
            <el-menu-item index="2-1">选项1</el-menu-item>
            <el-menu-item index="2-2">选项2</el-menu-item>
          </el-menu-item-group>
          <el-menu-item-group title="分组2">
            <el-menu-item index="2-3">选项3</el-menu-item>
          </el-menu-item-group>
          <el-submenu index="2-4">
            <template slot="title">选项4</template>
            <el-menu-item index="2-4-1">选项4-1</el-menu-item>
          </el-submenu>
        </el-submenu>
        <el-submenu index="3">
          <template slot="title"
            ><i class="el-icon-setting"></i>导航三</template
          >
          <el-menu-item-group>
            <template slot="title">分组一</template>
            <el-menu-item index="3-1">选项1</el-menu-item>
            <el-menu-item index="3-2">选项2</el-menu-item>
          </el-menu-item-group>
          <el-menu-item-group title="分组2">
            <el-menu-item index="3-3">选项3</el-menu-item>
          </el-menu-item-group>
          <el-submenu index="3-4">
            <template slot="title">选项4</template>
            <el-menu-item index="3-4-1">选项4-1</el-menu-item>
          </el-submenu>
        </el-submenu>
      </el-menu>
    </el-aside>

    <el-container>
      <el-header style="text-align: right; font-size: 12px">
        <el-dropdown>
          <i class="el-icon-setting" style="margin-right: 15px"></i>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item>查看</el-dropdown-item>
            <el-dropdown-item>新增</el-dropdown-item>
            <el-dropdown-item>删除</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <span>王小虎</span>
      </el-header>

      <el-main>
        <el-table :data="tableData">
          <el-table-column prop="date" label="日期" width="140">
          </el-table-column>
          <el-table-column prop="name" label="姓名" width="120">
          </el-table-column>
          <el-table-column prop="address" label="地址"> </el-table-column>
        </el-table>
      </el-main>
    </el-container>
  </el-container>
</template>

<style>
.el-header {
  background-color: #b3c0d1;
  color: #333;
  line-height: 60px;
}

.el-aside {
  color: #333;
}
</style>

<script>
export default {
  data() {
    const item = {
      date: "2016-05-02",
      name: "王小虎",
      address: "上海市普陀区金沙江路 1518 弄",
    };
    return {
      tableData: Array(20).fill(item),
    };
  },
};
</script>

App.vue

<template>
  <div id="app">
    <router-view />
  </div>
</template>

<style>
html,
body {
  margin: 0;
  padding: 0;
}
</style>

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Main from '../views/Main.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'main',
    component: Main
  },

]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

创建分类(客户端)

views/Main.vue

<template>
  <el-container style="height: 100vh">
    <el-aside width="200px" style="background-color: rgb(238, 241, 246)">
      <el-menu router :default-openeds="['1', '3']">
        <el-submenu index="1">
          <template slot="title"
            ><i class="el-icon-message"></i>内容管理</template
          >
          <el-menu-item-group>
            <template slot="title">分类</template>
            <el-menu-item index="/categories/create">新建分类</el-menu-item>
            <el-menu-item index="/categories/list">分类列表</el-menu-item>
          </el-menu-item-group>
        </el-submenu>
      </el-menu>
    </el-aside>

    <el-container>
      <el-header style="text-align: right; font-size: 12px">
        <el-dropdown>
          <i class="el-icon-setting" style="margin-right: 15px"></i>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item>查看</el-dropdown-item>
            <el-dropdown-item>新增</el-dropdown-item>
            <el-dropdown-item>删除</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <span>王小虎</span>
      </el-header>

      <el-main>
        <router-view></router-view>
      </el-main>
    </el-container>
  </el-container>
</template>

<style>
.el-header {
  background-color: #b3c0d1;
  color: #333;
  line-height: 60px;
}

.el-aside {
  color: #333;
}
</style>

<script>
export default {
  data() {
    const item = {
      date: "2016-05-02",
      name: "王小虎",
      address: "上海市普陀区金沙江路 1518 弄",
    };
    return {
      tableData: Array(20).fill(item),
    };
  },
};
</script>

views/CategoryEdit.vue

<template>
  <div class="about">
    <h1>新建分类</h1>

    <el-form label-width="120px" @submit.native.prevent="save">
      <el-form-item label="名称">
        <el-input v-model="model.name"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" native-type="submit">保存</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      model: {},
    };
  },
  methods: {
    save() {
      // this.$http.post()
    },
  },
};
</script>

router/index.js

在这里插入图片描述
在这里插入图片描述
src/http.js

import axios from 'axios'

const http = axios.create({
    baseURL: 'http://localhost:3000/admin/api'
})

export default http

main.js

在这里插入图片描述

CategoryEdit.vue
在这里插入图片描述

创建分类(服务端)

在这里插入图片描述

server/routes/admin/index.js

module.exports = app => {
	const express = require('express')
	const router = express.Router()
	const Category = require('../../models/Category')
	router.post('/categories', async(req, res) => {
		const model = await Category.create(req.body)
		res.send(model)
	})
	app.use('/admin/api', router)

}

server/index.js

const express = require('express')

const app = express()

app.use(express.json())
app.use(require('cors')())
require('./plugins/db')(app)
require('./routes/admin')(app)

app.listen(3000, ()=> {
	console.log('http://localhost:3000');
});

server/plugin/db.js

module.exports = app => {
	const mongoose = require('mongoose')
	mongoose.connect('mongodb://127.0.0.1:27017/node-vue-moba', {useNewUrlParser: true})
}

server/models/Category.js

const mongoose = require('mongoose')

const schema = new mongoose.Schema({
	name: String
})

module.exports = mongoose.model('Category', schema)

在这里插入图片描述

分类列表

admin/views/CategoryList.vue

<template>
  <div>
    <h1>分类列表</h1>
    <el-table :data="items">
      <el-table-column prop="_id" label="ID" width="230"></el-table-column>
      <el-table-column prop="name" label="分类名称"></el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [],
    };
  },
  methods: {
    async fetch() {
      const res = await this.$http.get("categories");
      this.items = res.data;
    },
  },
  created() {
    this.fetch();
  },
};
</script>

在这里插入图片描述

在这里插入图片描述

分类编辑

在这里插入图片描述
CategoryEdit.vue

<template>
  <div class="about">
    <h1>{{ id ? "编辑" : "新建" }}分类</h1>

    <el-form label-width="120px" @submit.native.prevent="save">
      <el-form-item label="名称">
        <el-input v-model="model.name"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" native-type="submit">保存</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  props: {
    id: {},
  },
  data() {
    return {
      model: {},
    };
  },
  methods: {
    async save() {
      let res;
      if (this.id) {
        res = await this.$http.put(`categories/${this.id}`, this.model);
      } else {
        res = await this.$http.post("categories", this.model);
      }
      this.$router.push("/categories/list");
      this.$message({
        type: "success",
        message: "保存成功",
      });
    },
    async fetch() {
      const res = await this.$http.get(`categories/${this.id}`);
      this.model = res.data;
    },
  },
  created() {
    this.id && this.fetch();
  },
};
</script>

在这里插入图片描述

分类删除

CategoryList.vue

<template>
  <div>
    <h1>分类列表</h1>
    <el-table :data="items">
      <el-table-column prop="_id" label="ID" width="230"></el-table-column>
      <el-table-column prop="name" label="分类名称"></el-table-column>
      <el-table-column fixed="right" label="操作" width="180">
        <template slot-scope="scope">
          <el-button
            @click="$router.push(`/categories/edit/${scope.row._id}`)"
            type="primary"
            size="small"
          >
            编辑
          </el-button>

          <el-button @click="remove(scope.row)" type="primary" size="small">
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [],
    };
  },
  methods: {
    async fetch() {
      const res = await this.$http.get("categories");
      this.items = res.data;
    },
    async remove(row) {
      this.$confirm(`是否确定要删除分类 ${row.name}`, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(async () => {
        const res = await this.$http.delete(`categories/${row._id}`);
        this.$message({
          type: "success",
          message: "删除成功!",
        });
        this.fetch();
      });
    },
  },
  created() {
    this.fetch();
  },
};
</script>

在这里插入图片描述


子分类

子分类部分代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/162015.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Bubbles原理解析

官方文档 https://developer.android.com/develop/ui/views/notifications/bubbles#the_bubble_api 气泡使用户可以轻松查看和参与对话。 气泡内置于通知系统中。 它们漂浮在其他应用程序内容之上&#xff0c;无论用户走到哪里都会跟随他们。 气泡可以展开以显示应用程序功能和…

如何搭建春节值班智能通知方案

春节期间&#xff0c;为了保证业务的正常运转&#xff0c;或者及时响应用户/客户需求&#xff0c;许多公司会安排一些人员轮流进行值班&#xff0c;解决一些突发情况或者问题。在过去&#xff0c;一般是排好值班表后&#xff0c;全靠人工自觉上线进行值班&#xff0c;容易遗忘或…

干货,游戏DDoS攻击趋势及原因分析,附防御案例

我曾看到充满激情的创业团队、一个个玩法很有特色的产品&#xff0c;被这种互联网攻击问题扼杀在摇篮里&#xff1b; 也看到过一个运营很好的产品&#xff0c;因为遭受DDoS攻击&#xff0c;而一蹶不振。这也是为什么想把自己6年做游戏行业DDoS的经验&#xff0c;与大家一起分享…

网络的基础认知

日升时奋斗&#xff0c;日落时自省 目录 1、网络发展史 1.1、独立模式 1.2、局域网 1.3、广域网 2、网络通信基础 2.1、IP地址 2.2、端口号 2.3、协议 2.4、网络协议分层 2.4.1、协议类别 2.4.2、TCP和UDP区别 2.5、分层理解事例 2.5.1 封装 2.5.2分用 2.5.3、总…

114. 二叉树展开为链表

114. 二叉树展开为链表 难度中等 给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。展开后的单链表应该与二叉树 先…

04 链式队列的实现

带头节点的链式队列&#xff1a; 初始化&#xff1a;rear和front指针都指向头节点入队&#xff1a;向rear指向的节点后插入新节点&#xff0c;并让rear指针移动指向新的队尾节点出队&#xff1a;front指针始终指向头节点&#xff0c;即删除头节点后一个节点&#xff1b;最后一个…

Arduino,Nodemcu,ESP8266网络连接(局域网),网页控制内部LED状态变化

整体思路&#xff08;无线终端模式&#xff09; 需要注意&#xff1a;esp8266是 802.11n⽀支持**(2.4GHz )&#xff0c;也就是平常说的wifi4&#xff0c;WiFi5G是连不上的** 配置指定的LED接口&#xff0c;配置网络的WiFi&#xff0c;记录ESP8266模块做为服务器的IP&#xff0…

2022某站百大up主公布名单,python如何快速获取up名单

前言 2022年已经过去&#xff0c;各大厂商都在做年度总结。某站在1月13日中午19点30分公布了2022百大UP主名单&#xff0c;那么今年的某站年度UP主都是谁呢&#xff1f;接下来就让我们一起了解一下吧。不过&#xff0c;我们去用python获取名单&#xff0c;是非常有成就的。 环…

Git(1)基础命令

Git基础知识总结 Author&#xff1a;onceday date&#xff1a;2022年8月8日 满满长路有人对你微笑过嘛… Modified date&#xff1a;2022年11月22日&#xff0c;完成第一章部分内容。 windows安装可参考文章&#xff1a;git简易配置_onceday_CSDN博客 參考文档&#xff1a…

腾讯云短信服务——获取验证码

引言 之前介绍过阿里云短信服务&#xff0c;传送门&#xff1a;阿里云短信服务——短信发送验证码&#xff0c;但是由于阿里云现在短信调用门槛较高&#xff0c;申请有很多限制&#xff08;我申请好几次都没有通过&#xff09;&#xff0c;所以只能使用测试账号给固定的手机号…

2023速卖通开店入驻流程及费用,新店运营思路

开店前准备 从卖家开始注册账户起&#xff0c;需速卖通平台的销售政策和全球速卖通平台规则。平台要求卖家在速卖通经营需遵循公平、诚实的行事原则&#xff0c;以确保安全的购买及销售体验。 1.注册账号 注册账户前&#xff0c;以下所有资料都是必须提供的资料。若资料不完…

AtCoder Beginner Contest 044(4/4)

Tak and Hotels (ABC Edit)前k晚花费x&#xff0c;k1晚以后花费yAC代码&#xff1a;import java.util.*; import java.io.*; public class Main {public static void main(String[] args) {InputStream inputStream System.in;OutputStream outputStream System.out;InputRea…

喜报 | 迅镭激光荣获2022年度江苏省科学技术奖

1月6日&#xff0c;江苏省科技厅发布了2022年度江苏省科学技术奖综合评审结果公示名单&#xff0c;迅镭激光与江苏师范大学等单位合作的“高功率2微米激光器关键技术及应用”项目&#xff0c;荣获2022年度江苏省科学技术二等奖。 江苏省科学技术奖是省内科技领域最高级别的奖项…

Java 23种设计模式(1.设计模式概念和UML)

1. 设计模式概念 软件设计模式&#xff08;Software Design Pattern&#xff09;&#xff0c;又称设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结 1.1 设计模式学习必要性理由 设计模式的本质是面向对象设计原则的实际运用&#xff0c;是对类的…

2022边缘计算开源项目

在边缘计算社区&#xff0c;统计边缘计算开源项目发展情况&#xff0c;开源软件生态蓬勃发展&#xff0c;边缘计算开源项目又是开源软件生态中不可忽视的重要力量。 2022 年边缘计算领域较为活跃和热门的十个开源项目&#xff1a;KubeEdge、EdgeXFoundry、Akraino、OpenYurt、B…

【UE4 第一人称射击游戏】47-修改AI为僵尸样貌

上一篇&#xff1a;【UE4 第一人称射击游戏】46-蹲高调整本篇效果&#xff1a;将AI修改成了僵尸的模样步骤&#xff1a;可以先从Mixamo网站下载 僵尸 资源&#xff0c;相关教程可以参考这篇文章&#xff1a;UE4 利用Mixamo自动绑骨并导入虚幻4我下载的是这个僵尸资源下载的时候…

【Qt】富文本处理简单介绍

文章目录Qt富文本处理富文本文档结构文本块QTextBlock表格、列表、图片查找功能语法高亮与HTML参考《Qt Creator快速入门(第三版)》。 Qt富文本处理 富文本Rich Text&#xff0c;简单说就是在文档中可以使用多种格式&#xff0c;比如字体颜色、图片和表格等&#xff0c;是与纯…

给定一个有序数组arr,代表坐落在X轴上的点 给定一个正数K,代表绳子的长度 返回绳子最多压中几个点? 即使绳子边缘处盖住点也算盖住

目录暴力求解贪心二分法滑动窗口对数器测试题目&#xff1a; 给定一个有序数组arr&#xff0c;代表坐落在X轴上的点 给定一个正数K&#xff0c;代表绳子的长度 返回绳子最多压中几个点&#xff1f; 即使绳子边缘处盖住点也算盖住 这道题有三个解决方案 暴力求解 //暴力求解O(N…

Docker容器MySQL数据库的备份与还原,以及每天定时自动备份.

1.快速启动mysql容器 1&#xff1a;拉取mysql镜像&#xff1a; 根据自己需要&#xff0c;我这个是5.7版本的镜像。 docker pull nanlist/mysql:5.72&#xff1a;宿主机建立挂载目录&#xff1a; mkdir三个文件夹&#xff0c;方便持久化。 /home/mysql/conf /home/mysql/log…

java面试资料(二)

这里写目录标题Spring什么是 Spring Framework&#xff1f;列举 Spring Framework 的优点。Spring Framework 有哪些不同的功能&#xff1f;Spring Framework 中有多少个模块&#xff0c;它们分别是什么&#xff1f;什么是 Spring 配置文件&#xff1f;Spring 应用程序有哪些不…