【商城实战(18)】后台管理系统基础搭建:从0到1构建电商中枢

【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配,乃至运营推广策略,102 章内容层层递进。无论是想深入钻研技术细节,还是探寻商城运营之道,本专栏都能提供从 0 到 1 的系统讲解,助力你打造独具竞争力的电商平台,开启电商实战之旅。

目录

  • 一、创建基于 Element Plus 的后台管理项目
    • 1.1 项目初始化
    • 1.2 安装 Element Plus
    • 1.3 基础页面布局搭建
  • 二、配置后台管理系统菜单及路由
    • 2.1 定义路由规则
    • 2.2 创建菜单组件
    • 2.3 关联菜单与路由
  • 三、搭建后台管理系统用户登录及权限验证机制
    • 3.1 用户登录流程
    • 3.2 Token 验证机制​
    • 3.3 权限控制实现​
  • 四、总结与展望
    • 4.1 回顾搭建过程
    • 4.2 后续优化方向


一、创建基于 Element Plus 的后台管理项目

在开发后台管理系统时,使用 Element Plus 能极大地提高开发效率,它提供了丰富的组件和美观的样式。下面我们将逐步创建基于 Element Plus 的后台管理项目,并搭建基础页面布局。

1.1 项目初始化

首先,确保你已经安装了 Node.js 和 Vue CLI。如果尚未安装 Vue CLI,可以通过以下命令进行全局安装:

npm install -g @vue/cli

安装完成后,使用 Vue CLI 创建一个新的项目,执行以下命令:

vue create admin-system

在创建过程中,会出现一系列选项让你选择项目配置。你可以根据项目需求选择合适的配置,例如是否使用 TypeScript、是否安装路由、是否使用状态管理等。这里我们选择默认配置,快速搭建项目基础框架。选择完成后,Vue CLI 会自动下载项目所需的依赖并初始化项目结构。

1.2 安装 Element Plus

项目初始化完成后,进入项目目录:

cd admin-system

然后使用 npm 安装 Element Plus,执行以下命令:

npm install element - plus --save

安装完成后,有两种方式在项目中引入 Element Plus:全局引入和按需引入。

  • 全局引入:在main.js文件中添加以下代码:
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
import App from './App.vue'const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')

这样,Element Plus 的所有组件都可以在项目中全局使用。

  • 按需引入:如果项目体积对大小比较敏感,希望只引入需要的组件,可以使用按需引入的方式。首先安装unplugin - vue - components和unplugin - auto - import插件,执行以下命令:
npm install -D unplugin - vue - components unplugin - auto - import

然后在vite.config.js(如果使用 Vite 构建工具)或webpack.config.js(如果使用 Webpack 构建工具)中进行配置。以 Vite 为例,在vite.config.js中添加以下配置:

import { defineConfig } from 'vite'
import Components from 'unplugin - vue - components/vite'
import { ElementPlusResolver } from 'unplugin - vue - components/resolvers'export default defineConfig({plugins: [Components({resolvers: [ElementPlusResolver()]})]
})

这样配置后,在使用 Element Plus 组件时,无需手动导入,直接在模板中使用即可,例如:

<template><el - button type="primary">主要按钮</el - button>
</template>

1.3 基础页面布局搭建

使用 Element Plus 的 Container 布局容器来搭建基础页面布局,它提供了el - container、el - header、el - aside、el - main和el - footer等组件,方便快速构建页面结构。

在App.vue文件中编写如下代码:

