同系列文章导读:【JavaWEB】文章导读

所有文章均在本博客首发,其他平台同步更新

如有问题,欢迎指正(评论区留言即可)

发表评论时请填写正确邮箱,以便于接收通知【推荐QQ邮箱】


Vue快速入门

  • Vue是一套构建用户界面的渐进式前端框架
  • 只关注视图层,并且非常容易学习,还可以很方便的与其他库或已有项目整合
  • 通过尽可能简单的API来实现响应数据的绑定和组合的视图组件

特点

  1. 易用:在有HTML CSS JavaScript 的基础上,快速上手
  2. 灵活:简单小巧的核心,渐进式技术栈,足以应付任何规模的应用
  3. 性能:20kb min + gzip 运行大小、超快虚拟DOM、最省心的优化

快速入门

  1. 下载和引入 vue.js 文件:https://cn.vuejs.org/
  2. 编写入门程序

    视图:负责页面渲染,主要由 HTML + CSS 构成

    脚本:负责业务数据模型(Model)以及数据的处理逻辑

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>快速入门</title>
</head>

<body>
    <!-- 视图 -->
    <div id="div">
        <!-- 通过双大括号将变量的值绑定,值从脚本部分获取 -->
        {{msg}}
    </div>
</body>
<script src="../js/vue.js"></script>
<script>
    // 脚本部分
    new Vue({
        el: "#div", // 将获取到的元素赋值给el
        data: { // 操作数据
            msg: "Hello Vue"
        }
    });
</script>

</html>

详解快速入门

  • Vue核心对象:每一个Vue程序都是从一个Vue核心对象开始的

    let vm = new Vue({
       选项列表; 
    });
  • 选项列表

    el 选项:用于接收获取到页面中的元素(根据常用选择器获取)

    data 选项:用于保存当前 Vue 对象中的数据。在视图中声明的变量需要在此处赋值

    methods 选项:用于定义方法。方法可以直接通过对象名调用,this代表当前Vue 对象

  • 数据绑定

    在视图部分可以获取脚本部分的数据

    获取方法:{{变量名}}

    这里需要使用双大括号
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>快速入门升级</title>
</head>

<body>
    <!-- 视图 -->
    <div id="div">
        <div>姓名:{{name}}</div>
        <div>班级:{{classRoom}}</div>
        <button onclick="hi()">打招呼</button>
        <button onclick="update()">修改班级</button>
    </div>
</body>
<script src="../js/vue.js"></script>
<script>
    // 脚本
    let vm = new Vue({
        el: "#div",
        data: {
            name: "张三",
            classRoom: "一班"
        },
        methods: {
            study() {
                alert(this.name + "正在" + this.classRoom + "好好学习");
            }
        }
    });

    // 定义打招呼方法
    function hi() {
        vm.study();
    }
    // 修改班级
    function update() {
        vm.classRoom = "二班";
    }
</script>

</html>

备注: 在创建Vue对象后,需要通过el获取到视图中的根标签,才能成功为根标签中的变量赋值


Vue常用指令

  • 指令:是带有 v- 前缀的特殊属性,不同指令具有不同含义。例如:v-html, v-if,v-for
  • 使用指令时,通常编写在标签的属性上,值可以使用JS 的表达式

常用指令

指令作用
v-html把文本解析为HTML代码
v-bind为HTML标签绑定属性值
v-if条件性的渲染某元素,判定为true时渲染,否则不渲染
v-else条件性的渲染某元素,判定为true时渲染,否则不渲染
v-else-if条件性的渲染某元素,判定为true时渲染,否则不渲染
v-show根据条件展示某元素,和if-else区别在于切换的是display 属性的值
v-for列表渲染,遍历容器的元素或者对象的属性
v-on为HTML标签绑定事件
v-model在表单元素上创建双向数据绑定

