SpringBoot和Vue.js實(shí)現(xiàn)的前后端分離的用戶權(quán)限管理系統(tǒng)
后端實(shí)現(xiàn)
1. 數(shù)據(jù)庫(kù)設(shè)計(jì)
我們需要設(shè)計(jì)兩個(gè)表:用戶表和角色表。
用戶表
字段 類型 描述
id bigint(20) 用戶 ID
username varchar(50) 用戶名
password varchar(255) 密碼
email varchar(50) 郵箱
phone varchar(20) 手機(jī)號(hào)碼
create_by varchar(50) 創(chuàng)建人
create_time datetime 創(chuàng)建時(shí)間
update_by varchar(50) 最后修改人
update_time datetime 最后修改時(shí)間
status tinyint(1) 用戶狀態(tài)
角色表
字段 類型 描述
id bigint(20) 角色 ID
role_name varchar(50) 角色名稱
create_by varchar(50) 創(chuàng)建人
create_time datetime 創(chuàng)建時(shí)間
update_by varchar(50) 最后修改人
update_time datetime 最后修改時(shí)間
status tinyint(1) 角色狀態(tài)
用戶角色表
字段 類型 描述
id bigint(20) ID
user_id bigint(20) 用戶 ID
role_id bigint(20) 角色 ID
create_by varchar(50) 創(chuàng)建人
create_time datetime 創(chuàng)建時(shí)間
update_by varchar(50) 最后修改人
update_time datetime 最后修改時(shí)間
status tinyint(1) 狀態(tài)
2. 創(chuàng)建 Maven 項(xiàng)目
使用 Maven 創(chuàng)建 Spring Boot 項(xiàng)目,引入 Spring Boot Web、Spring Boot JPA、MySQL 和 Lombok 等依賴??梢允褂靡韵旅顒?chuàng)建 Maven 項(xiàng)目:
mvn archetype:generate -DgroupId=com.example -DartifactId=user-management -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
3. 配置數(shù)據(jù)庫(kù)
在 application.properties 文件中添加以下配置:
spring.datasource.url=jdbc:mysql://localhost:3306/user_management?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.show_sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.use_sql_comments=true
4. 創(chuàng)建實(shí)體類
創(chuàng)建 User、Role 和 UserRole 實(shí)體類,使用 Lombok 注解簡(jiǎn)化代碼。具體代碼如下:
User.java
@Data
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id
User.java(續(xù))
java
Copy code
private String username;
private String password;
private String email;
private String phone;
private String createBy;
private Date createTime;
private String updateBy;
private Date updateTime;
private Boolean status;
}Role.java
@Data
@Entity
@Table(name = "role")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String roleName;
private String createBy;
private Date createTime;
private String updateBy;
private Date updateTime;
private Boolean status;
}
UserRole.java
@Data
@Entity
@Table(name = "user_role")
public class UserRole {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long userId;
private Long roleId;
private String createBy;
private Date createTime;
private String updateBy;
private Date updateTime;
private Boolean status;
}
5. 創(chuàng)建 Repository
創(chuàng)建 UserRepository、RoleRepository 和 UserRoleRepository,用于操作數(shù)據(jù)庫(kù)。
UserRepository.java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
RoleRepository.java
@Repository
public interface RoleRepository extends JpaRepository<Role, Long> {
}
UserRoleRepository.java
@Repository
public interface UserRoleRepository extends JpaRepository<UserRole, Long> {
List<UserRole> findByUserId(Long userId);
}6. 創(chuàng)建 Service
創(chuàng)建 UserService、RoleService 和 UserRoleService,用于處理業(yè)務(wù)邏輯。
UserService.java
@Service
public class UserService {
? ? @Autowired
? ? private UserRepository userRepository;
? ? @Autowired
? ? private UserRoleRepository userRoleRepository;
? ? public User findByUsername(String username) {
? ? ? ? return userRepository.findByUsername(username);
? ? }
? ? public List<UserRole> findUserRolesByUserId(Long userId) {
? ? ? ? return userRoleRepository.findByUserId(userId);
? ? }
}RoleService.java
@Service
public class RoleService {
@Autowired
private RoleRepository roleRepository;
}
UserRoleService.java
@Service
public class UserRoleService {
@Autowired
private UserRoleRepository userRoleRepository;
}
7. 創(chuàng)建 Controller
創(chuàng)建 UserController、RoleController 和 UserRoleController,用于處理請(qǐng)求。
UserController.java
@RestController
@RequestMapping("/api/user")
public class UserController {
? ? @Autowired
? ? private UserService userService;
? ? @GetMapping("/{username}")
? ? public User findByUsername(@PathVariable String username) {
? ? ? ? return userService.findByUsername(username);
? ? }
? ? @GetMapping("/{userId}/roles")
? ? public List<UserRole> findUserRolesByUserId(@PathVariable Long userId) {
? ? ? ? return userService.findUserRolesByUserId(userId);
? ? }
}RoleController.java
@RestController
@RequestMapping("/api/role")
public class RoleController {
? ? @Autowired
? ? private RoleService roleService;
? ? @GetMapping("")
? ? public List<Role> findAll() {
? ? ? ? return roleService.findAll();
? ? }
}UserRoleController.java
@RestController
@RequestMapping("/api/userRole")
public class UserRoleController {
@Autowired
private UserRoleService userRoleService;
}
8. 啟動(dòng)應(yīng)用
使用 Maven 命令 mvn spring-boot:run 啟動(dòng)應(yīng)用,或者直接運(yùn)行 UserManagementApplication 類。
9. 完整的SecurityConfig.java:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
? ? @Autowired
? ? private UserDetailsServiceImpl userDetailsService;
? ? @Autowired
? ? private JwtAuthenticationEntryPoint unauthorizedHandler;
? ? @Bean
? ? public JwtAuthenticationFilter jwtAuthenticationFilter() {
? ? ? ? return new JwtAuthenticationFilter();
? ? }
? ? @Override
? ? public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
? ? ? ? authenticationManagerBuilder
? ? ? ? ? ? ? ? .userDetailsService(userDetailsService)
? ? ? ? ? ? ? ? .passwordEncoder(passwordEncoder());
? ? }
? ? @Bean(BeanIds.AUTHENTICATION_MANAGER)
? ? @Override
? ? public AuthenticationManager authenticationManagerBean() throws Exception {
? ? ? ? return super.authenticationManagerBean();
? ? }
? ? @Bean
? ? public PasswordEncoder passwordEncoder() {
? ? ? ? return new BCryptPasswordEncoder();
? ? }
? ? @Override
? ? protected void configure(HttpSecurity http) throws Exception {
? ? ? ? http
? ? ? ? ? ? ? ? .cors()
? ? ? ? ? ? ? ? ? ? .and()
? ? ? ? ? ? ? ? .csrf()
? ? ? ? ? ? ? ? ? ? .disable()
? ? ? ? ? ? ? ? .exceptionHandling()
? ? ? ? ? ? ? ? ? ? .authenticationEntryPoint(unauthorizedHandler)
? ? ? ? ? ? ? ? ? ? .and()
? ? ? ? ? ? ? ? .sessionManagement()
? ? ? ? ? ? ? ? ? ? .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
? ? ? ? ? ? ? ? ? ? .and()
? ? ? ? ? ? ? ? .authorizeRequests()
? ? ? ? ? ? ? ? ? ? .antMatchers("/api/auth/**")
? ? ? ? ? ? ? ? ? ? ? ? .permitAll()
? ? ? ? ? ? ? ? ? ? .anyRequest()
? ? ? ? ? ? ? ? ? ? ? ? .authenticated();
? ? ? ? http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
? ? }
}其中,JwtAuthenticationFilter是前面提到的JWT認(rèn)證過(guò)濾器,UserDetailsServiceImpl是實(shí)現(xiàn)了Spring Security的UserDetailsService接口的用戶服務(wù)類,JwtAuthenticationEntryPoint是未經(jīng)授權(quán)時(shí)拋出的異常處理程序。配置類中的configure方法配置了授權(quán)規(guī)則,訪問(wèn)“/api/auth/**”路徑下的接口不需要認(rèn)證即可訪問(wèn),其他所有請(qǐng)求都需要認(rèn)證后才能訪問(wèn)。同時(shí),我們也添加了JWT認(rèn)證過(guò)濾器。
前端實(shí)現(xiàn)
1. 創(chuàng)建 Vue.js 項(xiàng)目
使用 Vue CLI 創(chuàng)建項(xiàng)目:
vue create user-management
2. 添加依賴
在 package.json 中添加以下依賴:
{
"dependencies": {
"axios": "^0.21.1",
"element-plus": "^1.0.2-beta.55",
"vue": "^2.6.12",
"vue-router": "^3.5.1"
}
}
然后執(zhí)行 npm install 安裝依賴。
3. 配置 Axios
在 src/main.js 中添加以下代碼:
import axios from 'axios' axios.defaults.baseURL = 'http://localhost:8080/api' Vue.prototype.$http = axios
4. 創(chuàng)建路由
在 src/router/index.js 中添加以下代碼:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Login from '../views/Login.vue'
Vue.use(VueRouter)
const routes = [
? {
? ? path: '/',
? ? name: 'Home',
? ? component: Home
? },
? {
? ? path: '/login',
? ? name: 'Login',
? ? component: Login
? }
]
const router = new VueRouter({
? mode: 'history',
? base: process.env.BASE_URL,
? routes
})
export default router5. 創(chuàng)建頁(yè)面
在 src/views 目錄下創(chuàng)建以下頁(yè)面:
Home.vue
<template>
? <div>
? ? <h1>用戶管理</h1>
? ? <table>
? ? ? <thead>
? ? ? ? <tr>
? ? ? ? ? <th>用戶名</th>
? ? ? ? ? <th>郵箱</th>
? ? ? ? ? <th>手機(jī)號(hào)碼</th>
? ? ? ? ? <th>操作</th>
? ? ? ? </tr>
? ? ? </thead>
? ? ? <tbody>
? ? ? ? <tr v-for="user in users" :key="user.id">
? ? ? ? ? <td>{{ user.username }}</td>
? ? ? ? ? <td>{{ user.email }}</td>
? ? ? ? ? <td>{{ user.phone }}</td>
? ? ? ? ? <td>
? ? ? ? ? ? <button @click="editUser(user)">編輯</button>
? ? ? ? ? ? <button @click="deleteUser(user)">刪除</button>
? ? ? ? ? </td>
? ? ? ? </tr>
? ? ? </tbody>
? ? </table>
? </div>
</template>
<script>
export default {
? name: 'Home',
? data() {
? ? return {
? ? ? users: []
? ? }
? },
? mounted() {
? ? this.loadUsers()
? },
? methods: {
? ? loadUsers() {
? ? ? this.$http.get('/user')
? ? ? ? .then(response => {
? ? ? ? ? this.users = response.data
? ? ? ? })
? ? ? ? .catch(error => {
? ? ? ? ? console.log(error)
? ? ? ? })
? ? },
? ? editUser(user) {
? ? ? console.log(user)
? ? },
? ? deleteUser(user) {
? ? ? console.log(user)
? ? }
? }
}
</script>Login.vue
<template>
? <div>
? ? <h1>登錄</h1>
? ? <form @submit.prevent="login">
? ? ? <div>
? ? ? ? <label>用戶名:</label>
? ? ? ? <input type="text" v-model="username" />
? ? ? </div>
? ? ? <div>
? ? ? ? <label>密碼:</label>
? ? ? ? <input type="password" v-model="password" />
? ? ? </div>
? ? ? <button type="submit">登錄</button>
? ? </form>
? </div>
</template>
<script>
export default {
? name: 'Login',
? data() {
? ? return {
? ? ? username: '',
? ? ? password: ''
? ? }
? },
? methods: {
? ? login() {
? ? ? const params = {
? ? ? ? username: this.username,
? ? ? ? password: this.password
? }
? this.$http.post('/login', params)
? ? .then(response => {
? ? ? console.log(response)
? ? })
? ? .catch(error => {
? ? ? console.log(error)
? ? })
}
}
}
</script>6. 添加 Element UI 組件
在 src/main.js 中添加以下代碼:
import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' Vue.use(ElementPlus)
7. 運(yùn)行項(xiàng)目
在項(xiàng)目根目錄下執(zhí)行以下命令運(yùn)行項(xiàng)目:
npm run serve
然后在瀏覽器中訪問(wèn) http://localhost:8080 查看效果。
以上代碼只是簡(jiǎn)單地實(shí)現(xiàn)了用戶列表的顯示以及登錄功能的實(shí)現(xiàn),還需要進(jìn)一步完善和優(yōu)化。同時(shí),還需要在后端實(shí)現(xiàn)相應(yīng)的接口。
8. 添加路由
在 src/router/index.js 中添加以下代碼:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../views/Login.vue'
import UserList from '../views/UserList.vue'
Vue.use(VueRouter)
const routes = [
? {
? ? path: '/',
? ? redirect: '/login'
? },
? {
? ? path: '/login',
? ? name: 'Login',
? ? component: Login
? },
? {
? ? path: '/userlist',
? ? name: 'UserList',
? ? component: UserList,
? ? meta: {
? ? ? requireAuth: true
? ? }
? }
]
const router = new VueRouter({
? mode: 'history',
? base: process.env.BASE_URL,
? routes
})
export default router其中,meta 屬性中的 requireAuth 表示該路由需要登錄才能訪問(wèn)。
9. 添加登錄攔截
在 src/main.js 中添加以下代碼:
router.beforeEach((to, from, next) => {
if (to.meta.requireAuth && !localStorage.getItem('token')) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
})
這段代碼的作用是,在用戶訪問(wèn)需要登錄才能訪問(wèn)的路由時(shí),檢查用戶是否已登錄。如果用戶未登錄,則跳轉(zhuǎn)到登錄頁(yè)面,并將目標(biāo)路由的路徑保存到查詢參數(shù)中,以便用戶登錄成功后自動(dòng)跳轉(zhuǎn)到目標(biāo)路由。
10. 添加用戶服務(wù)
在 src/services 目錄下創(chuàng)建 UserService.js 文件,并添加以下代碼:
import axios from 'axios'
const API_URL = '/api/users/'
class UserService {
? getUsers () {
? ? return axios.get(API_URL)
? }
? getUser (id) {
? ? return axios.get(API_URL + id)
? }
? createUser (data) {
? ? return axios.post(API_URL, data)
? }
? updateUser (id, data) {
? ? return axios.put(API_URL + id, data)
? }
? deleteUser (id) {
? ? return axios.delete(API_URL + id)
? }
}
export default new UserService()該文件定義了一個(gè) UserService 類,用于向后端發(fā)送請(qǐng)求,獲取用戶數(shù)據(jù)。其中,API_URL 表示后端 API 的根路徑,getUsers、getUser、createUser、updateUser 和 deleteUser 方法分別對(duì)應(yīng)獲取用戶列表、獲取單個(gè)用戶、創(chuàng)建用戶、更新用戶和刪除用戶。
11. 添加用戶列表頁(yè)面
在 src/views 目錄下創(chuàng)建 UserList.vue 文件,并添加以下代碼:
<template>
? <div>
? ? <h1>用戶列表</h1>
? ? <div class="mb-3">
? ? ? <router-link to="/user/add" class="btn btn-primary">添加用戶</router-link>
? ? </div>
? ? <table class="table table-striped">
? ? ? <thead>
? ? ? ? <tr>
? ? ? ? ? <th>用戶名</th>
? ? ? ? ? <th>郵箱</th>
? ? ? ? ? <th>角色</th>
? ? ? ? ? <th>操作</th>
? ? ? ? </tr>
? ? ? </thead>
? ? ? <tbody>
? ? ? ? <tr v-for="user in userList" :key="user.id">
? ? ? ? ? <td>{{ user.username }}</td>
? ? ? ? ? <td>{{ user.email }}</td>
? ? ? ? ? <td>{{ user.roles.map(role => role.name).join(', ') }}</td>
? ? ? ? ? <td>
? ? ? ? ? ? <router-link :to="'/user/edit/' + user.id" class="btn btn-primary">編輯</router-link>
? ? ? ? ? ? <button class="btn btn-danger" @click="deleteUser(user.id)">刪除</button>
? ? ? ? ? </td>
? ? ? ? </tr>
? ? ? </tbody>
? ? </table>
? </div>
</template>
<script>
import axios from "axios";
export default {
? data() {
? ? return {
? ? ? userList: [],
? ? };
? },
? methods: {
? ? fetchUserList() {
? ? ? axios.get("/api/private/users").then((response) => {
? ? ? ? this.userList = response.data;
? ? ? });
? ? },
? ? deleteUser(id) {
? ? ? if (confirm("確定刪除該用戶嗎?")) {
? ? ? ? axios.delete(`/api/private/users/${id}`).then(() => {
? ? ? ? ? this.fetchUserList();
? ? ? ? });
? ? ? }
? ? },
? },
? mounted() {
? ? this.fetchUserList();
? },
};
</script>這個(gè)文件中,我們使用了vue-router和axios庫(kù)。在fetchUserList方法中,我們使用axios庫(kù)發(fā)起了一個(gè)GET請(qǐng)求來(lái)獲取用戶列表。在deleteUser方法中,我們使用axios庫(kù)發(fā)起了一個(gè)DELETE請(qǐng)求來(lái)刪除用戶。
接下來(lái)我們將完成系統(tǒng)的權(quán)限控制部分。在Spring Security中,權(quán)限控制通常通過(guò)定義安全配置類來(lái)實(shí)現(xiàn)。
首先,我們需要?jiǎng)?chuàng)建一個(gè)實(shí)現(xiàn)了WebSecurityConfigurer接口的安全配置類SecurityConfig。在這個(gè)類中,我們可以配置用戶認(rèn)證和授權(quán)規(guī)則。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/private/**").authenticated()
.and().formLogin()
.loginPage("/login")
.permitAll()
.defaultSuccessUrl("/")
.and().logout().logoutUrl("/logout").logoutSuccessUrl("/login").invalidateHttpSession(true);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}在上述代碼中,我們配置了以下規(guī)則:
- 所有以/api/public開(kāi)頭的請(qǐng)求都不需要認(rèn)證即可訪問(wèn)。
- 所有以/api/private開(kāi)頭的請(qǐng)求都需要認(rèn)證才能訪問(wèn)。
- 登錄頁(yè)面為/login,登錄成功后默認(rèn)跳轉(zhuǎn)到根路徑/。
- 注銷路徑為/logout,注銷成功后跳轉(zhuǎn)到登錄頁(yè)面。
- 在AuthenticationManagerBuilder中指定了用戶認(rèn)證服務(wù)和密碼加密方式。
為了實(shí)現(xiàn)用戶認(rèn)證,我們需要?jiǎng)?chuàng)建一個(gè)實(shí)現(xiàn)了UserDetailsService接口的用戶認(rèn)證服務(wù)。UserDetailsService是一個(gè)Spring Security的核心接口,用于查詢用戶信息。我們可以通過(guò)重寫(xiě)該接口的loadUserByUsername方法來(lái)實(shí)現(xiàn)自定義的用戶認(rèn)證邏輯。
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("用戶不存在");
}
List<SimpleGrantedAuthority> authorities = user.getRoles().stream()
.map(role -> new SimpleGrantedAuthority(role.getName()))
.collect(Collectors.toList());
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
authorities);
}
}在上述代碼中,我們通過(guò)注入U(xiǎn)serRepository來(lái)查詢用戶信息。然后,我們將查詢到的用戶角色信息轉(zhuǎn)換為Spring Security的授權(quán)信息,并返回一個(gè)UserDetails對(duì)象。
至此,我們已經(jīng)完成了用戶認(rèn)證和權(quán)限控制的實(shí)現(xiàn)。通過(guò)這個(gè)系統(tǒng),我們可以實(shí)現(xiàn)用戶登錄、注銷和權(quán)限控制等基礎(chǔ)功能。
12. 完整的AddUser.vue組件代碼:
<template>
? <div>
? ? <h2>Add User</h2>
? ? <form>
? ? ? <div class="form-group">
? ? ? ? <label for="username">Username</label>
? ? ? ? <input type="text" class="form-control" id="username" v-model="user.username" required>
? ? ? </div>
? ? ? <div class="form-group">
? ? ? ? <label for="email">Email</label>
? ? ? ? <input type="email" class="form-control" id="email" v-model="user.email" required>
? ? ? </div>
? ? ? <div class="form-group">
? ? ? ? <label for="password">Password</label>
? ? ? ? <input type="password" class="form-control" id="password" v-model="user.password" required>
? ? ? </div>
? ? ? <div class="form-group">
? ? ? ? <label for="roles">Roles</label>
? ? ? ? <select multiple class="form-control" id="roles" v-model="user.roles">
? ? ? ? ? <option v-for="role in roles" :key="role.id" :value="role">{{ role.name }}</option>
? ? ? ? </select>
? ? ? </div>
? ? ? <button type="button" class="btn btn-primary" @click="addUser">Add User</button>
? ? </form>
? </div>
</template>
<script>
import axios from 'axios';
export default {
? name: 'AddUser',
? data() {
? ? return {
? ? ? user: {
? ? ? ? username: '',
? ? ? ? email: '',
? ? ? ? password: '',
? ? ? ? roles: []
? ? ? },
? ? ? roles: []
? ? }
? },
? created() {
? ? axios.get('/api/roles')
? ? ? .then(response => {
? ? ? ? this.roles = response.data;
? ? ? })
? ? ? .catch(error => {
? ? ? ? console.log(error);
? ? ? });
? },
? methods: {
? ? addUser() {
? ? ? axios.post('/api/users', this.user)
? ? ? ? .then(response => {
? ? ? ? ? this.$router.push({ name: 'UserList' });
? ? ? ? })
? ? ? ? .catch(error => {
? ? ? ? ? console.log(error);
? ? ? ? });
? ? }
? }
}
</script>
<style scoped>
.form-group {
? margin-bottom: 1rem;
}
</style>在這個(gè)組件中,我們使用了Bootstrap的樣式來(lái)美化表單。我們從后端獲取了所有的角色列表,將其渲染到了下拉列表中。同時(shí),我們綁定了一個(gè)addUser方法,在點(diǎn)擊“Add User”按鈕時(shí)將用戶信息提交到后端創(chuàng)建一個(gè)新用戶。13. 完整的UserForm.vue組件代碼:
<template>
? <div>
? ? <form>
? ? ? <div class="form-group">
? ? ? ? <label for="username">Username</label>
? ? ? ? <input type="text" class="form-control" id="username" v-model="user.username" required>
? ? ? </div>
? ? ? <div class="form-group">
? ? ? ? <label for="email">Email</label>
? ? ? ? <input type="email" class="form-control" id="email" v-model="user.email" required>
? ? ? </div>
? ? ? <div class="form-group">
? ? ? ? <label for="password">Password</label>
? ? ? ? <input type="password" class="form-control" id="password" v-model="user.password" required>
? ? ? </div>
? ? ? <div class="form-group">
? ? ? ? <label for="roles">Roles</label>
? ? ? ? <select multiple class="form-control" id="roles" v-model="user.roles">
? ? ? ? ? <option v-for="role in roles" :key="role.id" :value="role">{{ role.name }}</option>
? ? ? ? </select>
? ? ? </div>
? ? ? <button type="button" class="btn btn-primary" @click="submitForm">{{ submitButtonLabel }}</button>
? ? </form>
? </div>
</template>
<script>
import axios from 'axios';
export default {
? name: 'UserForm',
? props: {
? ? user: {
? ? ? type: Object,
? ? ? default: () => {
? ? ? ? return {
? ? ? ? ? username: '',
? ? ? ? ? email: '',
? ? ? ? ? password: '',
? ? ? ? ? roles: []
? ? ? ? };
? ? ? }
? ? },
? ? roles: {
? ? ? type: Array,
? ? ? default: () => {
? ? ? ? return [];
? ? ? }
? ? },
? ? submitButtonLabel: {
? ? ? type: String,
? ? ? default: 'Submit'
? ? },
? ? onSubmit: {
? ? ? type: Function,
? ? ? default: () => {
? ? ? ? console.log('Submit function not provided');
? ? ? }
? ? }
? },
? methods: {
? ? submitForm() {
? ? ? this.onSubmit(this.user);
? ? }
? }
}
</script>
<style scoped>
.form-group {
? margin-bottom: 1rem;
}
</style>在這個(gè)組件中,我們使用了Bootstrap的樣式來(lái)美化表單。我們從父組件中傳遞了一個(gè)user對(duì)象、roles數(shù)組和submitButtonLabel屬性,分別用于渲染表單元素和提交按鈕。同時(shí),我們使用了props屬性來(lái)聲明這些屬性。最后,我們綁定了一個(gè)submitForm方法,在點(diǎn)擊提交按鈕時(shí)將用戶信息傳遞給父組件的onSubmit方法處理。
到此這篇關(guān)于SpringBoot和Vue.js實(shí)現(xiàn)的前后端分離的用戶權(quán)限管理系統(tǒng)的文章就介紹到這了,更多相關(guān)SpringBoot Vue.js用戶權(quán)限管理系統(tǒng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 詳解springboot?springsecuroty中的注銷和權(quán)限控制問(wèn)題
- SpringBoot使用Spring Security實(shí)現(xiàn)登錄注銷功能
- SpringBoot--- SpringSecurity進(jìn)行注銷權(quán)限控制的配置方法
- Vue+springboot批量刪除功能實(shí)現(xiàn)代碼
- springboot和vue前后端交互的實(shí)現(xiàn)示例
- SpringBoot3結(jié)合Vue3實(shí)現(xiàn)用戶登錄功能
- 基于SpringBoot和Vue3的博客平臺(tái)的用戶注冊(cè)與登錄功能實(shí)現(xiàn)
- 詳解SpringBoot項(xiàng)目整合Vue做一個(gè)完整的用戶注冊(cè)功能
- Vue結(jié)合Springboot實(shí)現(xiàn)用戶列表單頁(yè)面(前后端分離)
- vue+springboot用戶注銷功能實(shí)現(xiàn)代碼
相關(guān)文章
Java 設(shè)計(jì)模式以虹貓藍(lán)兔的故事講解建造者模式
建造者模式,是一種對(duì)象構(gòu)建模式 它可以將復(fù)雜對(duì)象的建造過(guò)程抽象出來(lái),使這個(gè)抽象過(guò)程的不同實(shí)現(xiàn)方法可以構(gòu)造出不同表現(xiàn)的對(duì)象。本文將通過(guò)示例講解建造者模式,需要的可以參考一下2022-04-04
java如何讀取properties文件將參數(shù)值配置到靜態(tài)變量
這篇文章主要介紹了java如何讀取properties文件將參數(shù)值配置到靜態(tài)變量問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
Java利用反射實(shí)現(xiàn)框架類的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于Java利用反射實(shí)現(xiàn)框架類的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
詳解Springboot之整合JDBCTemplate配置多數(shù)據(jù)源
這篇文章主要介紹了詳解Springboot之整合JDBCTemplate配置多數(shù)據(jù)源,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好的幫助,需要的朋友可以參考下2021-04-04
kafka內(nèi)外網(wǎng)訪問(wèn)配置方式
這篇文章主要介紹了kafka內(nèi)外網(wǎng)訪問(wèn)配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
Simple Java Mail郵件發(fā)送實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了Simple Java Mail郵件發(fā)送實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
解決@PathVariable出現(xiàn)點(diǎn)號(hào).時(shí)導(dǎo)致路徑參數(shù)截?cái)喃@取不全的問(wèn)題
這篇文章主要介紹了解決@PathVariable出現(xiàn)點(diǎn)號(hào).時(shí)導(dǎo)致路徑參數(shù)截?cái)喃@取不全的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
對(duì)SpringBoot項(xiàng)目Jar包進(jìn)行加密防止反編譯
最近項(xiàng)目要求部署到其他公司的服務(wù)器上,但是又不想將源碼泄露出去,要求對(duì)正式環(huán)境的啟動(dòng)包進(jìn)行安全性處理,防止客戶直接通過(guò)反編譯工具將代碼反編譯出來(lái),本文介紹了如何對(duì)SpringBoot項(xiàng)目Jar包進(jìn)行加密防止反編譯,需要的朋友可以參考下2023-10-10
你知道在Java中Integer和int的這些區(qū)別嗎?
最近面試,突然被問(wèn)道,說(shuō)一下Integer和int的區(qū)別.額…可能平時(shí)就知道寫(xiě)一些業(yè)務(wù)代碼,包括面試的一些Spring源碼等,對(duì)于這種特別基礎(chǔ)的反而忽略了,導(dǎo)致面試的時(shí)候突然被問(wèn)到反而不知道怎么回答了.哎,還是乖乖再看看底層基礎(chǔ),順帶記錄一下把 ,需要的朋友可以參考下2021-06-06