<template><el - container style="height: 100vh"><el - header><!-- 头部内容,例如导航栏、logo等 --><h1>商城后台管理系统</h1></el - header><el - container><el - aside width="200px"><!-- 侧边栏内容,菜单等 --><el - menu :default - openeds="['1']"><el - sub - menu index="1"><template #title><i class="el - icon - message"></i>商品管理</template><el - menu - item index="1 - 1">商品列表</el - menu - item><el - menu - item index="1 - 2">添加商品</el - menu - item></el - sub - menu><el - sub - menu index="2"><template #title><i class="el - icon - setting"></i>订单管理</template><el - menu - item index="2 - 1">订单列表</el - menu - item><el - menu - item index="2 - 2">订单详情</el - menu - item></el - sub - menu></el - menu></el - aside><el - main><!-- 主要内容区域,根据路由显示不同页面 --><router - view></router - view></el - main></el - container></el - container>
</template><style scoped>
.el - header {background - color: #333;color: #fff;display: flex;justify - content: space - between;align - items: center;padding: 0 20px;
}.el - aside {background - color: #f4f4f4;
}.el - main {background - color: #fff;padding: 20px;
}
</style>

上述代码中,el-container作为外层容器,设置高度为视口高度100vh。el-header用于显示头部内容,设置了背景颜色和样式。el-aside作为侧边栏,包含了商品管理和订单管理的菜单。el-main作为主要内容区域,通过router-view来显示不同路由对应的页面内容。这样就完成了基础页面布局的搭建,一个简单的后台管理系统框架初见雏形。

二、配置后台管理系统菜单及路由

在完成后台管理系统的基础页面布局搭建后,配置菜单及路由是实现页面导航功能的关键步骤。合理的菜单及路由配置能够让用户方便地在不同功能页面之间进行切换,提升系统的易用性和交互性。下面我们将详细介绍如何配置后台管理系统的菜单及路由。

2.1 定义路由规则

在 Vue 项目中,我们使用 Vue Router 来定义路由规则。Vue Router 是 Vue.js 官方的路由管理器,它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。

首先,确保已经安装了 Vue Router。如果在项目初始化时没有选择安装,可以通过以下命令进行安装:

npm install vue-router --save

安装完成后,在src目录下创建router文件夹,并在该文件夹下新建index.js文件,用于定义路由规则。

假设我们有商品列表、添加商品、订单列表、订单详情等页面组件,分别位于src/views/goods和src/views/order目录下,以下是定义路由规则的示例代码:

import { createRouter, createWebHistory } from 'vue-router'
// 引入页面组件
import GoodsList from '@/views/goods/GoodsList.vue'
import AddGoods from '@/views/goods/AddGoods.vue'
import OrderList from '@/views/order/OrderList.vue'
import OrderDetail from '@/views/order/OrderDetail.vue'const routes = [{path: '/goods',name: 'Goods',component: () => import('@/views/goods/Goods.vue'),children: [{path: 'list',name: 'GoodsList',component: GoodsList},{path: 'add',name: 'AddGoods',component: AddGoods}]},{path: '/order',name: 'Order',component: () => import('@/views/order/Order.vue'),children: [{path: 'list',name: 'OrderList',component: OrderList},{path: 'detail/:id',name: 'OrderDetail',component: OrderDetail,props: true // 将路由参数作为props传递给组件}]}
]const router = createRouter({history: createWebHistory(),routes
})export default router

在上述代码中:

  • 使用createRouter和createWebHistory创建路由实例,createWebHistory表示使用 HTML5 的 history 模式,去除 URL 中的#。
  • routes数组定义了路由规则,每个路由对象包含path(路径)、name(路由名)和component(组件)等属性。
  • 对于商品管理和订单管理模块,使用了嵌套路由的配置方式。在Goods和Order路由下,通过children属性定义了子路由,例如GoodsList和AddGoods是Goods路由的子路由,OrderList和OrderDetail是Order路由的子路由。
  • 在OrderDetail路由中,使用了动态路由参数/:id,表示该路由可以匹配不同的订单 ID,例如/order/detail/123,并且通过props: true将路由参数id作为 props 传递给OrderDetail组件,在组件中可以通过this.$route.params.id获取该参数值。

2.2 创建菜单组件

使用 Element Plus 的 Menu 组件来创建后台管理系统的菜单,Menu 组件提供了丰富的功能和样式,方便我们构建出美观且易用的菜单。

在App.vue文件中,我们已经搭建了基础的侧边栏结构,现在进一步完善菜单部分。修改el - aside部分的代码如下:

<el-aside width="200px"><el-menu :default - openeds="['1']" router><el-sub-menu index="1"><template #title><i class="el - icon - message"></i>商品管理</template><el-menu-item :index="'/goods/list'">商品列表</el-menu-item><el-menu-item :index="'/goods/add'">添加商品</el-menu-item></el-sub-menu><el-sub-menu index="2"><template #title><i class="el-icon-setting"></i>订单管理</template><el-menu-item :index="'/order/list'">订单列表</el-menu-item><el-menu-item :index="'/order/detail/1'">订单详情</el-menu-item></el-sub-menu></el-menu>
</el-aside>

在上述代码中:

  • el - menu组件设置了router属性,这使得菜单能够与路由进行关联,实现点击菜单时自动切换到相应的路由页面。
  • :default - openeds="[‘1’]"表示默认展开索引为1的子菜单,即商品管理子菜单。
  • el - sub - menu用于创建二级菜单,index属性为子菜单的唯一标识。
  • el - menu - item为菜单项,index属性指定了菜单项对应的路由路径,例如’/goods/list’和’/goods/add’分别对应商品列表和添加商品的路由路径。

2.3 关联菜单与路由

通过前面的步骤,我们已经定义了路由规则并创建了菜单组件,接下来需要将菜单与路由进行关联,实现点击菜单时切换到相应页面的功能。

由于在el-menu组件上设置了router属性,Element Plus 会自动根据菜单项的index属性值来匹配路由。当用户点击菜单项时,Vue Router 会根据匹配到的路由规则,将对应的组件渲染到router - view中。

此外,路由导航守卫在路由切换过程中起着重要作用。路由导航守卫可以用来对路由的进入和离开进行控制,例如进行权限验证、页面加载前的准备工作等。

在router/index.js文件中,可以使用全局前置守卫beforeEach来实现简单的权限验证功能。假设我们需要用户登录后才能访问后台管理系统的页面,代码如下:

import router from './router'
import store from './store'const whiteList = ['/login'] // 白名单,不需要登录即可访问的页面router.beforeEach((to, from, next) => {const hasToken = store.getters.token // 从状态管理中获取用户登录令牌if (hasToken) {if (to.path === '/login') {next('/') // 如果已登录,访问登录页则重定向到首页} else {next() // 已登录,允许访问其他页面}} else {if (whiteList.includes(to.path)) {next() // 未登录,在白名单内的页面允许访问} else {next(`/login?redirect=${to.path}`) // 未登录,重定向到登录页,并携带当前访问路径}}
})

在上述代码中:

  • beforeEach函数接收三个参数:to表示即将进入的目标路由对象,from表示当前导航正要离开的路由对象,next是一个函数,必须调用它来继续导航。
  • 通过store.getters.token获取用户登录令牌,判断用户是否已登录。如果已登录,且访问的不是登录页,则允许访问;如果已登录但访问登录页,则重定向到首页。
  • 如果未登录,判断当前访问路径是否在白名单内,在白名单内则允许访问,否则重定向到登录页,并将当前访问路径作为参数传递,以便登录成功后能自动跳转到原访问页面。

通过以上步骤,我们成功地配置了后台管理系统的菜单及路由,并实现了页面导航功能和简单的权限验证机制,为后续的功能开发奠定了坚实的基础。

三、搭建后台管理系统用户登录及权限验证机制

在后台管理系统中,用户登录及权限验证机制是保障系统安全的重要环节。它能够确保只有合法用户能够访问系统,并且根据用户的角色和权限限制其对系统功能和数据的访问。下面我们将详细介绍如何搭建后台管理系统的用户登录及权限验证机制,并展示相关的实现源码。

3.1 用户登录流程

在前端登录页面,使用 Element Plus 的 Form 组件收集用户输入的用户名和密码,通过 Axios 发送 POST 请求到后端进行验证。前端代码示例如下:​

<template><el - container class="login - container"><el - form ref="loginFormRef" :model="loginForm" :rules="loginRules" label - width="80px"><el - form - item label="用户名" prop="username"><el - input v - model="loginForm.username" placeholder="请输入用户名"></el - input></el - form - item><el - form - item label="密码" prop="password"><el - input v - model="loginForm.password" type="password" placeholder="请输入密码"></el - input></el - form - item><el - form - item><el - button type="primary" @click="handleLogin">登录</el - button></el - form - item></el - form></el - container></template>​
​
<script setup lang="ts">import { ref } from 'vue';import axios from 'axios';import { useUserStore } from '../stores/user';​
​
const loginForm = ref({​username: '',​password: ''});​
​
const loginRules = ref({​username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],​password: [{ required: true, message: '请输入密码', trigger: 'blur' }]});​
​
const handleLogin = async () => {try {const response = await axios.post('/api/login', loginForm.value);if (response.data.success) {const userStore = useUserStore();​userStore.setToken(response.data.token);​userStore.setUserInfo(response.data.user);// 这里可以根据业务需求进行页面跳转,如跳转到首页​} else {// 提示用户登录失败信息​}} catch (error) {console.error('登录请求失败', error);}};</script>​
​
<style scoped lang="scss">.login - container {​display: flex;​justify - content: center;​align - items: center;​height: 100vh;​background - color: #f0f2f5;}</style>


后端使用 Spring Boot 处理登录请求,在UserController中编写登录接口:​

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RestController;import com.example.mallbackend.dto.LoginRequest;import com.example.mallbackend.dto.LoginResponse;import com.example.mallbackend.service.UserService;​
​
@RestControllerpublic class UserController {@Autowiredprivate UserService userService;​
​@PostMapping("/api/login")public LoginResponse login(@RequestBody LoginRequest loginRequest) {return userService.login(loginRequest);}}


LoginRequest和LoginResponse是自定义的数据传输对象,用于封装前端传递的登录信息和返回给前端的登录结果。​

3.2 Token 验证机制​

前端在每次发送请求时,将 Token 添加到请求头中。在 Axios 的拦截器中进行统一处理:​

import axios from 'axios';import { useUserStore } from '../stores/user';​
​
const service = axios.create({​baseURL: '/api',​timeout: 5000});​
​
service.interceptors.request.use(​config => {const userStore = useUserStore();if (userStore.token) {​config.headers['Authorization'] = `Bearer ${userStore.token}`;}return config;},​error => {return Promise.reject(error);});​
​
service.interceptors.response.use(​response => {return response;},​error => {if (error.response.status === 401) {// Token失效,进行相应处理,如跳转到登录页面​}return Promise.reject(error);});​
​
export default service;


后端在 Spring Boot 项目中,使用过滤器对请求头中的 Token 进行验证。创建一个JwtAuthenticationFilter过滤器:​

import java.io.IOException;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;import org.springframework.web.filter.GenericFilterBean;import io.jsonwebtoken.Claims;import io.jsonwebtoken.Jwts;import com.example.mallbackend.service.UserService;​
​
public class JwtAuthenticationFilter extends GenericFilterBean {private static final String HEADER_STRING = "Authorization";private static final String TOKEN_PREFIX = "Bearer ";private final UserService userService;private final String secret;​
​public JwtAuthenticationFilter(UserService userService, String secret) {this.userService = userService;this.secret = secret;}​
​@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;String header = request.getHeader(HEADER_STRING);if (header != null && header.startsWith(TOKEN_PREFIX)) {String token = header.replace(TOKEN_PREFIX, "");Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();String username = claims.getSubject();UserDetails userDetails = userService.loadUserByUsername(username);UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(​userDetails, null, userDetails.getAuthorities());​authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));SecurityContextHolder.getContext().setAuthentication(authentication);}​filterChain.doFilter(servletRequest, servletResponse);}}


在 Spring Security 配置类中注册该过滤器:​

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.config.http.SessionCreationPolicy;import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;import com.example.mallbackend.service.UserService;import com.example.mallbackend.filter.JwtAuthenticationFilter;​
​
@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {private final UserService userService;private final String secret;​
​public SecurityConfig(UserService userService, String secret) {this.userService = userService;this.secret = secret;}​
​@Overrideprotected void configure(HttpSecurity http) throws Exception {​http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().addFilterBefore(new JwtAuthenticationFilter(userService, secret),UsernamePasswordAuthenticationFilter.class).authorizeRequests().antMatchers("/api/login").permitAll().anyRequest().authenticated();}}


上述代码实现了前端和后端的 Token 验证机制,确保只有合法的用户请求能够访问受保护的资源。​

3.3 权限控制实现​

在前端,根据用户的角色动态显示或隐藏菜单和页面元素。例如,在菜单组件中根据用户角色判断是否显示某些菜单项:​

<template><el - menu :default - active="activeIndex" class="el - menu - vertical - demo" @select="handleSelect"><el - menu - item index="/"><el - icon><HomeFilled /></el - icon><span>首页</span></el - menu - item><el - menu - item v - if="userStore.role === 'admin'" index="/user"><el - icon><UserFilled /></el - icon><span>用户管理</span></el - menu - item><el - menu - item v - if="userStore.role === 'admin' || userStore.role ==='seller'" index="/product"><el - icon><GoodsFilled /></el - icon><span>商品管理</span></el - menu - item></el - menu></template>​
​
<script setup lang="ts">import { ref } from 'vue';import { HomeFilled, UserFilled, GoodsFilled } from '@element - plus/icons - vue';import { useUserStore } from '../stores/user';​
​
const activeIndex = ref('/');const handleSelect = (index: string) => {// 这里可以添加点击菜单后的额外逻辑,如记录操作日志等​activeIndex.value = index;};</script>​
​
<style scoped lang="scss">.el - menu - vertical - demo {​height: 100%;​border - right: none;}</style>



在后端,通过 Spring Security 的注解和配置来实现对接口的权限控制。例如,在UserController中对某些接口添加权限注解:​

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.access.prepost.PreAuthorize;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.example.mallbackend.service.UserService;​
​
@RestController@RequestMapping("/api/user")public class UserController {@Autowiredprivate UserService userService;​
​@GetMapping("/admin - only")@PreAuthorize("hasRole('ADMIN')")public String adminOnly() {return "This is an admin - only endpoint";}}


上述代码展示了前端和后端协同实现的权限控制机制,确保不同角色的用户只能访问其被授权的功能和页面。

四、总结与展望

4.1 回顾搭建过程

在本次后台管理系统的基础搭建中,我们首先使用Vue CLI创建了项目,并成功安装和引入了Element Plus组件库,通过其Container布局容器搭建了美观且实用的基础页面布局,包含了清晰的头部、侧边栏和主要内容区域。

接着,利用Vue Router定义了详细的路由规则,涵盖了商品管理、订单管理等多个模块及其子路由,同时创建了基于Element Plus Menu组件的菜单,并通过设置router属性实现了菜单与路由的无缝关联,还运用路由导航守卫实现了简单的权限验证,确保只有合法用户能够访问特定页面。

最后,搭建了用户登录及权限验证机制。完善的用户登录流程确保了用户身份的准确识别,可靠的 Token 验证机制保障了请求的安全性,细致的权限控制实现则从前端和后端两个层面保证了不同角色用户对系统资源的合理访问,为整个商城后台管理系统的稳定运行和数据安全奠定了坚实基础。

4.2 后续优化方向

在后续的开发中,我们可以从多个方面对后台管理系统进行优化。性能优化方面,通过代码压缩、缓存机制、异步加载等技术,提高系统的响应速度和运行效率,减少页面加载时间,提升用户体验。安全加固方面,进一步完善权限管理,采用更复杂的加密算法和安全策略,防止数据泄露和非法访问,例如对用户数据进行加密存储,对敏感操作进行详细的日志记录以便追溯。用户体验改进方面,优化界面设计,使其更加简洁美观、易于操作,增加操作提示和反馈机制,让用户在使用过程中更加清晰地了解系统状态和操作结果。同时,不断完善系统的功能,根据业务需求添加更多实用的功能模块,如数据分析、报表生成等,以满足商城运营和管理的多样化需求 。通过持续的优化和完善,使后台管理系统更加稳定、高效、安全,为商城的顺利运营提供坚实的支持。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

项目部署到生产上遇到的网络问题

今天项目上线不顺利,原因就是网络能 telnet 通过&#xff0c;但是就是访问不到接口。 项目使用的是 docker 部署的方式。一开始以为是网络权限没开通&#xff0c;一直找运维部门帮忙看&#xff0c;也都没发现问题&#xff0c;网络部门已经把权限都开了。 折腾了一番后&#x…

Odoo 18 中的列表视图装饰属性

引言 列表视图装饰在 Odoo 中提供了一种基于特定条件在列表/树形视图中直观突出显示记录或字段的方式。这些装饰能够提升用户体验&#xff0c;使用户更轻松地识别重要记录。在 Odoo 18 中&#xff0c;有多个属性可用于列表视图装饰&#xff0c;为数据管理提供了灵活性。 以下…

SpringMVC中有关请求参数的问题(映射路径,传递不同的参数)

目录 请求映射路径 get请求与psot请求发送普通参数 get请求发送参数 post请求发送参数 post请求乱码问题 5种参数类型传递 普通参数传递&#xff08;不同名&#xff09; 实体类对象传递 数组传递 集合参数 json数据传递参数 JSON数组 JSON对象 ​编辑 JSON引用集…

图片查看器:用PyQt5实现本地图片预览工具

通过python代码&#xff0c;基于PyQt5实现本地图片预览查看工具。 我们对窗口进行了圆角设计&#xff0c;图片的翻页按钮半透明处理&#xff0c;当鼠标移动至按钮上的动画效果&#xff0c;当选择某一张图片&#xff0c;进行左右翻页则轮播同目录所有支持的图片格式。 import …

算法优选系列(1.双指针_下)

目录 五. 有效三角形的个数&#xff08;medium&#xff09; 题目链接&#xff1a;有效三角形的个数 解法: 代码&#xff1a; 六&#xff1a;和为 s 的两个数字&#xff08;easy&#xff09; 题目链接&#xff1a;和为 s 的两个数字 解法&#xff1a; 代码; 七&#xf…

【数据结构】2算法及分析

0 章节 &#xff11;&#xff0e;&#xff14;到1&#xff0e;&#xff15;小节。 掌握算法概念、特性、描述、算法性能时间复杂度和空间复杂度&#xff1b; 理解递归含义&#xff1f; 掌握实现递归的条件和时机&#xff1b; 应用简单递归问题的算法设计&#xff1b; 重点 算法…

要在Unreal Engine 5(UE5)中实现角色打击怪物并让怪物做出受击反应,

UE5系列文章目录 文章目录 UE5系列文章目录前言一、实现思路二、最终效果 前言 ue5角色受击没有播放受击动画&#xff0c;主角达到怪物身上没有反应 一、实现思路 要在Unreal Engine 5&#xff08;UE5&#xff09;中实现角色打击怪物并让怪物做出受击反应&#xff0c;你需要…

Java糊涂包(Hutool)的安装教程并进行网络爬虫

Hutool的使用教程 1&#xff1a;在官网下载jar模块文件 Central Repository: cn/hutool/hutool-all/5.8.26https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.26/ 下载后缀只用jar的文件 2&#xff1a;复制并到idea当中&#xff0c;右键这个模块点击增加到库 3&…

C++从零实现Json-Rpc框架

文章目录 一、项目介绍1. 基本原理2. 涉及到的技术栈3. 最终实现的效果 二、 第三方库的介绍与使用1. JsonCpp库Json的数据格式JsonCpp介绍封装Json工具类 2. muduo库muduo库是什么Muduo库常见接口介绍 3. C11异步操作std::future 三、框架设计1. 服务端模块划分NetworkProtoco…

用伪元素和jquery实现tab标签切换(下标线样式)

HTML代码 <div class"title"><div class"tab-item active">按场景</div><div class"tab-item">按名称</div><div class"tab-item">按手机号</div> </div> CSS代码 .active{positio…

Python写一个查星座的小程序,适合初学者练手——字典和if语句练习

一、界面预览 二、完整代码 # 导入必要的库 import tkinter as tk from tkinter import ttk # 导入ttk模块用于更现代的控件 from PIL import Image, ImageTk # 用于处理图片 import os # 用于文件路径操作class ZodiacApp:def __init__(self, root):self.root rootself.r…

【A2DP】蓝牙A2DP协议剖析:从架构到规范

目录 一、A2DP 协议架构 1.1 A2DP 协议栈结构组成 1.2 协议栈各部分的关系与作用 二、设备配置与角色定义&#xff08;Configurations and roles &#xff09; 2.1 角色定义 2.2 配置示例与角色体现 三、用户需求与场景 3.1 用户需求与场景 3.2 协议限制 3.3 协议要求…

C语言for循环语句的用法(非常详细)

在 C语言中&#xff0c;除了 while 和 do while&#xff0c;使用 for 语句也可以实现循环结构。 C语言for循环的基本用法 for 循环语句的一般形式如下&#xff1a; for(表达式1;表达式2;表达式3) {语句块; } 有以下几点说明&#xff1a; for 是循环结构中的关键字之一。表…

Flutter 学习之旅 之 flutter 不使用插件,实现简单带加载动画的 LoadingToast 功能

Flutter 学习之旅 之 flutter 不使用插件&#xff0c;实现简单带加载动画的 LoadingToast 功能 目录 Flutter 学习之旅 之 flutter 不使用插件&#xff0c;实现简单带加载动画的 LoadingToast 功能 一、简单介绍 二、LoadingToast 三、简单案例实现 四、关键代码 一、简单…

289. 生命游戏

根据 百度百科 &#xff0c; 生命游戏 &#xff0c;简称为 生命 &#xff0c;是英国数学家约翰何顿康威在 1970 年发明的细胞自动机。 给定一个包含 m n 个格子的面板&#xff0c;每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态&#xff1a; 1 即为 活细胞 &am…

滑动窗口及边缘化直观理解

文章目录 问题例子example求解思路边缘化边缘化原理边缘化的实际步骤marg先验约束公式先验约束公式1先验约束公式2 marg的问题及FEJ实例分析&#xff1a;VINS-Mono中的滑动窗口策略 边缘化的代码实现&#xff08;伪代码&#xff09; 参考 本文简要介绍VIO常用的滑动窗口及边缘化…

类和对象(下)

一.再谈构造函数 构造函数有构造函数体赋值实现和初始化列表两种方式 1.构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数&#xff0c;给对象中各个成员变量一个合适的初始值. 虽然上述构造函数调用之后&#xff0c;对象中已经有了一个初始值&#xff0c;但是…

在资源有限中逆势突围:从抗战智谋到寒门高考的破局智慧

目录 引言 一、历史中的非对称作战&#xff1a;从李牧到八路军的智谋传承 李牧戍边&#xff1a;古代军事博弈中的资源重构 八路军的游击战&#xff1a;现代战争中的智慧延续 二、创业界的逆袭之道&#xff1a;小米与拼多多的资源重构 从MVP到杠杆解 社交裂变与资源错配 …

eLection: 1靶场渗透测试

eLection: 1 来自 <eLection: 1 ~ VulnHub> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182&#xff0c;靶场IP192.168.23.196 3&#xff0c;对靶机进行端口服…

RuleOS:区块链开发的“新引擎”,点燃Web3创新之火

RuleOS&#xff1a;区块链开发的“新引擎”&#xff0c;点燃Web3创新之火 在区块链技术的浪潮中&#xff0c;RuleOS宛如一台强劲的“新引擎”&#xff0c;为个人和企业开发去中心化应用&#xff08;DApp&#xff09;注入了前所未有的动力。它以独特的设计理念和强大的功能特性&…