文本插值

  • v-html:把文本解析问HTML代码(既可以有普通的文本,还可以有相应的标签
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文本插值</title>
</head>

<body>
    <!-- 视图入口 -->
    <div id="div">
        <div>{{msg}}</div>
        <!-- 通过指令获取内容(解析标签) -->
        <div v-html="msg"></div>
    </div>

</body>
<script src="../../js/vue.js"></script>
<script>
    // 脚本
    new Vue({
        el: "#div",
        data: {
            msg: "<b>Hello Vue</b>" // 无法解析标签
        }
    });
</script>

</html>

绑定属性

  • v-bind:为HTML标签绑定对应的属性(可以省略,但是需要有:

    格式:v-bind:属性名=属性值属性值可以从脚本中获取

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>绑定属性</title>
    <style>
        .test {
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>

<body>
    <!-- 视图入口 -->
    <div id="div">
        <!-- 通过指令为a添加href属性 -->
        <a v-bind:href="url">Hello Code.</a>
        <br>
        <!-- 简写格式 -->
        <a :href="url">Hello Code.</a>
        <br>
        <!-- 为标签添加样式 -->
        <div :class="cls"></div>
    </div>
</body>
<script src="../../js/vue.js"></script>
<script>
    // 脚本
    new Vue({
        el: "#div", // 获取视图入口
        data: { // 为视图中相应的变量赋值
            url: "https://www.hellocode.top",
            cls: "test"
        }
    });
</script>

</html>

条件渲染

  • v-if:条件性的渲染某元素,判定为真时渲染,否则不渲染
  • v-else:条件性的渲染
  • v-else-if:条件性的渲染
  • v-show:根据条件展示某元素,区别在于切换的是display 属性的值

备注

  • 前三类if-else-if都是和Java中一样的
  • v-show是使用display属性的值来实现元素的渲染控制
  • 使用v-show隐藏元素后,f12检查网页源代码还是有那个标签的,只是display为none
  • 使用if-else-if隐藏元素后,检查网页源代码并无未被渲染的元素
所有条件渲染方式,接收的值一定要是布尔类型(1或0;true或false)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>条件渲染</title>
</head>

<body>
    <!-- 视图入口 -->
    <div id="div">
        <!-- 判断num的值,对3取余,余数为0显示div1,为1显示div2,为2显示div3 -->
        <div v-if="num % 3 == 0">div1</div>
        <div v-if="num % 3 ==1">div2</div>
        <div v-if="num % 3 == 2">div3</div>
        <!-- 通过v-show控制元素渲染 -->
        <div v-show="flag">div4</div>
    </div>
</body>
<script src="../../js/vue.js"></script>
<script>
    new Vue({
        el: "#div", // 获取视图入口
        data: { // 为视图中的变量赋值
            num: 2,
            flag: false
        }
    });
</script>

</html>

列表渲染

  • v-for:列表渲染,遍历容器的元素或者对象的属性(类似于增强for

    格式:v-for="变量名 in 容器名"容器可以是数组,集合或对象

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>列表渲染</title>
</head>

<body>
    <!-- 视图入口 -->
    <div id="div">
        <ul>
            <!-- 循环遍历数组 -->
            <li v-for="name in names">
                {{name}}
            </li>
            <br>
            <!-- 循环遍历对象 -->
            <li v-for="value in students">
                {{value}}
            </li>

        </ul>
    </div>
</body>
<script src="../../js/vue.js"></script>
<script>
    new Vue({
        el: "#div", // 获取视图入口
        data: {
            names: ["张三", "李四", "王五"], // 数组

            students: { // 对象
                name: "张三",
                age: 23
            }
        }
    });
</script>

</html>

事件绑定

  • v-on:为HTML 标签绑定事件

    格式:v-on:事件名="要调用的方法"

    简写格式:@事件名="要调用的方法"

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件绑定</title>
</head>

<body>
    <!-- 视图入口 -->
    <div id="div">
        <div>{{name}}</div>
        <br>
        <!-- 绑定事件 -->
        <button v-on:click="change()">修改姓名</button>
        <!-- 简写格式 -->
        <button @click="change2()">恢复姓名</button>
    </div>
</body>
<script src="../../js/vue.js"></script>
<script>
    // 脚本
    new Vue({
        el: "#div", // 获取视图入口
        data: {
            name: "张三"
        },
        methods: {
            change() {
                this.name = "李四"
            },
            change2() {
                this.name = "张三"
            }
        }
    });
</script>

</html>

表单绑定

  • v-model:在表单元素上创建双向数据绑定(只能在表单元素使用
  • 双向数据绑定

    更新data数据,页面中的数据也会更新

    更新页面数据,data数据也会更新(并不是直接更新代码内容,而是在内存中进行

  • 对应MVVM模型(Model View ViewMode):是MVC模式的改进版

    在前端页面中,JS 对象表示 Model,页面表示 View,两者做到了最大限度的分离

    将Model 和 View 关联起来的就是 ViewModel,它是一个桥梁

    ViewModel 负责把 Model 的数据同步到 View 显示出来,还负责把 View 修改的数据同步回 Model

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>表单绑定</title>
</head>

<body>
    <!-- 视图入口 -->
    <div id="div">
        <form autocomplete="off">
            姓名:<input type="text" name="username" v-model="name">
            <br> 年龄:
            <input type="number" name="age" v-model="age">
        </form>
    </div>

</body>
<script src="../../js/vue.js"></script>
<script>
    // 脚本
    new Vue({
        el: "#div",
        data: {
            name: "张三",
            age: 23
        }
    });
</script>

</html>

Element基本使用

  • Element:网站快速成型工具。是饿了么公司前端开发团队提供的一套基于Vue 的网站组件库
  • 使用Element 前提是必须有 Vue
  • 组件:组成页面的部件,例如:超链接、按钮、图片、表格等等
  • Element官网:https://element.eleme.cn/#/zh-CN
相应的代码部分只需要了解即可,用的时候在官网查阅文档

快速入门

  1. 下载Element 核心库
  2. 引入 Element 样式文件
  3. 引入 Vue核心js 文件
  4. 引入Element 核心 js 文件
  5. 编写按钮标签
  6. 通过Vue 核心对象加载元素

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>快速入门</title>
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
    <script src="../js/vue.js"></script>
    <script src="element-ui/lib/index.js"></script>
</head>

<body>
    <button>我是按钮</button>
    <br>
    <!-- 视图入口 -->
    <div id="div">
        <el-row>
            <el-button>默认按钮</el-button>
            <el-button type="primary">主要按钮</el-button>
            <el-button type="success">成功按钮</el-button>
            <el-button type="info">信息按钮</el-button>
            <el-button type="warning">警告按钮</el-button>
            <el-button type="danger">危险按钮</el-button>
        </el-row>
        <br>
        <el-row>
            <el-button plain>朴素按钮</el-button>
            <el-button type="primary" plain>主要按钮</el-button>
            <el-button type="success" plain>成功按钮</el-button>
            <el-button type="info" plain>信息按钮</el-button>
            <el-button type="warning" plain>警告按钮</el-button>
            <el-button type="danger" plain>危险按钮</el-button>
        </el-row>
        <br>

        <el-row>
            <el-button round>圆角按钮</el-button>
            <el-button type="primary" round>主要按钮</el-button>
            <el-button type="success" round>成功按钮</el-button>
            <el-button type="info" round>信息按钮</el-button>
            <el-button type="warning" round>警告按钮</el-button>
            <el-button type="danger" round>危险按钮</el-button>
        </el-row>
        <br>

        <el-row>
            <el-button icon="el-icon-search" circle></el-button>
            <el-button type="primary" icon="el-icon-edit" circle></el-button>
            <el-button type="success" icon="el-icon-check" circle></el-button>
            <el-button type="info" icon="el-icon-message" circle></el-button>
            <el-button type="warning" icon="el-icon-star-off" circle></el-button>
            <el-button type="danger" icon="el-icon-delete" circle></el-button>
        </el-row>
    </div>
</body>
<script>
    new Vue({ // 使用element必须使用Vue加载视图入口标签
        el: "#div"
    });
</script>

</html>

基础布局

  • 基础布局:可以将页面最多分成24个部分,供我们自由切分

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>基础布局</title>
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
    <script src="../js/vue.js"></script>
    <script src="element-ui/lib/index.js"></script>
    <style>
        .el-row {
            margin-bottom: 20px;
        }
  
        .el-col {
            border-radius: 4px;
        }
  
        .bg-purple-dark {
            background: #99a9bf;
        }
  
        .bg-purple {
            background: #d3dce6;
        }
  
        .bg-purple-light {
            background: #e5e9f2;
        }
  
        .grid-content {
            border-radius: 4px;
            min-height: 36px;
        }
  
        .row-bg {
            padding: 10px 0;
            background-color: #f9fafc;
        }
    </style>
</head>

<body>
    <div id="div">
        <el-row>
            <el-col :span="24">
                <div class="grid-content bg-purple-dark"></div>
            </el-col>
        </el-row>
        <el-row>
            <el-col :span="12">
                <div class="grid-content bg-purple"></div>
            </el-col>
            <el-col :span="12">
                <div class="grid-content bg-purple-light"></div>
            </el-col>
        </el-row>
        <el-row>
            <el-col :span="8">
                <div class="grid-content bg-purple"></div>
            </el-col>
            <el-col :span="8">
                <div class="grid-content bg-purple-light"></div>
            </el-col>
            <el-col :span="8">
                <div class="grid-content bg-purple"></div>
            </el-col>
        </el-row>
        <el-row>
            <el-col :span="6">
                <div class="grid-content bg-purple"></div>
            </el-col>
            <el-col :span="6">
                <div class="grid-content bg-purple-light"></div>
            </el-col>
            <el-col :span="6">
                <div class="grid-content bg-purple"></div>
            </el-col>
            <el-col :span="6">
                <div class="grid-content bg-purple-light"></div>
            </el-col>
        </el-row>
        <el-row>
            <el-col :span="4">
                <div class="grid-content bg-purple"></div>
            </el-col>
            <el-col :span="4">
                <div class="grid-content bg-purple-light"></div>
            </el-col>
            <el-col :span="4">
                <div class="grid-content bg-purple"></div>
            </el-col>
            <el-col :span="4">
                <div class="grid-content bg-purple-light"></div>
            </el-col>
            <el-col :span="4">
                <div class="grid-content bg-purple"></div>
            </el-col>
            <el-col :span="4">
                <div class="grid-content bg-purple-light"></div>
            </el-col>
        </el-row>
    </div>

</body>
<script>
    new Vue({
        el: "#div" // 加载视图入口
    });
</script>

</html>

容器布局

  • 容器布局:将页面分为头部区域、侧边栏区域、主区域、底部区域

    可以进行有选择的使用,最多就是这四个

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>容器布局</title>
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
    <script src="../js/vue.js"></script>
    <script src="element-ui/lib/index.js"></script>
    <style>
        .el-header,
        .el-footer {
            background-color: #B3C0D1;
            color: #333;
            text-align: center;
            line-height: 60px;
        }
  
        .el-aside {
            background-color: #D3DCE6;
            color: #333;
            text-align: center;
            line-height: 200px;
        }
  
        .el-main {
            background-color: #E9EEF3;
            color: #333;
            text-align: center;
            line-height: 160px;
        }
  
        body>.el-container {
            margin-bottom: 40px;
        }
  
        .el-container:nth-child(5) .el-aside,
        .el-container:nth-child(6) .el-aside {
            line-height: 260px;
        }
  
        .el-container:nth-child(7) .el-aside {
            line-height: 320px;
        }
    </style>
</head>

<body>
    <div id="div">
        <el-container>
            <el-header>Header</el-header>
            <el-container>
                <el-aside width="200px">Aside</el-aside>
                <el-container>
                    <el-main>Main</el-main>
                    <el-footer>Footer</el-footer>
                </el-container>
            </el-container>
        </el-container>
    </div>

</body>
<script>
    new Vue({
        // 加载视图入口
        el: "#div"
    });
</script>

</html>

表单组件

  • 表单:由输入框、下拉列表、单选框、多选框等控件组成,用以收集、校验、提交数据

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>表单组件</title>
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
    <script src="../js/vue.js"></script>
    <script src="element-ui/lib/index.js"></script>
</head>

<body>
    <div id="div">
        <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
            <el-form-item label="活动名称" prop="name">
                <el-input v-model="ruleForm.name"></el-input>
            </el-form-item>
            <el-form-item label="活动区域" prop="region">
                <el-select v-model="ruleForm.region" placeholder="请选择活动区域">
                    <el-option label="区域一" value="shanghai"></el-option>
                    <el-option label="区域二" value="beijing"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="活动时间" required>
                <el-col :span="11">
                    <el-form-item prop="date1">
                        <el-date-picker type="date" placeholder="选择日期" v-model="ruleForm.date1" style="width: 100%;"></el-date-picker>
                    </el-form-item>
                </el-col>
                <el-col class="line" :span="2">-</el-col>
                <el-col :span="11">
                    <el-form-item prop="date2">
                        <el-time-picker placeholder="选择时间" v-model="ruleForm.date2" style="width: 100%;"></el-time-picker>
                    </el-form-item>
                </el-col>
            </el-form-item>
            <el-form-item label="即时配送" prop="delivery">
                <el-switch v-model="ruleForm.delivery"></el-switch>
            </el-form-item>
            <el-form-item label="活动性质" prop="type">
                <el-checkbox-group v-model="ruleForm.type">
                    <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
                    <el-checkbox label="地推活动" name="type"></el-checkbox>
                    <el-checkbox label="线下主题活动" name="type"></el-checkbox>
                    <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
                </el-checkbox-group>
            </el-form-item>
            <el-form-item label="特殊资源" prop="resource">
                <el-radio-group v-model="ruleForm.resource">
                    <el-radio label="线上品牌商赞助"></el-radio>
                    <el-radio label="线下场地免费"></el-radio>
                </el-radio-group>
            </el-form-item>
            <el-form-item label="活动形式" prop="desc">
                <el-input type="textarea" v-model="ruleForm.desc"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
                <el-button @click="resetForm('ruleForm')">重置</el-button>
            </el-form-item>
        </el-form>
    </div>
</body>
<script>
    new Vue({
        el: "#div",
        data: {
            ruleForm: {
                name: '',
                region: '',
                date1: '',
                date2: '',
                delivery: false,
                type: [],
                resource: '',
                desc: ''
            },
            rules: {
                name: [{
                    required: true,
                    message: '请输入活动名称',
                    trigger: 'blur'
                }, {
                    min: 3,
                    max: 5,
                    message: '长度在 3 到 5 个字符',
                    trigger: 'blur'
                }],
                region: [{
                    required: true,
                    message: '请选择活动区域',
                    trigger: 'change'
                }],
                date1: [{
                    type: 'date',
                    required: true,
                    message: '请选择日期',
                    trigger: 'change'
                }],
                date2: [{
                    type: 'date',
                    required: true,
                    message: '请选择时间',
                    trigger: 'change'
                }],
                type: [{
                    type: 'array',
                    required: true,
                    message: '请至少选择一个活动性质',
                    trigger: 'change'
                }],
                resource: [{
                    required: true,
                    message: '请选择活动资源',
                    trigger: 'change'
                }],
                desc: [{
                    required: true,
                    message: '请填写活动形式',
                    trigger: 'blur'
                }]
            }
        },
        methods: {
            submitForm(formName) {
                this.$refs[formName].validate((valid) => {
                    if (valid) {
                        alert('submit!');
                    } else {
                        console.log('error submit!!');
                        return false;
                    }
                });
            },
            resetForm(formName) {
                this.$refs[formName].resetFields();
            }
        }
    });
</script>

</html>

表格组件

  • 表格:用于展示多条结构类似的数据,可对数据进行编辑、删除或其他自定义操作

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>表格标签</title>
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
    <script src="../js/vue.js"></script>
    <script src="element-ui/lib/index.js"></script>
</head>

<body>
    <div id="div">
        <template>
            <el-table
              :data="tableData"
              style="width: 100%">
              <el-table-column
                prop="date"
                label="日期"
                width="180">
              </el-table-column>
              <el-table-column
                prop="name"
                label="姓名"
                width="180">
              </el-table-column>
              <el-table-column
                prop="address"
                label="地址">
              </el-table-column>
              <el-table-column
                label="操作">
                <el-button type="warning" round>修改</el-button>
                <el-button type="danger" round>删除</el-button>
              </el-table-column>
            </el-table>
          </template>
    </div>
</body>
<script>
    new Vue({
        el: "#div",
        data: {
            tableData: [{
                date: '2016-05-02',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1518 弄'
            }, {
                date: '2016-05-04',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1517 弄'
            }, {
                date: '2016-05-01',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1519 弄'
            }, {
                date: '2016-05-03',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1516 弄'
            }]
        }
    });
</script>

</html>

顶部导航栏组件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>顶部导航栏</title>
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
    <script src="../js/vue.js"></script>
    <script src="element-ui/lib/index.js"></script>
</head>

<body>
    <div id="div">
        <el-menu :default-active="activeIndex2" class="el-menu-demo" mode="horizontal" @select="handleSelect" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
            <el-menu-item index="1">处理中心</el-menu-item>
            <el-submenu index="2">
                <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 index="2-3">选项3</el-menu-item>
                <el-submenu index="2-4">
                    <template slot="title">选项4</template>
                    <el-menu-item index="2-4-1">选项1</el-menu-item>
                    <el-menu-item index="2-4-2">选项2</el-menu-item>
                    <el-menu-item index="2-4-3">选项3</el-menu-item>
                </el-submenu>
            </el-submenu>
            <el-menu-item index="3" disabled>消息中心</el-menu-item>
            <el-menu-item index="4"><a href="https://www.ele.me" target="_blank">订单管理</a></el-menu-item>
        </el-menu>
    </div>
</body>
<script>
    new Vue({
        el: "#div"
    });
</script>

</html>

侧边导航栏组件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>侧边导航栏</title>
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
    <script src="../js/vue.js"></script>
    <script src="element-ui/lib/index.js"></script>
</head>

<body>
    <div id="div">
        <el-col :span="4">
            <el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
                <el-submenu index="1">
                    <template slot="title">
                  <i class="el-icon-location"></i>
                  <span>导航一</span>
                </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">选项1</el-menu-item>
                    </el-submenu>
                </el-submenu>
                <el-menu-item index="2">
                    <i class="el-icon-menu"></i>
                    <span slot="title">导航二</span>
                </el-menu-item>
                <el-menu-item index="3" disabled>
                    <i class="el-icon-document"></i>
                    <span slot="title">导航三</span>
                </el-menu-item>
                <el-menu-item index="4">
                    <i class="el-icon-setting"></i>
                    <span slot="title">导航四</span>
                </el-menu-item>
            </el-menu>
        </el-col>
        </el-row>
    </div>
</body>
<script>
    new Vue({
        el: "#div"
    });
</script>

</html>

学生列表案例

案例分析

  • 三个区域:头部区域、侧边导航条、主区域
  • 头部:logo+顶部导航条
  • 侧边栏:侧边导航条
  • 主区域:标题+表格+按钮

案例实现

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>学生列表</title>
    <link rel="stylesheet" href="../element-ui/lib/theme-chalk/index.css">
    <script src="../../js/vue.js"></script>
    <script src="../element-ui/lib/index.js"></script>
    <style>
        .header {
            background-color: #545c64;
        }
  
        .logo {
            width: 200px;
            margin-top: 5px;
        }
    </style>
</head>

<body>
    <div id="div">
        <el-container>
            <!-- 顶部区域 -->
            <el-header class="header">
                <el-container>
                    <!-- logo -->
                    <div>
                        <el-image src="logo.png" class="logo"></el-image>
                    </div>
                    <!-- 导航栏 -->
                    <el-menu :default-active="activeIndex2" mode="horizontal" @select="handleSelect" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" style="margin-left: auto;">
                        <el-menu-item index="1">处理中心</el-menu-item>
                        <el-submenu index="2">
                            <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 index="2-3">选项3</el-menu-item>
                        </el-submenu>
                        <el-menu-item index="3"><a href="https://www.hellocode.top" target="_self">首页</a></el-menu-item>
                    </el-menu>
                </el-container>
            </el-header>
            <!-- 侧边栏 -->
            <el-container style="height: 960px; ">
                <el-aside style="background-color: rgb(238,241,246);">
                    <el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :default-openeds="['1']">
                        <el-submenu index="1">
                            <template slot="title">
                                <i class="el-icon-s-custom"></i>
                                <span>学工部</span>
                            </template>
                            <el-menu-item-group>
                                <el-menu-item index="1-1"><i class="el-icon-position"></i>在校学生管理</el-menu-item>
                                <el-menu-item index="1-2"><i class="el-icon-place"></i>学生升级/留级</el-menu-item>
                                <el-menu-item index="1-3"><i class="el-icon-basketball"></i>学生就业情况</el-menu-item>
                            </el-menu-item-group>
                        </el-submenu>
                        <el-submenu index="2">
                            <template slot="title">
                                <i class="el-icon-message"></i>
                                <span>咨询部</span>
                            </template>
                            <el-menu-item-group>
                                <el-menu-item index="2-1"><i class="el-icon-ship"></i>意向学生管理</el-menu-item>
                                <el-menu-item index="2-2"><i class="el-icon-football"></i>未报名学生管理</el-menu-item>
                                <el-menu-item index="2-3"><i class="el-icon-sugar"></i>已报名学生管理</el-menu-item>
                            </el-menu-item-group>
                        </el-submenu>
                        <el-submenu index="3">
                            <template slot="title">
                                <i class="el-icon-odometer"></i>
                                <span>教研部</span>
                            </template>
                            <el-menu-item-group>
                                <el-menu-item index="3-1"><i class="el-icon-connection"></i>已有课程管理</el-menu-item>
                                <el-menu-item index="3-2"><i class="el-icon-guide"></i>正在研发课程管理</el-menu-item>
                                <el-menu-item index="3-3"><i class="el-icon-magic-stick"></i>新技术课程管理</el-menu-item>
                            </el-menu-item-group>
                        </el-submenu>
                    </el-menu>
                </el-aside>
                <!-- 主区域 -->
                <el-main>
                    <b style="font-size: 20px; color: red; float: left;">学生列表</b>
                    <div style="float: right;">
                        <el-button type="primary" round>添加学生</el-button>
                    </div>
                    <!-- 表格 -->
                    <template>
                        <el-table
                          :data="tableData"
                          style="width: 100%">
                          <el-table-column
                            prop="date"
                            label="日期"
                            width="180">
                          </el-table-column>
                          <el-table-column
                            prop="name"
                            label="姓名"
                            width="180">
                          </el-table-column>
                          <el-table-column
                            prop="address"
                            label="地址">
                          </el-table-column>
                          <el-table-column
                            label="操作">
                            <el-button type="primary" icon="el-icon-edit" circle></el-button>
                            <el-button type="danger" icon="el-icon-delete" circle></el-button>
                          </el-table-column>
                        </el-table>
                      </template>
                </el-main>
            </el-container>
        </el-container>
    </div>
</body>
<script>
    new Vue({
        el: "#div",
        data: {
            tableData: [{
                date: "2022-04-22",
                name: "张三",
                address: "安康市紫阳县"
            }, {
                date: "2022-04-22",
                name: "李四",
                address: "宝鸡市凤县"
            }, {
                date: "2022-04-22",
                name: "王五",
                address: "西安市未央区"
            }]
        }
    });
</script>

</html>

Vue高级使用

自定义组件

  • 通过学习Element ,我们发现组件其实就是自定义的标签。例如:<el-button>就是对<button>的封装
  • 本质上,组件就是带有一个名字且可以重复使用的Vue实例,我们完全可以自己定义
  • 定义格式

    Vue.component(组件名称,{
        props:组件的属性,
        data:组件的数据函数,
        template:组件解析的标签模板
    })
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>自定义组件</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="div">
        <my-button>我是按钮</my-button>
    </div>
</body>
<script>
    // 自定义组件
    Vue.component("my-button", {
        props: "style",
        data: function() {
            return {        // 组件数据必须是一个函数,数据通过return返回
                msg: "这是按钮"
            }
        },
        template: "<button style='color:red;'>{{msg}}</button>"
    })

    // 脚本
    new Vue({
        el: "#div"
    });
</script>

</html>

生命周期

生命周期的八个阶段

状态阶段周期
beforeCreate创建前
created创建后
beforeMount载入前
mounted载入后
beforeUpdate更新前
updated更新后
beforeDestroy销毁前
destroyed销毁后

异步操作

  • 在 Vue 中发送异步请求,本质上还是AJAX,我们可以使用axios 这个插件来简化操作

使用步骤

  1. 引入 axios 核心js文件
  2. 调用axios 对象的方法来发起异步请求
  3. 调用axios 对象的方法来处理响应的数据

axios常用方法

方法名作用
get(请求的资源路径与请求的参数)发去GET方式请求
post(请求的资源路径,请求的参数)发起POST方式请求
then(response)请求成功后的回调函数,通过response获取响应的数据
catch(error)请求失败后的回调函数,通过error获取错误信息
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>异步操作</title>
    <script src="js/vue.js"></script>
    <script src="js/axios-0.18.0.js"></script>
</head>
<body>
    <div id="div">
        {{name}}
        <button @click="send()">发起请求</button>
    </div>
</body>
<script>
    new Vue({
        el:"#div",
        data:{
            name:"张三"
        },
        methods:{
            send(){
                // GET请求方式
                // axios.get("testServlet?name="+this.name).
                //     then(resp => {
                //         alert(resp.data);
                // }).catch(error => {
                //     alert(error);
                // });

                // POST请求方式
                axios.post("testServlet","name="+this.name).
                then(resp => {
                    alert(resp.data);
                }).catch(error => {
                    alert(error);
                });
            }
        }
    });
</script>
</html>
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/testServlet")
public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置编码
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        // 获取请求参数
        String name = req.getParameter("name");
        System.out.println(name);
        // 响应参数
        resp.getWriter().write("请求成功");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

学生管理系统

WEB

index

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>学生列表</title>
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
    <script src="js/vue.js"></script>
    <script src="element-ui/lib/index.js"></script>
    <style>
        .header {
            background-color: #545c64;
        }
  
        .logo {
            width: 200px;
            margin-top: 5px;
        }
    </style>
</head>

<body>
    <div id="div">
        <el-container>
            <!-- 顶部区域 -->
            <el-header class="header">
                <el-container>
                    <!-- logo -->
                    <div>
                        <el-image src="logo.png"
                            class="logo" @click="index()" style="cursor: pointer"></el-image>
                    </div>
                    <!-- 导航栏 -->
                    <el-menu :default-active="activeIndex2" mode="horizontal" @select="handleSelect" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" style="margin-left: auto;">
                        <el-menu-item index="1">处理中心</el-menu-item>
                        <el-submenu index="2">
                            <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 index="2-3">选项3</el-menu-item>
                        </el-submenu>
                        <el-menu-item index="3"><a href="https://www.hellocode.top" target="_self">首页</a></el-menu-item>
                    </el-menu>
                </el-container>
            </el-header>
            <!-- 侧边栏 -->
            <el-container style="height: 960px; ">
                <el-aside style="background-color: rgb(238,241,246);">
                    <el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :default-openeds="['1']">
                        <el-submenu index="1">
                            <template slot="title">
                                <i class="el-icon-s-custom"></i>
                                <span>学工部</span>
                            </template>
                            <el-menu-item-group>
                                <el-menu-item index="1-1" @click="findAll()"><i class="el-icon-position"></i>在校学生管理</el-menu-item>
                                <el-menu-item index="1-2"><i class="el-icon-place"></i>学生升级/留级</el-menu-item>
                                <el-menu-item index="1-3"><i class="el-icon-basketball"></i>学生就业情况</el-menu-item>
                            </el-menu-item-group>
                        </el-submenu>
                        <el-submenu index="2">
                            <template slot="title">
                                <i class="el-icon-message"></i>
                                <span>咨询部</span>
                            </template>
                            <el-menu-item-group>
                                <el-menu-item index="2-1"><i class="el-icon-ship"></i>意向学生管理</el-menu-item>
                                <el-menu-item index="2-2"><i class="el-icon-football"></i>未报名学生管理</el-menu-item>
                                <el-menu-item index="2-3"><i class="el-icon-sugar"></i>已报名学生管理</el-menu-item>
                            </el-menu-item-group>
                        </el-submenu>
                        <el-submenu index="3">
                            <template slot="title">
                                <i class="el-icon-odometer"></i>
                                <span>教研部</span>
                            </template>
                            <el-menu-item-group>
                                <el-menu-item index="3-1"><i class="el-icon-connection"></i>已有课程管理</el-menu-item>
                                <el-menu-item index="3-2"><i class="el-icon-guide"></i>正在研发课程管理</el-menu-item>
                                <el-menu-item index="3-3"><i class="el-icon-magic-stick"></i>新技术课程管理</el-menu-item>
                            </el-menu-item-group>
                        </el-submenu>
                    </el-menu>
                </el-aside>
                <!-- 主区域 -->
                <el-main>
                    <iframe :src="iframeSrc" frameborder="false" style="top: 80px;left: 120px;width: 100%;height: 100%"></iframe>
                </el-main>
            </el-container>
        </el-container>
    </div>
</body>
<script>
    new Vue({
        el: "#div",
        data: {
            iframeSrc:"manager.html"
        },
        methods:{
            findAll:function (){
                this.iframeSrc="stuList.html"
            },
            index:function (){
                this.iframeSrc="manager.html"
            }
        }
    });
</script>

</html>

login

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>请先登录</title>
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
    <script src="js/vue.js"></script>
    <script src="element-ui/lib/index.js"></script>
    <script src="js/axios-0.18.0.js"></script>
    <style>
        .login-box {
            border: 1px solid #DCDFE6;
            width: 350px;
            margin: 120px auto;
            padding: 35px 35px 15px 35px;
            border-radius: 5px;
            -webkit-border-radius: 5px;
            -moz-border-radius: 5px;
            box-shadow: 0 0 25px #909399;
        }

        .login-title {
            text-align: center;
            margin: 0 auto 40px auto;
            color: #303133;
        }

    </style>
</head>
<body>
    <div id="app">
        <el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
            <h3 class="login-title">欢迎登录</h3>
            <el-form-item label="用户名" prop="username">
                <el-input v-model="form.username" type="text" placeholder="请输入用户名"/>
            </el-form-item>
            <el-form-item label="密码" prop="password">
                <el-input v-model="form.password" type="password" placeholder="请输入密码"/>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button>
            </el-form-item>
        </el-form>
    </div>
</body>
<script>
    new Vue({
        el:"#app",
        data:{
            form:{
                username:'',
                password:''
            },
            rules:{     // 校验规则
                username:[
                    {required:true,message:'请输入用户名',trigger:'blur'}
                ],
                password:[
                    {required:true,message:'请输入密码',trigger:'blur'}
                ]
            }
        },
        methods:{
            onSubmit:function (formName){
                // 为表单绑定验证功能
                this.$refs[formName].validate((valid) =>{
                    if(valid){
                        // 请求服务器完成登录功能
                        axios.post("userServlet", "username=" + this.form.username + "&password=" + this.form.password)
                        .then(resp => {
                            // 成功回调函数
                            if(resp.data == true){
                                // 登录成功。跳转首页
                                location.href = "index.html";
                            }else{
                                // 登录失败
                                alert("登录失败,请检查用户名或密码");
                                location.href = "login.html";
                            }
                        });
                    }else{
                        return false;
                    }
                });
            }
        }
    });
</script>
</html>

manager

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p style="font-size: 35px;font-weight: 700;">欢迎来到学生管理系统~~~</p>
</body>
</html>

stuList

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
    <script src="js/vue.js"></script>
    <script src="element-ui/lib/index.js"></script>
    <script src="js/axios-0.18.0.js"></script>
</head>
<body>
    <div id="div">
        <b style="font-size: 20px; color: red; float: left;">学生列表</b>
        <div style="float: right;">
            <el-button type="primary" round @click="showAddStu">添加学生</el-button>
        </div>
        <!-- 表格 -->
        <template>
            <el-table
                    :data="tableData"
                    style="width: 100%">
                <el-table-column
                        prop="number"
                        label="学号"
                        width="180">
                </el-table-column>
                <el-table-column
                        prop="name"
                        label="姓名"
                        width="180">
                </el-table-column>
                <el-table-column
                        prop="birthday"
                        label="生日"
                        width="180">
                </el-table-column>
                <el-table-column
                        prop="address"
                        label="地址">
                </el-table-column>
                <el-table-column
                        label="操作">
                    <template slot-scope="props">
                        <el-button type="primary" icon="el-icon-edit" @click="showEditStu(props.row)" circle></el-button>
                        <el-button type="danger" icon="el-icon-delete" @click="deleteStu(props.row)" circle></el-button>
                    </template>
                </el-table-column>
            </el-table>
            <!--
                分页组件
                @size-change: 当改变每页条数时触发的函数
                @current-change:当改变页码时触发的函数
                current-page:默认的页码
                :page-sizes:每页条数选择框中显示的值
                :page-size:默认的每页条数
                layout:分页组件的布局
                    total(总条数),sizes(每页条数),prev(上一页),pager(所有的页码),next(下一页),jumper(跳转页码)
                :total:总条数
            -->
            <el-pagination
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                    :current-page="pagination.currentPage"
                    :page-sizes="[3, 5, 8]"
                    :page-size="100"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="pagination.total">
            </el-pagination>


            <!-- 添加学生窗口 -->
            <el-dialog title="添加学生信息" :visible.sync="dialogTableVisible4add" @close="resetForm('addForm')">
                <!--
                    :model="formData":关联数据
                    :rules:关联校验规则
                    ref:在获取表单对象时使用
                -->
                <el-form :model="formData" :rules="rules" ref="addForm" label-width="100px" class="demo-ruleForm">
                    <el-form-item label="学生学号" prop="number">
                        <el-input v-model="formData.number"></el-input>
                    </el-form-item>
                    <el-form-item label="学生姓名" prop="name">
                        <el-input v-model="formData.name"></el-input>
                    </el-form-item>
                    <el-form-item label="学生生日" prop="birthday">
                        <el-input v-model="formData.birthday" type="date"></el-input>
                    </el-form-item>
                    <el-form-item label="学生地址" prop="address">
                        <el-input v-model="formData.address"></el-input>
                    </el-form-item>
                </el-form>
                <div slot="footer" class="dialog-footer">
                    <el-button type="primary" @click="addStu()">添加</el-button>
                    <el-button @click="resetForm('addForm')">重置</el-button>
                </div>
            </el-dialog>

            <!--编辑学生信息-->
            <el-dialog title="编辑学生信息" :visible.sync="dialogTableVisible4edit" @close="resetForm('editForm')">
                <!--
                    :model="formData":关联数据
                    :rules:关联校验规则
                    ref:在获取表单对象时使用
                -->
                <el-form :model="editFormData" :rules="rules" ref="editForm" label-width="100px" class="demo-ruleForm">
                    <el-form-item label="学生学号" prop="number">
                        <el-input v-model="editFormData.number"></el-input>
                    </el-form-item>
                    <el-form-item label="学生姓名" prop="name">
                        <el-input v-model="editFormData.name"></el-input>
                    </el-form-item>
                    <el-form-item label="学生生日" prop="birthday">
                        <el-input v-model="editFormData.birthday" type="date"></el-input>
                    </el-form-item>
                    <el-form-item label="学生地址" prop="address">
                        <el-input v-model="editFormData.address"></el-input>
                    </el-form-item>
                </el-form>
                <div slot="footer" class="dialog-footer">
                    <el-button type="primary" @click="updateStu()">修改</el-button>
                </div>
            </el-dialog>

        </template>
    </div>
</body>
<script>
    new Vue({
        el:"#div",
        data:{
            dialogTableVisible4add:false,   // 添加窗口显示状态
            dialogTableVisible4edit:false,      // 编辑窗口显示状态
            formData:{},     //添加表单的数据
            editFormData:{},        // 编辑表单的数据
            tableData:[],       // 表格数据
            pagination:{
                currentPage:1,      //当前页
                pageSize:3,     //每页显示条数
                total:0         // 总条数
            },
            rules: {
                number: [
                    {required: true, message: '请输入学号', trigger: 'blur'},
                    {min: 10, max: 11, message: '长度在 10 或 11 个字符', trigger: 'blur'}
                ],
                name: [
                    {required: true, message: '请输入姓名', trigger: 'blur'},
                    {min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur'}
                ],
                birthday: [
                    {required: true, message: '请选择日期', trigger: 'change'}
                ],
                address: [
                    {required: true, message: '请输入地址', trigger: 'blur'},
                    {min: 2, max: 200, message: '长度在 2 到 200 个字符', trigger: 'blur'}
                ]
            }
        },
        methods:{
            //改变每页条数时执行的函数
            handleSizeChange(pageSize) {
                //修改分页查询的参数
                this.pagination.pageSize = pageSize;
                //重新执行查询
                this.selectByPage();
            },
            //改变页码时执行的函数
            handleCurrentChange(pageNum) {
                //修改分页查询的参数
                this.pagination.currentPage = pageNum;
                //重新执行查询
                this.selectByPage();
            },
            showAddStu() {
                //弹出窗口
                this.dialogTableVisible4add = true;
            },
            // 添加学生功能
            addStu(){
                let param = "method=addStu&number=" + this.formData.number + "&name=" + this.formData.name
                    + "&birthday=" + this.formData.birthday + "&address=" + this.formData.address
                    + "&currentPage=" + this.pagination.currentPage + "&pageSize=" + this.pagination.pageSize;
                axios.post("studentServlet",param)
                .then(resp => {
                    // 将查询出的数据赋值tableDate
                    this.tableData = resp.data.list;
                    // 设置分页参数
                    // 当前页
                    this.pagination.currentPage = resp.data.pageNum;
                    // 总条数
                    this.pagination.total = resp.data.total;
                });
                // 关闭窗口
                this.dialogTableVisible4add = false;
            },
            resetForm(addForm) {
                //双向绑定,输入的数据都赋值给了formData, 清空formData数据
                this.formData = {};
                //清除表单的校验数据
                this.$refs[addForm].resetFields();
            },
            showEditStu(row) {
                //1. 弹出窗口
                this.dialogTableVisible4edit = true;

                //2. 显示表单数据
                this.editFormData = {
                    number:row.number,
                    name:row.name,
                    birthday:row.birthday,
                    address:row.address,
                }
            },
            // 修改数据功能
            updateStu(){
                let param = "method=updateStu&number=" + this.editFormData.number + "&name=" + this.editFormData.name
                    + "&birthday=" + this.editFormData.birthday + "&address=" + this.editFormData.address
                    + "&currentPage=" + this.pagination.currentPage + "&pageSize=" + this.pagination.pageSize;
                axios.post("studentServlet",param)
                    .then(resp => {
                        // 将查询出的数据赋值tableDate
                        this.tableData = resp.data.list;
                        // 设置分页参数
                        // 当前页
                        this.pagination.currentPage = resp.data.pageNum;
                        // 总条数
                        this.pagination.total = resp.data.total;
                    });
                // 关闭窗口
                this.dialogTableVisible4edit = false;
            },
            // 分页查询功能
            selectByPage(){
                axios.post("studentServlet","method=selectByPage&currentPage=" + this.pagination.currentPage + "&pageSize=" + this.pagination.pageSize)
                .then(resp => {
                    // 成功的回调函数
                    // 将查询出的数据赋值给tableDate
                    this.tableData = resp.data.list;
                    // 设置分页参数
                    // 当前页
                    this.pagination.currentPage = resp.data.pageNum;
                    // 总条数
                    this.pagination.total = resp.data.total;
                });
            },
            // 删除功能
            deleteStu(row){
                if(confirm("确定要删除" + row.name + "的数据吗?")){      // 弹出确认(true)与取消(false)
                    // 确认则删除
                    let param = "method=deleteStu&number=" + row.number
                        + "&currentPage=" + this.pagination.currentPage + "&pageSize=" + this.pagination.pageSize;
                    axios.post("studentServlet",param)
                    .then(resp => {
                        // 将查询出的数据赋值给tableDate
                        this.tableData = resp.data.list;
                        // 设置分页参数
                        // 当前页
                        this.pagination.currentPage = resp.data.pageNum;
                        // 总条数
                        this.pagination.total = resp.data.total;
                    });
                }
            }
        },
        mounted(){      // 页面加载完成后执行的功能
            // 调用分页查询功能
            this.selectByPage();
        }
    });
</script>
</html>

Java

Student和User标准类

package study.vue.bean;

import java.sql.Date;


public class Student {
    private Integer number;
    private String name;
    private Date birthday;
    private String address;

    public Student() {
    }

    public Student(Integer number, String name, Date birthday, String address) {
        this.number = number;
        this.name = name;
        this.birthday = birthday;
        this.address = address;
    }

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Student{" +
                "number=" + number +
                ", name='" + name + '\'' +
                ", birthday=" + birthday +
                ", address='" + address + '\'' +
                '}';
    }
}
package study.vue.bean;

public class User {
    private String username;
    private String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public User() {
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

controller

package study.vue.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import study.vue.bean.Student;
import study.vue.service.StudentService;
import study.vue.service.impl.StudentServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

@WebServlet("/studentServlet")
public class StudentServlet extends HttpServlet {
    private StudentService service = new StudentServiceImpl();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求和响应编码
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        // 获取方法名
        String method = req.getParameter("method");
        if("selectByPage".equals(method)){
            // 分页查询功能
            selectByPage(req,resp);
        }else if("addStu".equals(method)){
            // 添加数据功能
            addStu(req,resp);
        }else if("updateStu".equals(method)){
            // 添加数据功能
            updateStu(req,resp);
        }else if("deleteStu".equals(method)){
            // 添加数据功能
            deleteStu(req,resp);
        }
    }
    // 删除数据功能
    private void deleteStu(HttpServletRequest req, HttpServletResponse resp) {
        try {
            req.setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        resp.setContentType("text/html;charset=UTF-8");

        // 获取请求参数
        String number = req.getParameter("number");
        String currentPage = req.getParameter("currentPage");
        String pageSize = req.getParameter("pageSize");

        // 调用删除方法
        service.deleteStu(Integer.parseInt(number));

        // 重定向到分页查询功能
        try {
            resp.sendRedirect(req.getContextPath() + "/studentServlet?method=selectByPage&currentPage=" + currentPage + "&pageSize=" + pageSize);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 修改数据功能
    private void updateStu(HttpServletRequest req, HttpServletResponse resp) {
        try {
            req.setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        resp.setContentType("text/html;charset=UTF-8");

        // 获取请求参数
        Map<String, String[]> map = req.getParameterMap();
        String currentPage = req.getParameter("currentPage");
        String pageSize = req.getParameter("pageSize");


        // 封装Student 对象
        Student stu = new Student();

        // 注册日期转换器
        dateConvert();

        try {
            BeanUtils.populate(stu,map);        // 自动封装数据
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 调用业务层的修改方法
        service.updateStu(stu);

        // 重定向到分页查询功能
        try {
            resp.sendRedirect(req.getContextPath() + "/studentServlet?method=selectByPage&currentPage=" + currentPage + "&pageSize=" + pageSize);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 添加数据功能
    private void addStu(HttpServletRequest req, HttpServletResponse resp) {
        try {
            req.setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        resp.setContentType("text/html;charset=UTF-8");

        // 获取请求参数
        Map<String, String[]> map = req.getParameterMap();
        String currentPage = req.getParameter("currentPage");
        String pageSize = req.getParameter("pageSize");


        // 封装Student 对象
        Student stu = new Student();

        // 注册日期转换器
        dateConvert();

        try {
            BeanUtils.populate(stu,map);        // 自动封装数据
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 调用业务层的添加方法
        service.addStu(stu);

        // 重定向到分页查询功能
        try {
            resp.sendRedirect(req.getContextPath() + "/studentServlet?method=selectByPage&currentPage=" + currentPage + "&pageSize=" + pageSize);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void dateConvert() {
        ConvertUtils.register(new Converter() {
            @Override
            public Object convert(Class type, Object value) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    return simpleDateFormat.parse(value.toString());
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }, Date.class);
    }

    // 分页查询功能
    private void selectByPage(HttpServletRequest req, HttpServletResponse resp) {

        try {
            req.setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        resp.setContentType("text/html;charset=UTF-8");
        // 获取请求参数
        String currentPage = req.getParameter("currentPage");
        String pageSize = req.getParameter("pageSize");

        // 调用业务层的查询方法
        Page page = service.selectByPage(Integer.parseInt(currentPage), Integer.parseInt(pageSize));

        // 封装PageInfo
        PageInfo info = new PageInfo(page);

        // 将info转为json,响应给客户端
        try {
            String json = new ObjectMapper().writeValueAsString(info);
            resp.getWriter().write(json);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
package study.vue.controller;

import study.vue.bean.User;
import study.vue.service.UserService;
import study.vue.service.impl.UserServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@WebServlet("/userServlet")
public class UserServlet extends HttpServlet {
    private UserService service = new UserServiceImpl();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求和响应编码
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        // 获取请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        // 封装User对象
        User user = new User(username,password);

        // 调用业务层的登录方法
        List<User> list = service.login(user);

        // 判断是否查询出了结果
        if(list.size() != 0){
            // 将用户名存入会话域
            req.getSession().setAttribute("username",username);
            // 响应给客户端
            resp.getWriter().write("true");
        }else{
            resp.getWriter().write("false");
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

filter

package study.vue.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter(value = {"/index.html"})
public class LoginFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 转换Http协议相关的请求和响应对象
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 获取会话域对象中的数据
        Object username = request.getSession().getAttribute("username");
        // 判断用户名
        if(username == null || "".equals(username)){
            // 重定向到登录页面
            response.sendRedirect(request.getContextPath() + "/login.html");
            return;
        }
        // 放行
        filterChain.doFilter(request,response);
    }
}

mapper

package study.vue.mapper;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import study.vue.bean.Student;

import java.util.List;

public interface StudentMapper {
    // 查询全部方法
    @Select("SELECT * FROM student")
    public abstract List<Student> selectAll();

    /*
    *   添加数据方法
    * */
    @Insert("INSERT INTO student VALUES (#{number},#{name},#{birthday},#{address})")
    public abstract void addStu(Student stu);

    /*
    *   修改数据方法
    * */
    @Update("UPDATE student SET number=#{number},name=#{name},birthday=#{birthday},address=#{address} WHERE number=#{number}")
    public abstract void updateStu(Student stu);

    /*
    *   删除数据方法
    * */
    @Delete("DELETE FROM student WHERE number=#{number}")
    public abstract void deleteStu(Integer number);
}
package study.vue.mapper;

import org.apache.ibatis.annotations.Select;
import study.vue.bean.User;

import java.util.List;

public interface UserMapper {
    /*
    *   登录方法
    * */
    @Select("SELECT * FROM user WHERE username = #{username} AND password = #{password}")
    public abstract List<User> login(User user);
}

service

package study.vue.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import study.vue.bean.Student;
import study.vue.mapper.StudentMapper;
import study.vue.service.StudentService;

import java.io.IOException;
import java.io.InputStream;

public class StudentServiceImpl implements StudentService {
    @Override
    public Page selectByPage(Integer currentPage, Integer pageSize) {
        InputStream is = null;
        SqlSession sqlSession = null;
        Page page = null;
        try {
            // 加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");
            // 获取sqlsession
            sqlSession = new SqlSessionFactoryBuilder().build(is).openSession(true);
            // 获取mapper
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            // 设置分页参数
            page = PageHelper.startPage(currentPage,pageSize);
            // 查询全部
            mapper.selectAll();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 释放资源
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(sqlSession != null){
                sqlSession.close();
            }
        }
        // 返回结果
        return page;
    }

    @Override
    public void addStu(Student stu) {
        InputStream is = null;
        SqlSession sqlSession = null;
        try {
            // 加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");
            // 获取sqlsession
            sqlSession = new SqlSessionFactoryBuilder().build(is).openSession(true);
            // 获取mapper
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            // 执行添加方法
            mapper.addStu(stu);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 释放资源
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(sqlSession != null){
                sqlSession.close();
            }
        }
    }

    @Override
    public void updateStu(Student stu) {
        InputStream is = null;
        SqlSession sqlSession = null;
        try {
            // 加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");
            // 获取sqlsession
            sqlSession = new SqlSessionFactoryBuilder().build(is).openSession(true);
            // 获取mapper
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            // 执行添加方法
            mapper.updateStu(stu);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 释放资源
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(sqlSession != null){
                sqlSession.close();
            }
        }
    }

    @Override
    public void deleteStu(Integer number) {
        InputStream is = null;
        SqlSession sqlSession = null;
        try {
            // 加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");
            // 获取sqlsession
            sqlSession = new SqlSessionFactoryBuilder().build(is).openSession(true);
            // 获取mapper
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            // 执行添加方法
            mapper.deleteStu(number);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 释放资源
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(sqlSession != null){
                sqlSession.close();
            }
        }
    }
}
package study.vue.service.impl;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import study.vue.bean.User;
import study.vue.mapper.UserMapper;
import study.vue.service.UserService;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class UserServiceImpl implements UserService {
    @Override
    public List<User> login(User user) {
        InputStream is = null;
        SqlSession sqlSession = null;
        List<User> list = null;
        try {
            // 加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            // 获取sqlsession
            sqlSession = new SqlSessionFactoryBuilder().build(is).openSession(true);
            // 获取UserMapper接口的实现类对象
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            // 调用登录方法
            list = mapper.login(user);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 释放资源
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(sqlSession != null){
                sqlSession.close();
            }
        }
        // 返回结果
        return list;
    }
}

配置文件

config.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.23.129:3306/db15
username=root
password=密码

log4j

# log4j.properties

# Global logging configuration
# ?????????????ERROR?WARN?INFO?DEBUG
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

MyBatisConfig.xml

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

<!--核心根标签-->
<configuration>
    <!-- 引入数据库连接信息配置文件 -->
    <properties resource="config.properties"/>
    <!--集成LOG4J日志信息-->
    <settings>
        <setting name="logImpl" value="log4j"/>
    </settings>

    <!--集成分页助手插件-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"/>
    </plugins>


    <!--配置数据库环境,环境可以有多个。default指定使用的是哪个-->
    <environments default="mysql">
        <!--配置数据库环境,可以写很多个,id表示唯一的标识-->
        <environment id="mysql">
            <!--事务管理,type属性代表采用JDBC默认的事务处理-->
            <transactionManager type="JDBC"></transactionManager>
            <!--数据源信息,type属性代表连接池-->
            <dataSource type="POOLED">
                <!--获取数据库连接的配置信息-->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--引入映射配置文件-->
    <mappers>
        <!--接口所在的包-->
        <package name="study.vue.mapper"/>
    </mappers>
</configuration>

推荐阅读:【JavaWEB】Redis基础

END
本文作者: 文章标题:【JavaWEB】Vue+Element
本文地址:https://www.jiusi.cc/archives/62/
版权说明:若无注明,本文皆九思のJava之路原创,转载请保留文章出处。
最后修改:2022 年 05 月 07 日
如果觉得我的文章对你有用,请随意赞赏