SSM-Vue 前后端分离练习

SSM-Vue 前后端分离练习

刚学完Vue,就在网上找了个Demo,功能只有简单的增删改查,但是可以练一下Vue和前后端分离。

用到的技术和开发工具

前端

  • 开发工具:IDEA
  • 开发框架:Vue + axios + elementUI
  • 包管理工具: npm
  • 打包工具:webpack

后端

  • 开发工具:IDEA
  • 开发框架:SpringMVC + Spring + Mybatis
  • 包管理工具:maven
  • 数据库: MySQL

需求及功能

  • 增删改查(CRUD)
  • 分页
  • 批量删除
  • 前后端分离

数据库环境搭建

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `user_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `card_type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `card_no` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `user_sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `user_age` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `user_role` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

INSERT INTO `user` VALUES ('15968162087363060', '身份证', '4264465547656467', '过突然', '男', '30', '办事人员和有关人员');
INSERT INTO `user` VALUES ('15968162346981977', '护照', '432532654364654', '规划图', '男', '29', '不便分类的其他从业人员');
INSERT INTO `user` VALUES ('15968162893439470', '身份证', '4354324534532', '具体办1', '男', '31', '农、林、牧、渔、水利业生产人员');
INSERT INTO `user` VALUES ('15968163245457143', '身份证', '43564546576687', '回各家', '男', '34', '未知');
INSERT INTO `user` VALUES ('15968163514764733', '军官证', '7657868', '缺口v4', '女', '23', '不便分类的其他从业人员');
INSERT INTO `user` VALUES ('15968165113694372', '台湾往来大陆通行证', '343214321412433214', '遗体ioy', '女', '48', '生产、运输设备操作人员及有关人员');
INSERT INTO `user` VALUES ('15968165371931786', '港澳居民通行证', '65765887989090909', '垂直发射的', '女', '35', '不便分类的其他从业人员');
INSERT INTO `user` VALUES ('15968941217553030', '身份证', '34354657665768768', '撒撒到', '男', '22', '军人');
INSERT INTO `user` VALUES ('15968943937844616', '身份证', '4454534436565756', '出手大', '女', '31', '不便分类的其他从业人员');
INSERT INTO `user` VALUES ('15968944123869023', '护照', '43225465457657', 'VCD法国', '女', '39', '农、林、牧、渔、水利业生产人员');
INSERT INTO `user` VALUES ('15968953962316864', '身份证', '342354325', '房东是个大帅哥', '女', '33', '商业、服务业人员');
INSERT INTO `user` VALUES ('15968954638794962', '身份证', '343343554654', '撒撒旦', '女', '29', '生产、运输设备操作人员及有关人员');

SET FOREIGN_KEY_CHECKS = 1;

后台开发环境搭建

创建一个maven项目ssm_project,增加web支持,导入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>ssm</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.12</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.1.1</version>
            <scope>provided</scope>
        </dependency>
        <!--实现slf4j接口并整合-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.1</version>
            <scope>provided</scope>
        </dependency>

        <!--Junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!--druid==>阿里巴巴数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.25</version>
        </dependency>

        <!--Servlet - JSP -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!--json-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.3</version>
        </dependency>

        <!--Mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.2</version>
        </dependency>

        <!--Spring核心-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.10.RELEASE</version>
        </dependency>
        <!--Spring单元测试-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.14.RELEASE</version>
        </dependency>

        <!--Aop要导入的包-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
        </dependency>
    </dependencies>

    <!--2.maven静态资源过滤-->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>

</project>

配置文件:
mybatis配置文件mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
        <!-- 开启二级缓存 -->
        <setting name="cacheEnabled" value="true"/>
        <!-- 标准日志 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!--开启驼峰命名规则自动转换-->
        <setting name="mapUnderscoreToCamelCase" value="true" />
    </settings>

    <!--别名-->
    <typeAliases>
        <package name="com.kuang.pojo"/>
    </typeAliases>

</configuration>

spring配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       https://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">

    <!--spring-dao-->
    <!--1.关联数据库文件-->
    <context:property-placeholder location="classpath:database.properties"/>

    <!--2.配置数据源-->
    <!--数据库连接池 druid-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--3.配置SqlsessionFactory对象-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置Mybatis全局配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--配置映射文件-->
        <property name="mapperLocations" value="classpath:com/kuang/dao/*.xml"/>
    </bean>

    <!--4.配置扫描Dao接口包,动态实现Dao接口注入到Spring容器中-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入sqlSessionFactory,可省?一套dataSource可省,多套不可省!-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--给出需要扫描的Dao接口包-->
        <property name="basePackage" value="com.kuang.dao"/>
    </bean>

    <!--spring-service-->
    <!--1.扫描service层的注解-->
    <context:component-scan base-package="com.kuang.service"/>

    <!--声明式事务-->
    <!--2.配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:advice id="txManager" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="query*" read-only="true"/>
            <tx:method name="search*" read-only="true"/>
            <tx:method name="select*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*"  isolation="DEFAULT" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <!--配置aop织入事务-->
        <aop:pointcut id="pointcut" expression="execution(* com.kuang.dao.*.*(..))"/>
        <aop:advisor advice-ref="txManager" pointcut-ref="pointcut"/>
    </aop:config>

    <import resource="applicationContext-mvc.xml"/>
</beans>

database.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm_vue?useSSL=true&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456

springmvc配置文件applicationContext-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context.xsd
   http://www.springframework.org/schema/mvc
   https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--1.开启SpringMVC注解驱动-->
    <mvc:annotation-driven/>

    <!--2.静态资源过滤-->
    <mvc:default-servlet-handler/>

    <!--3.配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--4.扫描controller层的注解-->
    <context:component-scan base-package="com.kuang.controller"/>

</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--配置DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--配置字符编码过滤器-->
    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--Session过期时间-->
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>

</web-app>

代码编写:
实体类User.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    
    
    private String userId;//用户id
    private String cardType;//证件类型
    private String cardNo;//证件号码
    private String userName;//用户姓名
    private String userSex;//用户性别
    private String userAge;//用户年龄
    private String userRole;//用户角色
}

UserMapper接口

public interface UserMapper {
    
    

    /**
     * 分页查询 User
     * @param startRows 起始页
     * @return List<User>
     */
    List<User> queryUserPage(int startRows);

    /**
     * 分页查询 User 带条件
     * @param userName
     * @param userSex
     * @param startRows
     * @return
     */
    List<User> selectUserPage(@Param("userName")String userName, @Param("userSex")String userSex, @Param("startRows")int startRows);

    /**
     * 查询 User 个数
     * @param userName
     * @param userSex
     * @return
     */
    int getRowCount(@Param("userName")String userName, @Param("userSex")String userSex);

    /**
     * 添加 User
     * @param user
     * @return 返回码
     */
    int createUser(User user);

    /**
     * 根据 userId 删除用户
     * @return 返回码
     */
    int deleteUserById(String userId);

    /**
     * 根据 userId 批量删除用户
     * @param userIds
     * @return
     */
    int deleteUserByIdList(@Param("list") List userIds);

    /**
     * 根据 userId 更新用户
     * @return 返回码
     */
    int updateUserById(User user);

}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.dao.UserMapper">

	<!--二级缓存-->
    <cache/>

    <sql id="Base_Column_List" >
        user_id, card_type, card_no, user_name, user_sex, user_age, user_role
    </sql>

    <select id="queryUserPage" parameterType="int" resultType="User">
        select
            <include refid="Base_Column_List"/>
        from user
            limit #{startRows,jdbcType=INTEGER},5;
    </select>
    
    
    <select id="selectUserPage" resultType="user">
        select
            <include refid="Base_Column_List"/>
        from user
        <where>
            <if test="userName != null and userName != ''">
                user_name like #{userName}
            </if>
            <if test="userSex != null and userSex != ''">
                and user_sex =#{userSex}
            </if>
        </where>
        order by user_id  desc
        limit #{startRows},5;
    </select>

    <select id="getRowCount" resultType="int">
        select count(*) from user
        <where>
            <if test="userName !=null and userName != ''">
                user_name like concat('%',#{userName},'%')
            </if>
            <if test="userSex != null and userSex != ''">
                and user_sex =#{userSex}
            </if>
        </where>
    </select>

    <insert id="createUser" parameterType="user">
        insert into user(user_id, card_type, card_no, user_name, user_sex, user_age, user_role)
        values (#{userId}, #{cardType}, #{cardNo}, #{userName}, #{userSex}, #{userAge}, #{userRole});
    </insert>

    <delete id="deleteUserById" parameterType="java.lang.String">
        delete from user where user_id = #{userId};
    </delete>

    <delete id="deleteUserByIdList" parameterType="java.util.List">
        delete from user
        <where>
            <foreach collection="list" item="userID" open="(" close=")" separator="or">
            user_id = #{userID}
            </foreach>
        </where>
    </delete>
    
    <update id="updateUserById" parameterType="user">
        update user
        <set>
            <if test="cardNo != null" >
                card_no = #{cardNo,jdbcType=VARCHAR},
            </if>
            <if test="cardType != null" >
                card_type = #{cardType,jdbcType=VARCHAR},
            </if>
            <if test="userName != null" >
                user_name = #{userName,jdbcType=VARCHAR},
            </if>
            <if test="userSex != null" >
                user_sex = #{userSex,jdbcType=VARCHAR},
            </if>
            <if test="userAge != null" >
                user_age = #{userAge,jdbcType=VARCHAR},
            </if>
            <if test="userRole != null" >
                user_role = #{userRole,jdbcType=VARCHAR}
            </if>
        </set>
        where 1 = 1
        and user_id = #{userId,jdbcType=VARCHAR}
    </update>

</mapper>

UserService接口

public interface UserService {
    
    
    /**
     * 分页查询 User
     * @param startRows 起始页
     * @return List<User>
     */
    List<User> queryUserPage(int startRows);

    /**
     * 分页查询 User 带条件
     * @param userName
     * @param userSex
     * @param startRows
     * @return
     */
    List<User> selectUserPage(String userName, String userSex, int startRows);

    /**
     * 查询 User 个数
     * @param userName
     * @param userSex
     * @return
     */
    int getRowCount(String userName, String userSex);

    /**
     * 添加 User
     * @param user
     * @return 返回码
     */
    int createUser(User user);

    /**
     * 根据 userId 删除用户
     * @return 返回码
     */
    int deleteUserById(String userId);

    /**
     * 根据 userId 批量删除用户
     * @param userIds
     * @return
     */
    int deleteUserByIdList(List userIds);

    /**
     * 根据 userId 更新用户
     * @return 返回码
     */
    int updateUserById(User user);
}

UserServiceImpl.java

@Service
public class UserServiceImpl implements UserService{
    
    

    @Autowired
    private UserMapper userMapper;


    public List<User> queryUserPage(int startRows) {
    
    
        return userMapper.queryUserPage(startRows);
    }

    public List<User> selectUserPage(String userName, String userSex, int startRows) {
    
    
        if (userName!=null && userName !=""){
    
    
            userName = "%" + userName +"%";
        }
        return userMapper.selectUserPage(userName,userSex,startRows);
    }

    public int getRowCount(String userName, String userSex) {
    
    
        return userMapper.getRowCount(userName,userSex);
    }

    public int createUser(User user) {
    
    
        return userMapper.createUser(user);
    }

    public int deleteUserById(String userId) {
    
    
        return userMapper.deleteUserById(userId);
    }

    public int deleteUserByIdList(List userIds) {
    
    
        return userMapper.deleteUserByIdList(userIds);
    }

    public int updateUserById(User user) {
    
    
        return userMapper.updateUserById(user);
    }
}

UserController.java

@RestController
@RequestMapping("/user")
public class UserController {
    
    

    @Autowired
    @Qualifier("userServiceImpl")
    private UserService userServiceImpl;

    /**
     * 分页查询所有用户
     * @param page 页码
     * @return
     */
    @RequestMapping("/queryUserPage")
    public List<User> queryUserPage(Integer page){
    
    
        int pageNow = page == null ? 1 :page;
        int pageSize = 5;
        int startRows = (pageNow-1)*pageSize;
        List<User> userList = userServiceImpl.queryUserPage(startRows);
        System.out.println(userList);
        return userList;
    }

    /**
     * 根据条件分页查用户
     * @param userName 用户名
     * @param userSex 用户性别
     * @param page 页码
     * @return
     */
    @RequestMapping("/selectUserPage")
    public List<User> selectUserPage(String userName, String userSex, Integer page){
    
    
        int pageNow = page == null ? 1 :page;
        int pageSize = 5;
        int startRows = (pageNow-1)*pageSize;
        List<User> userList = userServiceImpl.selectUserPage(userName, userSex, startRows);
        System.out.println(userList);
        return  userList;
    }

    /**
     * 查询 User 个数
     * @param userName 用户名
     * @param userSex 性别
     * @return
     */
    @RequestMapping("/getRowCount")
    public int getRowCount(String userName, String userSex){
    
    
        int total = userServiceImpl.getRowCount(userName, userSex);
        System.out.println(total);
        return total;
    }

    /**
     * 添加 User
     * @param user 一个用户信息
     * @return 返回码
     */
    @RequestMapping("/createUser")
    public int createUser(User user){
    
    
        Random random = new Random();
        Integer number = random.nextInt(9000) + 1000;
        user.setUserId(System.currentTimeMillis() + String.valueOf(number));
        return userServiceImpl.createUser(user);
    }

    /**
     * 根据 userId 删除用户
     * @return 返回码
     */
    @RequestMapping("/deleteUserById")
    public int deleteUserById(String userId){
    
    
        return userServiceImpl.deleteUserById(userId);
    }

    /**
     * 根据 userId 批量删除用户
     * @param userIdList userId列表
     * @return
     */
    @RequestMapping("/deleteUserByIdList")
    public int deleteUserByIdList(String userIdList){
    
    
        String userIdListSub = userIdList.substring(0, userIdList.length()-1);

        List userIds = new ArrayList();
        for (String userIdStr: userIdListSub.split(",")){
    
    
            userIds.add(userIdStr.trim());
        }
        return userServiceImpl.deleteUserByIdList(userIds);
    }

    /**
     * 根据 userId 更新用户
     * @return 返回码
     */
    @RequestMapping("/updateUserById")
    public int updateUserById(User user){
    
    
        return userServiceImpl.updateUserById(user);
    }
}

项目结构图:
在这里插入图片描述
问题:Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/exc/InvalidDefinitionException
解决:jackson-databind版本太低,提升版本–>2.9.3

前台开发环境搭建

cd D:\Program Files\JetBrains\workspace\ssm-vue

vue init webpack vue_project

cd vue_project

npm i element-ui -S

npm install

cnpm install --save vue-axios

cnpm install sass-loader node-sass --save-dev

npm run dev

浏览器中能打开证明环境搭建完成。
main.js

import Vue from 'vue';
import App from './App';
import router from './router';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import qs from 'qs';
import axios from "axios";


Vue.config.productionTip = false;
Vue.use(ElementUI);
Vue.prototype.axios = axios;
Vue.prototype.qs = qs;

/* eslint-disable no-new */
new Vue({
    
    
  el: '#app',
  router,
  components: {
    
     App },
  template: '<App/>'
})

App.vue

<template>
  <div id="app">
    <el-row type="flex" justify="center">
      <el-col :xs="24" :sm="22" :md="20" :lg="20" :xl="18">
        <router-view/>
      </el-col>
    </el-row>
  </div>
</template>

<script>
export default {
     
     
  name: 'App'
}
</script>

<style>
#app {
     
     
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.el-table th.gutter {
     
     
  display: table-cell !important;
}
</style>

/router/index.js

import Router from 'vue-router';
import HelloWorld from '@/components/HelloWorld'
import UserHome from '@/components/UserHome'
import Vue from 'vue'
Vue.use(Router)

export default new Router({
    
    
  routes: [
    {
    
    
      path: '/HelloWorld',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
    
    
      path: '/',
      name: 'UserHome',
      component: UserHome
    }
  ]
})

UserHome.vue
element-ui官方文档:https://element.eleme.cn/#/zh-CN/component/installation

<template>
  <div>
    <el-form :inline="true" :model="formInline" class="demo-form-inline">
      <el-form-item>
        <el-input v-model="formInline.search1" size="mini" placeholder="输入姓名查询" v-on:input="handleSearch()">
        </el-input>
      </el-form-item>
      <el-form-item>
        <el-select size="mini" v-model="formInline.search2" v-on:change="handleSearch()">
          <el-option label="请选择性别" value=""></el-option>
          <el-option label="" value=""></el-option>
          <el-option label="" value=""></el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button icon="el-icon-circle-plus-outline" type="text" @click="dialogAdd = true">添加</el-button>
      </el-form-item>
      <el-form-item>
        <el-button icon="el-icon-delete" type="text" @click="handleDeleteList()">删除</el-button>
      </el-form-item>
    </el-form>

    <el-table
      ref="multipleTable"
      :data="tableData"
      border
      highlight-current-row
      style="width: 100%"
      @selection-change="handleSelectionDelete">
      <el-table-column type="selection" width="55"></el-table-column>
      <el-table-column label="用户编号">
        <template slot-scope="scope">
          <span>{
   
   { scope.row.userId }}</span>
        </template>
      </el-table-column>
      <el-table-column label="证件类型" prop="cardType"></el-table-column>
      <el-table-column label="证件号码" prop="cardNo"></el-table-column>
      <el-table-column label="用户姓名">
        <template slot-scope="scope">
          <el-popover trigger="hover" placement="right">
            <p>证件类型: {
   
   { scope.row.cardType }}</p>
            <p>证件号码: {
   
   { scope.row.cardNo }}</p>
            <p>用户姓名:{
   
   { scope.row.userName }}</p>
            <p>用户性别: {
   
   { scope.row.userSex }}</p>
            <p>用户年龄: {
   
   { scope.row.userAge }}</p>
            <p>用户角色:{
   
   { scope.row.userRole }}</p>
            <div slot="reference" class="name-wrapper">
              <el-button type="text">{
   
   { scope.row.userName }}</el-button>
            </div>
          </el-popover>
        </template>
      </el-table-column>
      <el-table-column label="用户性别" prop="userSex"></el-table-column>
      <el-table-column label="用户年龄" prop="userAge"></el-table-column>
      <el-table-column label="用户角色" prop="userRole"></el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button type="text" icon="el-icon-edit" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
          <el-button type="text" icon="el-icon-delete" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>


    <el-dialog title="添加" :append-to-body='true' :visible.sync="dialogAdd" :before-close="handleClose">
      <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="80px" class="demo-ruleForm" size="medium">
        <el-form-item label="证件类型">
          <el-select v-model="ruleForm.cardType" placeholder="请选择证件类型" prop="cardType">
            <el-option label="身份证" value="身份证"></el-option>
            <el-option label="军官证" value="军官证"></el-option>
            <el-option label="护照" value="护照"></el-option>
            <el-option label="港澳居民通行证" value="港澳居民通行证"></el-option>
            <el-option label="台湾往来大陆通行证" value="台湾往来大陆通行证"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="证件号码">
          <el-input v-model="ruleForm.cardNo"></el-input>
        </el-form-item>
        <el-form-item label="用户姓名">
          <el-input v-model="ruleForm.userName"></el-input>
        </el-form-item>
        <el-form-item label="用户性别">
          <el-radio-group v-model="ruleForm.userSex">
            <el-radio label=""></el-radio>
            <el-radio label=""></el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="用户年龄">
          <el-slider v-model="ruleForm.userAge" show-input></el-slider>
        </el-form-item>
        <el-form-item label="用户角色">
          <el-select v-model="ruleForm.userRole" placeholder="请选择用户角色" prop="userRole">
            <el-option label="国家机关、党群组织、企业、事业单位负责人" value="国家机关、党群组织、企业、事业单位负责人"></el-option>
            <el-option label="专业技术人员" value="专业技术人员"></el-option>
            <el-option label="办事人员和有关人员" value="办事人员和有关人员"></el-option>
            <el-option label="商业、服务业人员" value="商业、服务业人员"></el-option>
            <el-option label="农、林、牧、渔、水利业生产人员" value="农、林、牧、渔、水利业生产人员"></el-option>
            <el-option label="生产、运输设备操作人员及有关人员" value="生产、运输设备操作人员及有关人员"></el-option>
            <el-option label="军人" value="军人"></el-option>
            <el-option label="不便分类的其他从业人员" value="不便分类的其他从业人员"></el-option>
            <el-option label="未知" value="未知"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
        <span slot="footer" class="dialog-footer">
			        <el-button @click="emptyUserData()" size="medium">取 消</el-button>
			        <el-button @click="addUser('ruleForm')" type="primary" size="medium">确 定</el-button>
		    </span>
    </el-dialog>

    <el-dialog title="编辑" :append-to-body='true' :visible.sync="dialogUpdate" :before-close="handleClose">
      <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="70px" class="demo-ruleForm" size="medium">
        <el-form-item label="证件类型">
          <el-select v-model="ruleForm.cardType" placeholder="请选择证件类型" prop="cardType">
            <el-option label="身份证" value="身份证"></el-option>
            <el-option label="军官证" value="军官证"></el-option>
            <el-option label="护照" value="护照"></el-option>
            <el-option label="港澳居民通行证" value="港澳居民通行证"></el-option>
            <el-option label="台湾往来大陆通行证" value="台湾往来大陆通行证"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="证件号码">
          <el-input v-model="ruleForm.cardNo"></el-input>
        </el-form-item>
        <el-form-item label="用户姓名">
          <el-input v-model="ruleForm.userName"></el-input>
        </el-form-item>
        <el-form-item label="用户性别">
          <el-radio-group v-model="ruleForm.userSex">
            <el-radio label=""></el-radio>
            <el-radio label=""></el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="用户年龄">
          <el-slider v-model="ruleForm.userAge" show-input></el-slider>
        </el-form-item>
        <el-form-item label="用户角色">
          <el-select v-model="ruleForm.userRole" placeholder="请选择用户角色" prop="userRole">
            <el-option label="国家机关、党群组织、企业、事业单位负责人" value="国家机关、党群组织、企业、事业单位负责人"></el-option>
            <el-option label="专业技术人员" value="专业技术人员"></el-option>
            <el-option label="办事人员和有关人员" value="办事人员和有关人员"></el-option>
            <el-option label="商业、服务业人员" value="商业、服务业人员"></el-option>
            <el-option label="农、林、牧、渔、水利业生产人员" value="农、林、牧、渔、水利业生产人员"></el-option>
            <el-option label="生产、运输设备操作人员及有关人员" value="生产、运输设备操作人员及有关人员"></el-option>
            <el-option label="军人" value="军人"></el-option>
            <el-option label="不便分类的其他从业人员" value="不便分类的其他从业人员"></el-option>
            <el-option label="未知" value="未知"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
        <span slot="footer" class="dialog-footer">
	            	<el-button @click="emptyUserData()" size="medium">取 消</el-button>
	            	<el-button @click="updateUser()" type="primary" size="medium">确 定</el-button>
	      </span>
    </el-dialog>

    <br>

    <el-pagination
      background
      :disabled="disablePage"
      :current-page.sync="currentPage"
      small
      layout="prev, pager, next"
      :page-size="pageSize"
      :total="total"
      @current-change="handlePageChange">
    </el-pagination>
  </div>
</template>

<script>
export default {
     
     
  data() {
     
     
    return {
     
     
      ruleForm: {
     
     
        userId: null,//用户id
        cardType: null,//证件类型
        cardNo: null,//证件号码
        userName: null,//用户姓名
        userSex: null,//用户性别
        userAge: 25,//用户年龄
        userRole: null//用户角色
      },
      rules: {
     
     },
      tableData: [],
      formInline:{
     
     
        search1: '',
        search2: ''
      },
      dialogAdd: false,
      dialogUpdate: false,
      pageSize: 5,
      currentPage: 1,
      total: 0,
      disablePage: false,
      multipleSelection: []
    };
  },

  created() {
     
     
    this.handlePageChange();
    this.getRowCount();
  },

  methods: {
     
     
    /**
     * 分页
     */
    handlePageChange() {
     
     
      let postData=this.qs.stringify({
     
     
        page:this.currentPage,
        userName:this.formInline.search1,
        userSex:this.formInline.search2
      });
      this.axios({
     
     
        method:'post',
        url:'/user/selectUserPage',
        data:postData
      }).then(response=>{
     
     
        this.tableData=response.data;
      }).catch(error=>{
     
     
        console.log(error);
      })
    },

    /**
     * 统计用户个数
     */
    getRowCount() {
     
     
      let postData=this.qs.stringify({
     
     
        userName:this.formInline.search1,
        userSex:this.formInline.search2
      });
      this.axios({
     
     
        method:'post',
        url:'/user/getRowCount',
        data:postData
      }).then(response=>{
     
     
        this.total=response.data;
      }).catch(error=>{
     
     
        console.log(error);
      })
    },

    /**
     * 添加用户
     */
    addUser() {
     
     
      if (this.ruleForm.cardType == null || this.ruleForm.cardNo == null || this.ruleForm.userName == null || this.ruleForm.userSex == null || this.ruleForm.userRole == null) {
     
     
        this.$alert('用户信息不完整请检查', '温馨提示', {
     
     
          confirmButtonText: '确定'
        });
        return;
      }
      let postData = this.qs.stringify({
     
     
        cardType: this.ruleForm.cardType,//证件类型
        cardNo: this.ruleForm.cardNo,//证件号码
        userName: this.ruleForm.userName,//用户姓名
        userSex: this.ruleForm.userSex,//用户性别
        userAge: this.ruleForm.userAge,//用户年龄
        userRole: this.ruleForm.userRole,//用户角色
      });
      this.axios({
     
     
        method:'post',
        url:'/user/createUser',
        data:postData
      }).then(response=>{
     
     
        this.handlePageChange();
        this.getRowCount();
        this.$message({
     
     
          type: 'success',
          message: '已添加!'
        });
        this.emptyUserData();
      }).catch(error=>{
     
     
        console.log(error);
      })
    },

    handleSearch() {
     
     
      this.handlePageChange();
      this.getRowCount();
    },

    handleEdit(index, row) {
     
     
      this.dialogUpdate = true;
      row.userAge = Number(row.userAge);
      this.ruleForm = Object.assign({
     
     }, row, index); //这句是关键!!!
    },

    handleClose(done) {
     
     
      this.$confirm('确认关闭?')
        .then(_ => {
     
     
          done();
          this.emptyUserData();
        })
        .catch(_ => {
     
     
        });
    },

    /**
     * 清空绑定数据
     */
    emptyUserData() {
     
     
      this.dialogAdd = false;
      this.dialogUpdate = false;
      this.ruleForm = {
     
     
        userId: null,//用户id
        cardType: null,//证件类型
        cardNo: null,//证件号码
        userName: null,//用户姓名
        userSex: null,//用户性别
        userAge: 25,//用户年龄
        userRole: null//用户角色
      };
    },

    /**
     * 根据 userId 删除用户
     * @param index
     * @param row
     */
    handleDelete(index, row) {
     
     
      //console.log(index, row);
      this.$confirm('删除操作, 是否继续?', '提示', {
     
     
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
     
     
        let postData = this.qs.stringify({
     
     
          userId: row.userId,
        });
        this.axios({
     
     
          method: 'post',
          url: '/user/deleteUserById',
          data: postData
        }).then(response => {
     
     
          this.getRowCount();
          if (this.total % 5 == 1 && this.currentPage >= 1) {
     
     
            if (this.total / 5 < this.currentPage) {
     
     
              this.currentPage = this.currentPage - 1;
            }
          }
          this.handlePageChange();

          this.$message({
     
     
            type: 'success',
            message: '删除成功!'
          });
          //console.log(response);
        }).catch(error => {
     
     
          console.log(error);
        });

      }).catch(() => {
     
     
        this.$message({
     
     
          type: 'info',
          message: '已取消删除'
        });
      });
    },

    handleSelectionDelete(val) {
     
     
      this.multipleSelection = val;
    },

    /**
     * 根据 userId 批量删除用户
     */
    handleDeleteList() {
     
     
      let userIds = "";
      this.multipleSelection.forEach(item => {
     
     
        userIds += item.userId + ',';
      })
      console.log(userIds);
      // let userIds= this.multipleSelection.map(item => item.userId).join()

      this.$confirm('删除操作, 是否继续?', '提示', {
     
     
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
     
     
        let postData = this.qs.stringify({
     
     
          userIdList: userIds
        });
        console.log(postData);
        this.axios({
     
     
          method: 'post',
          url: '/user/deleteUserByIdList',
          data: postData
        }).then(response => {
     
     
          this.getRowCount();
          if (this.total % 5 == 1 && this.currentPage >= 1) {
     
     
            if (this.total / 5 < this.currentPage) {
     
     
              this.currentPage = this.currentPage - 1;
            }
          }
          this.handlePageChange();

          this.$message({
     
     
            type: 'success',
            message: '删除成功!'
          });
          //console.log(response);
        }).catch(error => {
     
     
          console.log(error);
        });

      }).catch(() => {
     
     
        this.$message({
     
     
          type: 'info',
          message: '已取消删除'
        });
      });
    },


    updateUser() {
     
     
      if (this.ruleForm.cardType == null || this.ruleForm.cardNo == null || this.ruleForm.userName == null || this.ruleForm.userSex == null || this.ruleForm.userRole == null) {
     
     
        this.$alert('用户信息不完整请检查', '温馨提示', {
     
     
          confirmButtonText: '确定'
        });
        return;
      }
      let postData = this.qs.stringify({
     
     
        userId: this.ruleForm.userId,//用户 Id
        cardType: this.ruleForm.cardType,//证件类型
        cardNo: this.ruleForm.cardNo,//证件号码
        userName: this.ruleForm.userName,//用户姓名
        userSex: this.ruleForm.userSex,//用户性别
        userAge: this.ruleForm.userAge,//用户年龄
        userRole: this.ruleForm.userRole,//用户角色
      });
      this.axios({
     
     
        method: 'post',
        url: '/user/updateUserById',
        data: postData
      }).then(response => {
     
     
        this.handlePageChange();
        this.getRowCount();
        this.$message({
     
     
          type: 'success',
          message: '已编辑!'
        });
        this.emptyUserData();
        //console.log(response);
      }).catch(error => {
     
     
        console.log(error);
      });
    }
  },

}
</script>
<style scoped>
</style>

/config/index.js
配置跨域访问

'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.

const path = require('path')

module.exports = {
    
    
  dev: {
    
    

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
    
    
      '/': {
    
    
        target: 'http://localhost:8080',
        changeOrigin: true,//允许跨域
        pathRewrite: {
    
    
          '^/': '/'
        }
      },
      '/ws/*': {
    
    
        target: 'ws://127.0.0.1:8080',
        ws: true
      }
    },

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 8082, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    autoOpenBrowser: false,
    errorOverlay: true,
    notifyOnErrors: true,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-

    // Use Eslint Loader?
    // If true, your code will be linted during bundling and
    // linting errors and warnings will be shown in the console.
    useEslint: true,
    // If true, eslint errors and warnings will also be shown in the error overlay
    // in the browser.
    showEslintErrorsInOverlay: false,

    /**
     * Source Maps
     */

    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-module-eval-source-map',

    // If you have problems debugging vue-files in devtools,
    // set this to false - it *may* help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true,

    cssSourceMap: true
  },

  build: {
    
    
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',

    /**
     * Source Maps
     */

    productionSourceMap: true,
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map',

    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],

    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  }
}

项目结构图
在这里插入图片描述
效果图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总结:
后端

  • 包的版本容易引发错误
  • 复习了SSM的整合,练习了简答的增删改查

前端

  • element-ui不熟,看官方文档大致知道是什么意思,需要多写
  • vue学完缺乏系统,发蒙
  • 学会了跨域请求

在原文基础上进行了优化。
原文参考: https://blog.csdn.net/jianyuwuyi/article/details/107924066.

猜你喜欢

转载自blog.csdn.net/qq_42665745/article/details/114239191