千锋 Vue 详细笔记整理

视频笔记是根据B站 千锋 涛哥 - SpringBoot+vue+前后端分离项目《锋迷商城》实战课-完结版 进行整理的

笔记可上 gitee仓库 自取

千锋 Vue 笔记整理

  • 一、vue 的简介
    • 1.1 使用 JQuery 的复杂性问题
    • 1.2 VUE 简介
      • 1.2.1 前端框架
      • 1.2.2 MVVM
  • 二、 vue 入门使用
    • 2.1 vue 的引入
    • 2.2 入门案例 -- Hello World
  • 三、 vue 的语法
    • 3.1 基本类型数据和字符串
    • 3.2 对象类型数据
    • 3.3 条件 v-if
    • 3.4 循环 v-for
    • 3.5 绑定标签属性 v-bind
    • 3.6 表单标签的双向绑定 v-model
  • 四、vue 实例
    • 4.1 vue 实例的生命周期
    • 4.2 钩子函数
  • 五、 计算属性和侦听器
    • 5.1 计算属性
    • 5.2 侦听器
  • 六、class 与 style 绑定
    • 6.1 class 绑定
    • 6.2 style 绑定
  • 七、条件与列表渲染
    • 7.1 条件渲染
      • 7.1.1 v-if
      • 7.1.2 v-else
      • 7.1.3 v-else-if
      • 7.1.4 v-show
    • 7.2 列表渲染
  • 八、事件处理
    • 8.1 使用 JS 函数传值
    • 8.2 使用 dataset 对象传值 `(推荐)`
    • 8.3 混合使用
    • 8.4 事件修饰符
      • 8.4.1 事件修饰符使用示例
      • 8.4.2 事件修饰符
    • 8.5 按键修饰符
    • 8.6 系统修饰符
  • 九、表单输入绑定
  • 十、组件
    • 10.1 组件介绍及示例
      • 10.1.1 组件注册
      • 10.1.2 组件引用
    • 10.2 组件注册
      • 10.2.1 自定义组件的结构
      • 10.2.2 组件的封装
      • 10.2.3 组件的复用
    • 10.3 组件通信
      • 10.3.1 父传子
      • 10.3.2 子传父 -- 使用 `props` 属性动态传递参数
      • 10.3.3 总结
    • 10.4 组件插槽
      • 10.4.1 插槽的使用
      • 10.4.2 具名插槽
      • 10.4.3 插槽作用域
  • 十一、axios 异步通信
    • 11.1 axios 介绍
    • 11.2 axios 入门使用
    • 11.3 axios 异步请求方法
      • 11.3.1 GET 格式的请求
      • 11.3.2 POST 格式的请求
      • 11.3.3 自定义请求
      • 11.3.4 请求方法别名
    • 11.4 并发请求
    • 11.5 箭头函数
      • 11.5.1 axios 回调函数的参数 res
      • 11.5.2 箭头函数
  • 十二、 路由 router
    • 12.1 路由插件的引用
      • 12.1.1 离线
      • 12.1.2 在线 CDN
    • 12.2 动态路由匹配
      • 12.2.1 通配符
      • 12.2.2 路由参数
      • 12.2.3 优先级
    • 12.3 嵌套路由
    • 12.4 编程式导航
      • 12.4.1 push()
      • 12.4.2 push() 参数
      • 12.4.3 replace()
      • 12.4.4 go()
    • 12.5 命名路由
    • 12.6 命名视图
    • 12.7 重定向
      • 12.7.1 重定向
      • 12.7.2 路由别名
    • 12.8 路由组件传参

一、vue 的简介

在这里插入图片描述

1.1 使用 JQuery 的复杂性问题

  • 使用 JQuery 进行前后端分离开发,既可以实现前后端交互 (ajax) ,又可以完成数据渲染
  • 存在的问题: JQuery 需要通过 HTML 标签拼接、DOM 节点操作完成数据的显示,开发效率低且容易出错,渲染效率较低
  • vue 是继 JQuery 之后的又一优秀的前端框架:专注于前端数据的渲染 ———— 语法简单、渲染效率高

1.2 VUE 简介

1.2.1 前端框架

  • 前端三框架:HTML、CSS、JavaScript

    • HTML 决定网页结构
    • CSS 决定显示效果
    • JavaScript 决定网页功能 (交互、数据显示)
  • UI 框架:(只提供样式、显示效果)

    • Bootstrap
    • amazeUI
    • Layui
  • JS 框架:

    • JQuery (JQuery UI)
    • React
    • angular
    • nodejs ---- 后端开发
    • vue 集各种前端框架的优势发展而来

1.2.2 MVVM

项目结构经历的三个阶段:

后端 MVC :可以理解为单体结构,流程控制是由后端控制器来完成

前端 MVC :前后端分离开发,后端只负责接收响应请求

MVVM是MVC的增强版,实质上和MVC没有本质区别,只是代码的位置变动而已

MVVM 前端请求后端接口,后端返回数据,前端接收数据,并将接收到的数据设置为 “VM”,HTML 从 vm 取值

  • M model 数据模型,指的是后端接口返回的数据
  • V view 视图
  • VM ViewModel 视图模型 数据模型与视图之间的桥梁,后端返回的 model 转换前端所需的 vm,视图层可以直接从 vm 中提取数据

在这里插入图片描述

Model-View-ViewModel —— 概念图

二、 vue 入门使用

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

2.1 vue 的引入

  • 离线引用:下载 vue 的 js 文件,添加到前端项目,在网页中通过 script 标签引用 vue.js 文件

  • CDN 引用:

    直接使用在线 CDN 的方式引入

<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

2.2 入门案例 – Hello World

文本:数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:{{message}}

  1. 创建一个 HTML 文件

  2. 引入 vue.js 文件

    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    
  3. 示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 引入vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="app-1">
        从 0 开始: {{message}}
    </div>


    <script type="text/javascript">
        var vm = new Vue({
            el: '#app-1',
            data: {
                message: 'Hello World!'
            }
        })

    </script>
</body>
</html>

在这里插入图片描述

Mustache 标签将会被替代为对应数据对象上 message property 的值。无论何时,绑定的数据对象上 message property 发生了改变,插值处的内容都会更新。

三、 vue 的语法

3.1 基本类型数据和字符串

<div id="app-2">
    {{code}}
    从 0 开始: {{message}}
</div>


<script type="text/javascript">
    var vm = new Vue({
        el: '#app-2',
        data: {
            code: 1_3_3,
            message: 'Hello World!'
        }
    })

</script>

在这里插入图片描述

3.2 对象类型数据

  • 支持 ognl 语法
<div id="app-3">
    学号:{{stu.stuNum}} <br />
    姓名:{{stu.stuName}} <br />
    性别:{{stu.stuGender}} <br />
    年龄:{{stu.stuAge}}
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app-3',
        data: {
            stu: {
                stuNum: '10001',
                stuName: '张三',
                stuGender: 'M',
                stuAge: 20
            }
        }
    })

</script>

在这里插入图片描述

3.3 条件 v-if

v-if : 用来控制切换一个元素是否显示 (底层控制是 DOM 元素,操作 DOM)

注:在浏览器中网页打开这个文件 F12,从标签上可以看到没有 stu.stuGender == 'F' 对应的元素。即条件不成立,网页不会渲染该 DOM,连标签都不会有。

<div id="app-4">
    学号:{{stu.stuNum}} <br />
    姓名:{{stu.stuName}} <br />
    性别:
    <label v-if="stu.stuGender == 'M'"></label>
    <label v-if="stu.stuGender == 'F'"></label>
    <br />
    年龄:{{stu.stuAge}}

</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app-4',
        data: {
            stu: {
                stuNum: '10001',
                stuName: '张三',
                stuGender: 'M',
                stuAge: 20
            }
        }
    })

</script>

在这里插入图片描述

3.4 循环 v-for

v-for 指令基于一个数组来渲染一个列表。

v-for 块中,我们可以访问所有父作用域的 property。v-for 还支持一个可选的第二个参数,即当前项的索引。

<div id="app-5">
    <table border="1" cellspacing="0" width="400">
        <tr>
            <th>序号</th>
            <th>学号</th>
            <th>姓名</th>
            <th>性别</th>
            <th>年龄</th>
        </tr>
        <tr v-for="(stu, index) in stus">
            <td>{{index + 1}}</td>
            <td>{{stu.stuNum}}</td>
            <td>{{stu.stuName}}</td>
            <td>
                <table v-if="stu.stuGender == 'M'"></table>
                <table v-if="stu.stuGender == 'F'"></table>
            </td>
            <td>{{stu.stuAge}}</td>

        </tr>
    </table>

</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app-5',
        data: {
            stus: [
                {
                    stuNum: '10001',
                    stuName: '张三',
                    stuGender: 'M',
                    stuAge: 20
                },
                {
                    stuNum: '10002',
                    stuName: '李四',
                    stuGender: 'M',
                    stuAge: 23
                },
                {
                    stuNum: '10003',
                    stuName: '郑红',
                    stuGender: 'F',
                    stuAge: 19
                }
            ]
        }
    })

</script>

在这里插入图片描述

3.5 绑定标签属性 v-bind

  • v-bind:属性名 缩写:属性名
<div id="app-6">
    <input type="text" v-bind:value="message">
    <hr /><br />
    <table border="1" cellspacing="0" width="400">
        <tr>
            <th>序号</th>
            <th>学号</th>
            <th>姓名</th>
            <th>性别</th>
            <th>年龄</th>
        </tr>
        <tr v-for="(stu, index) in stus">
            <td>{{index + 1}}</td>
            <td>{{stu.stuNum}}</td>
            <td><img height="30" :src="stu.stuImg" /> </td>
            <td>{{stu.stuName}}</td>
            <td>
                <table v-if="stu.stuGender == 'M'"></table>
                <table v-if="stu.stuGender == 'F'"></table>
            </td>
            <td>{{stu.stuAge}}</td>

        </tr>
    </table>

</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app-6',
        data: {
            message: 'Hello World!!',
            stus: [
                {
                    stuNum: '10001',
                    stuName: '张三',
                    stuGender: 'M',
                    stuAge: 20,
                    stuImg: 'img/1.jpg'
                },
                {
                    stuNum: '10002',
                    stuName: '李四',
                    stuGender: 'M',
                    stuAge: 23,
                    stuImg: 'img/2.jpg'
                },
                {
                    stuNum: '10003',
                    stuName: '郑红',
                    stuGender: 'F',
                    stuAge: 19,
                    stuImg: 'img/3.jpg'
                }
            ]
        }
    })

</script>

在这里插入图片描述

3.6 表单标签的双向绑定 v-model

  • 只能使用在表单输入标签
  • v-model:value 可以简写为 v-model
<div id="app-7">
    <input type="text" v-model="message">
    <hr /><br />
    双向绑定:{{message}}

</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app-7',
        data: {
            message: 'Hello World!!'
        }
    })

</script>

四、vue 实例

每个使用 vue 进行数据渲染的网页文档都需要创建一个 vue 实例 — — ViewModel

4.1 vue 实例的生命周期

vue 实例生命周期 — — vue 实例从创建到销毁的过程

在这里插入图片描述

  • 创建 vue 实例 (初始化 data,加载 el)
  • 数据挂载 (将 vue 实例 data 中的数据渲染到网页 HTML 标签)
  • 重新渲染 (当 vue 的 data 数据发生变化,会重新渲染到 HTML 标签)
  • 销毁实例

创建对象 ---- 属性初始化 ---- 获取属性值 ----- GC 回收

4.2 钩子函数

为了便于开发者在 vue 实例生命周期的不同阶段进行特定的操作,vue 在生命周期四个阶段的前后分别提供了一个函数,这个函数无需开发者调用,当 vue 实例到达生命周期的指定阶段会自动调用对应的函数。

<div id="app-8">
    <label v-once>{{message}}</label><br />
    <label>{{message}}</label><br />
    <input type="text" v-model="message">

</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app-8',
        data: {
            message: 'Hello World!!'
        },
        beforeCreate: function () {
            // 1. data 初始化之前执行,不能操作 data
        },
        create: function () {
            // 2. data 初始化之后执行,模板加载之前,可以修改 / 获取 data 中的值
            console.log(this.message);
            // this.message = 'Hello World!! create()';
        },
        beforeMount: function () {
            // 3. 模板加载之后,数据初始渲染(挂载)之前,可以修改 / 获取 data 中的值
            // this.message = 'Hello World!!  beforeMount';
        },
        mounted: function () {
            // 4. 数据初始渲染(挂载)之后,可以对 data 中的变量进行修改,但是不会影响 v-once 的渲染
            // this.message = "Hello World!!  mounted";
        },
        beforeUpdate: function () {
            // 5. 数据渲染之后,当 data 中的数据发生变化触发重新渲染,渲染之前执行此函数
            console.log("---" + this.message);
            this.message = 'Hello World!!  beforeUpdate';
        },
        update: function () {
            // 6. data 数据被修改之后,重新渲染到页面之后
            // this.message = "Hello World!!   update";
        },
        beforeDestroy: function () {
            // 7. 实例销毁之前
        },
        destroy: function () {
            // 8. 实例销毁之后
        }
    })

</script>

五、 计算属性和侦听器

5.1 计算属性

data 中的属性可以通过声明获得,也可以通过在 computed 计算属性的 getter 获得

特性:计算属性所依赖的属性值发生变化会影响计算属性的值同时发生变化

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app-9">
        <input type="text" v-model="message1"><br />
        <input type="text" v-model="message2"><br />
        {{message3}}
    </div>


    <script type="text/javascript">
        var vm = new Vue({
            el: '#app-9',
            data: {
                message1: 'Hello',
                message2: 'World'
            },
            computed: {
                message3: function () {
                    return this.message1 + this.message2;
                }
            }
        })

    </script>
</body>
</html>

5.2 侦听器

侦听器,就是 data 中属性的侦听器,当 data 中的属性值发生变化就会触发侦听器函数的执行

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app-10">
        <input type="text" v-model="message1"><br />
        <input type="text" v-model="message2"><br />
        {{message3}}
    </div>


    <script type="text/javascript">
        var vm = new Vue({
            el: '#app-10',
            data: {
                message1: 'Hello',
                message2: 'World',
                message3: 'Hello World'
            },
            watch: {
                message1: function () {
                    this.message3 = this.message1 + this.message2;
                },
                message2: function () {
                    this.message3 = this.message1 + this.message2;
                }
            }
        })

    </script>
</body>
</html>

六、class 与 style 绑定

6.1 class 绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .my-style1 {
            width: 200px;
            height: 100px;
            background: orange;
        }
        .my-style2 {
            border-radius: 10px;
        }
        .my-style3 {
            width: 200px;
            height: 100px;
            background: black;
        }
    </style>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app-11">
        <!-- 如果 message1 为 true, 就加载 my-style1,如果 message2 为 true, 就加载 my-style2  -->
        <div :class="{'my-style1': message1, 'my-style2' : message2}">
        </div><hr />
        <!-- 为 class 属性加载多个样式名 -->
        <div :class="[booleanValue1, booleanValue2]">
        </div><hr />
        <!-- 如果 message3 为 true, 则 class = 'my-style3',否则 class = 'my-style1'
        如果在三目运算中使用样式名则需要加单引号,不加单引号则表示从 data 变量中获取样式名
        -->
        <div :class="[message3 ? 'my-style3' : 'my-style1']">
        </div>
        <div :class="[message1 ? booleanValue1 : booleanValue3]"></div>
    </div>


    <script type="text/javascript">
        var vm = new Vue({
            el: '#app-11',
            data: {
                message1: true,
                message2: true,
                message3: true,
                booleanValue1: "my-style1",
                booleanValue2: "my-style2",
                booleanValue3: "my-style3"
            }
        })

    </script>
</body>
</html>

在这里插入图片描述

6.2 style 绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app-12">
        <!-- 当使用 v-bind 绑定内联样式时:
            1. 使用 {} 定义 style 样式,才能获取 data 的值, {} 要遵循 JSON 格式
            2. {} 中不在使用 style 样式属性名 “font-size”, 而要使用对应的 js 属性名
            border-style-width --- borderStyleWidth
         -->
        <div v-bind:style="{color: colorName, fontSize: fontsize + 'px' }">
            Hello World!
        </div>
        <!-- 我们可以直接为 style 属性绑定一个 data 中定义好的内联样式的字符串 -->
        <div v-bind:style="myStyle1">
            Hello World!!
        </div>
        <!-- 我们可以直接为 style 属性绑定一个 data 中定义好的内联样式的对象 -->
        <div v-bind:style="myStyle2">
            Hello World!!!
        </div>
        <!-- 我们可以在同一个 style 属性通过数组引用多个内联样式的对象 -->
        <div v-bind:style="[myStyle2, myStyle3]">
            Hello World!!!!
        </div>
    </div>


    <script type="text/javascript">
        var vm = new Vue({
            el: '#app-12',
            data: {
                colorName: "yellow",
                fontsize: "40",
                myStyle1: "color: orange; font-size: 50px",
                myStyle2: {
                    color: "blue",
                    fontSize: "60px"
                },
                myStyle3: {
                    textShadow: "orange 3px 3px 5px"
                }
            }
        })

    </script>
</body>
</html>

在这里插入图片描述

七、条件与列表渲染

7.1 条件渲染

条件判断语句:

  • v-if
  • v-else-if
  • v-else

7.1.1 v-if

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app-13">
        <h3 v-if="code == 1">Hello :可以看到</h3>
        <h3 v-if="flag">flag 为 true, 可以看到</h3>
    </div>


    <script type="text/javascript">
        var vm = new Vue({
            el: '#app-13',
            data: {
                code: 1,
                flag: false
            }
        })

    </script>
</body>
</html>

在这里插入图片描述

7.1.2 v-else

v-else 指令来表示 v-if 的“else 块”

    <div id="app-13">
        <!-- v-else 标签需要紧跟在 v-if 的标签之后,中间不能有其他标签, 否则它将不会被识别 -->
        <h3 v-if="code == 1">Hello :可以看到</h3>
        <h3 v-else>World :可以看到</h3>
    </div>


    <script type="text/javascript">
        var vm = new Vue({
            el: '#app-13',
            data: {
                code: 1
            }
        })

    </script>

7.1.3 v-else-if

    <div id="app-13">
        分数 {{code}}
        对应的等级:
        <h3 v-if="code >= 90">优秀</h3>
        <h3 v-else-if="code >= 80">良好</h3>
        <h3 v-else-if="code >= 70">中等</h3>
        <h3 v-else-if="code >= 60">及格</h3>
        <h3 v-else>挂科</h3>
    </div>


    <script type="text/javascript">
        var vm = new Vue({
            el: '#app-13',
            data: {
                code: 85
            }
        })
    </script>

在这里插入图片描述

7.1.4 v-show

v-show :同样用于根据条件展示元素。

从功能上 v-show 与 v-if 作用是相同的,只是渲染过程有区别。

v-if 与 v-show 的区别:

  • v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
  • v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
  • 相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
  • 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

7.2 列表渲染

编码过程中,发现网页出现报错:

Uncaught Error: Bootstrap's JavaScript requires jQuery at bootstrap.min.js:6

解决方法:在引进JQuery文件时,将其放在 bootstrap 前面即可。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>

    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app-14">
       <ul>
           <li v-for="c in categories">
               <a :href="'query?cid=' + c.cid">{{c.cname}}</a>
           </li>
       </ul>

        <table class="table table-bordered">
            <tr>
                <th>学号</th>
                <th>照片</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
                <th>操作</th>
            </tr>
            <template v-for="(s, index) in stu">
                <tr :id="'tr' + s.stuNum">
                    <td>{{s.stuNum}}</td>
                    <td>
                        <img height="30" :src="s.stuImg" />
                    </td>
                    <td>{{s.stuName}}</td>
                    <td>
                        <!-- {{s.stuGender == 'M' ? '男' : '女'}} -->
                        <img v-if="s.stuGender == 'M'" src="img/m.bmp">
                        <img v-else src="img/f.bmp">
                    </td>
                    <td>{{s.stuAge}}</td>
                    <td>
                        <a class="btn btn-danger" :href="'stu/delete?cid=' + s.stuNum">删除</a>
                        <a class="btn btn-success" :href="'stu/update?cid=' + s.stuNum">修改</a>
                    </td>
                </tr>
            </template>

        </table>
    </div>

    <script type="text/javascript">
        var vm = new Vue({
            el: '#app-14',
            data: {
                categories:[
                    {
                        cid: 1,
                        cname: "华为"
                    },
                    {
                        cid: 2,
                        cname: "小米"
                    },
                    {
                        cid: 3,
                        cname: "OPPO"
                    },
                    {
                        cid: 4,
                        cname: "VIVO"
                    }
                ],
                stu: [
                    {
                        stuNum: "10010",
                        stuImg: "img/1.jpg",
                        stuName: "Tom",
                        stuGender: "M",
                        stuAge: 20
                    },
                    {
                        stuNum: "10011",
                        stuImg: "img/2.jpg",
                        stuName: "Joker",
                        stuGender: "M",
                        stuAge: 21
                    },
                    {
                        stuNum: "10012",
                        stuImg: "img/3.jpg",
                        stuName: "Ling",
                        stuGender: "F",
                        stuAge: 20
                    },
                    {
                        stuNum: "10013",
                        stuImg: "img/1.jpg",
                        stuName: "Jack",
                        stuGender: "F",
                        stuAge: 18
                    },
                ]
            }
        })
    </script>
</body>
</html>

八、事件处理

  • 在使用 vue 进行数据渲染时,如果使用原生 js 事件绑定 (例如 onclick),如果需要获取 vue 实例中的数据并传参则需要通过拼接来完成

  • vue 提供了 v-on 指令用于绑定各种事件 (v-on:click),简化了从 vue 取值的过程,但是触发的方法需要定义在 vue 实例的 methods 中

    <button class="btn btn-danger" v-on:click="doDelete(s.stuNum,s.stuName)">删除</button>
    
    <script type="text/javascript">
        var vm = new Vue({
            el: '#app-15',
            data: {
                stu: [
                    {
                        stuNum: "10010",
                        stuImg: "img/1.jpg",
                        stuName: "Tom",
                        stuGender: "M",
                        stuAge: 20
                    }
                ]
            },
            methods: {
                doDelete: function (sNum, sName) {
                    alert("---delete:" + sNum + " " + sName)
                }
            }
        })
    </script>
    
  • v-on:click 可以简写为 @click

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>

    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app-15">
       <ul>
           <li v-for="c in categories">
               <a :href="'query?cid=' + c.cid">{{c.cname}}</a>
           </li>
       </ul>

        <table class="table table-bordered">
            <tr>
                <th>学号</th>
                <th>照片</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
                <th>操作</th>
            </tr>
            <template v-for="(s, index) in stu">
                <tr :id="'tr' + s.stuNum">
                    <td>{{s.stuNum}}</td>
                    <td>
                        <img height="30" :src="s.stuImg" />
                    </td>
                    <td>{{s.stuName}}</td>
                    <td>
                        <!-- {{s.stuGender == 'M' ? '男' : '女'}} -->
                        <img v-if="s.stuGender == 'M'" src="img/m.bmp">
                        <img v-else src="img/f.bmp">
                    </td>
                    <td>{{s.stuAge}}</td>
                    <td>
                        <button class="btn btn-danger" v-on:click="doDelete(s.stuNum,s.stuName)">删除</button>
                        <button class="btn btn-success" @click="doUpdate" :data-snum="s.stuNum"
                                :data-sname="s.stuName" :data-simg="s.stuImg">修改</button>
                    </td>
                </tr>
            </template>

        </table>
    </div>

    <script type="text/javascript">
        var vm = new Vue({
            el: '#app-15',
            data: {
                categories:[
                    {
                        cid: 1,
                        cname: "华为"
                    },
                    {
                        cid: 2,
                        cname: "小米"
                    },
                    {
                        cid: 3,
                        cname: "OPPO"
                    },
                    {
                        cid: 4,
                        cname: "VIVO"
                    }
                ],
                stu: [
                    {
                        stuNum: "10010",
                        stuImg: "img/1.jpg",
                        stuName: "Tom",
                        stuGender: "M",
                        stuAge: 20
                    },
                    {
                        stuNum: "10011",
                        stuImg: "img/2.jpg",
                        stuName: "Joker",
                        stuGender: "M",
                        stuAge: 21
                    },
                    {
                        stuNum: "10012",
                        stuImg: "img/3.jpg",
                        stuName: "Ling",
                        stuGender: "F",
                        stuAge: 20
                    },
                    {
                        stuNum: "10013",
                        stuImg: "img/1.jpg",
                        stuName: "Jack",
                        stuGender: "F",
                        stuAge: 18
                    },
                ]
            },
            methods: {
                doDelete: function (sNum, sName) {
                    alert("---delete:" + sNum + " " + sName)
                },
                doUpdate: function (event) {
                    // 如果 v-on 绑定的 js 函数没有参数,调用的时候可以省略 (), 同时可以给 js 函数一个 event 参数(事件对象)
                    // 1. event 表示触发当前函数的事件
                    // 2. event.srcElement 表示发生事件的元素 --- 修改按钮
                    // 3. event.srcElement.dataset 表示按钮上绑定的数据集 (data-开头的属性)
                    alert("---update:");
                    let stu = event.srcElement.dataset;
                }
            }
        })
    </script>
</body>
</html>

8.1 使用 JS 函数传值

<button class="btn btn-danger" v-on:click="doDelete(s.stuNum,s.stuName)">删除</button>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app-15',
        data: {
            stu: [
                {
                    stuNum: "10010",
                    stuImg: "img/1.jpg",
                    stuName: "Tom",
                    stuGender: "M",
                    stuAge: 20
                }
            ]
        },
        methods: {
            doDelete: function (sNum, sName) {
                alert("---delete:" + sNum + " " + sName)
            }
        }
    })
</script>

8.2 使用 dataset 对象传值 (推荐)

<button class="btn btn-success" @click="doUpdate" :data-snum="s.stuNum"
                                :data-sname="s.stuName" :data-simg="s.stuImg">修改</button>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app-15',
        data: {
            stu: [
                {
                    stuNum: "10010",
                    stuImg: "img/1.jpg",
                    stuName: "Tom",
                    stuGender: "M",
                    stuAge: 20
                }
            ]
        },
        methods: {
            doUpdate: function (event) {
                    // 如果 v-on 绑定的 js 函数没有参数,调用的时候可以省略 (), 同时可以给 js 函数一个 event 参数(事件对象)
                    // 1. event 表示触发当前函数的事件
                    // 2. event.srcElement 表示发生事件的元素 --- 修改按钮
                    // 3. event.srcElement.dataset 表示按钮上绑定的数据集 (data-开头的属性)
                    alert("---update:");
                    let stu = event.srcElement.dataset;
                }
        }
    })
</script>

8.3 混合使用

有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法

<button class="btn btn-danger" v-on:click="doDelete(s.stuNum,s.stuName, $event)" :data-simg="s.stuImg">删除</button>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app-15',
        data: {
            stu: [
                {
                    stuNum: "10010",
                    stuImg: "img/1.jpg",
                    stuName: "Tom",
                    stuGender: "M",
                    stuAge: 20
                }
            ]
        },
        methods: {
            doDelete: function (sNum, sName, event) {
                alert("---delete:" + sNum + " " + sName)
                console.log(event.srcElement.dataset)
            }
        }
    })
</script>

8.4 事件修饰符

修饰符是由点开头的指令后缀来表示的。

当使用 v-on 进行事件绑定的时候,可以添加特定后缀,设置事件触发的特性

8.4.1 事件修饰符使用示例

<button type="submit" class="btn btn-success" @click.prevent="test">修改</button>

8.4.2 事件修饰符

常用的事件修饰符:

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive

.prevent 用来阻止标签的默认行为

<div id="app-16">
    <form action="https://www.baidu.com">
         <!-- 此处不加 .prevent ,网页会跳转到 https://www.baidu.com -->
        <button type="submit" class="btn btn-success" @click.prevent="test">修改</button>
    </form>
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app-16',
        data: {},
        methods: {

            test: function (event) {
                alert("--test");
            }
        }
    })
</script>

.stop 阻止事件冒泡

.self 设置只能自己触发事件(子标签不能触发)

<div id="app-16">
    <!-- .prevent 示例 -->
    <form action="https://www.baidu.com">
        <!-- 此处不加 .prevent ,网页会跳转到 https://www.baidu.com -->
        <button type="submit" class="btn btn-success" @click层="test">修改</button>
    </form>
    <!-- .stop 示例 .self 示例:只能点击自己触发 -->
    <div style="width: 200px; height: 200px; background: red;" @click.self="outside">
        <div style="width: 100px; height: 100px; background: yellow;" @click="inside">
            <!-- 此处加了 .stop , 网页的外层 div  父标签不会触发 -->
            <button @click.stop="itself">test stop 修饰符</button>
        </div>
    </div>

</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app-16',
        data: {},
        methods: {
            test: function (event) {
                alert("--test");
            },
            inside: function () {
                alert("--inside");
            },
            outside: function () {
                alert("--outside");
            },
            itself: function () {
                alert("--itself");
            }
        }
    })
</script>

.once 限定事件只能触发一次

<!-- .once 示例:test()方法只执行一次, -->
<form action="https://www.baidu.com">
    <!-- 加了 .prevent,第一次点击执行 test(),默认跳转被阻止, 第二次点击按钮,直接跳转, test()不执行 -->
    <button type="submit" class="btn btn-success" @click.prevent.once="test">修改</button>
</form>

8.5 按键修饰符

按键修饰符:针对键盘事件的修饰符,限定哪个按键会触发事件

常用的按键修饰符:

  • .enter
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

.enter 只有在 keyEnter 时调用(触发 enter 按键之后触发事件)

<div id="app-17">
     <input type="text" @keyup.enter="test">
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app-17',
        data: {},
        methods: {
            test: function () {
                alert("enter松开触发")
            }
        }
    })
</script>

还可以通过全局 config.keyCodes 对象自定义按键修饰符别名:

// 输入 按键 j 触发事件 test
<input type="text" @keyup.aaa="test">
// 按键 j 的别名
Vue.config.keyCodes.aaa = 74

8.6 系统修饰符

组合键

示例:CTRL + J 触发事件

<div id="app-17">
    <input type="text" @keyup.ctrl.j="test">
</div>

<script type="text/javascript">
    Vue.config.keyCodes.j = 74
    var vm = new Vue({
        el: '#app-17',
        data: {},
        methods: {
            test: function () {
                alert("enter松开触发")
            }
        }
    })
</script>

常用的修饰符:

  • .ctrl
  • .alt
  • .shift
  • .meta windows 键

九、表单输入绑定

表单输入绑定,即双向绑定:就是能够将 vue 实例的 data 数据渲染到表单输入视图 (input\textarea\select),

也能够将输入视图的数据同步到 vue 实例的 data中。

<div id="app-18">
    <!-- 文本输入框 密码输入框 -->
    <input type="text" v-model="name" /><br />
    <input type="password" v-model="password" />
    <hr />
    <!-- 单选按钮 -->
    <input type="radio" v-model="radioTest" value="A" /> A
    <input type="radio" v-model="radioTest" value="B" /> B
    <input type="radio" v-model="radioTest" value="C" /> C
    <input type="radio" v-model="radioTest" value="D" /> D
    <hr />

    <!-- 复选框,绑定的是一个数组 -->
    <input type="checkbox" v-model="checkBox" value="篮球" /> 篮球 <br />
    <input type="checkbox" v-model="checkBox" value="足球" /> 足球 <br />
    <input type="checkbox" v-model="checkBox" value="羽毛球" /> 羽毛球 <br />
    <input type="checkbox" v-model="checkBox" value="乒乓球" /> 乒乓球 <br />

    <!-- 下拉菜单 select:绑定一个字符串 -->
    <select v-model="city">
        <option value="BJ">北京</option>
        <option value="SH">上海</option>
        <option value="SZ">深圳</option>
        <option value="GZ">广州</option>
    </select>
    <hr />

    <!-- 下拉菜单 select:加上了 multiple ,表示可多选,需要绑定一个数组 -->
    <select v-model="cities" multiple>
        <option value="BJ">北京</option>
        <option value="SH">上海</option>
        <option value="SZ">深圳</option>
        <option value="GZ">广州</option>
    </select>

    <button type="button" @click="test">测试</button>
</div>

<script type="text/javascript">

    var vm = new Vue({
        el: '#app-18',
        data: {
            name: "admin",
            password: "123456",
            radioTest: "C",
            checkBox: [],
            city: "",
            cities: []
        },
        methods: {
            test: function () {
                alert(vm.cities)
            }
        }

    })
</script>

十、组件

10.1 组件介绍及示例

组件,就是讲通用的 HTML 模块进行封装 —— 可复用的 Vue 实例

​ 通常一个应用会以一棵嵌套的组件树的形式来组织:

在这里插入图片描述

10.1.1 组件注册

将通用的 HTML 模块封装注册到 vue 中

自定义组件 my-components.js:

Vue.component('header-button', {
    template: `<div style="width: 100%; height: 80px; background: salmon">
                <table width="100%">
                    <tr>
                        <td width="200" align="right" valign="middle">
                            <img src="img/1.jpg" height="80" />
                        </td>
                        <td>
                            <label style="color: deepskyblue; font-size: 32px; font-family: 'Adobe 楷体 Std R'; margin-left: 30px">
                                登录
                            </label>
                        </td>
                    </tr>
                </table>
            </div>`
});

10.1.2 组件引用

  • 定义组件需要依赖 vue.js,在引用自定义组件 js 文件要先引用 vue.js
  • 组件的引用必须在 vue 实例 el 指定的容器中 ,即要在Vue实例范围内
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>

    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app-19">
        <header-button></header-button>
        <hr />
        <header-button></header-button>
    </div>
    <script src="js/my-components.js"></script>
    <script type="text/javascript">

        var vm = new Vue({
            el: '#app-19'
        })
    </script>
</body>
</html>

在这里插入图片描述

10.2 组件注册

10.2.1 自定义组件的结构

  • Vue.component() 注册组件
  • data 定义组件的模板渲染的数据
  • template 组件的 HTML 模块(HTML 标签 \ CSS 样式)
  • methods 定义组件中的标签事件中绑定的 JS 函数

my-components.js:

Vue.component('header-button', {
    data: function () {
        // 组件中 data 是通过函数返回的对象
        return {
            name: "貂蝉"
        };
    },
    template: `<div style="width: 100%; height: 80px; background: salmon">
                <table width="100%">
                    <tr>
                        <td width="200" align="right" valign="middle">
                            <img src="img/1.jpg" height="80" />
                        </td>
                        <td>
                            <label style="color: deepskyblue; font-size: 32px; font-family: 'Adobe 楷体 Std R'; margin-left: 30px">
                                登录人: {{name}}
                            </label>
                        </td>
                        <td>
                            <button @click="test">组件按钮</button>
                        </td>
                    </tr>
                </table>
            </div>`,
    methods: {
        test: function () {
            alert("组件中 header-button 定义的函数事件")
        }
    }
});

10.2.2 组件的封装

  • 将模板中的 css 样式提取出来,单独封装到 css 文件存储在 css 目录
  • 将模板中的图片存储在 img 目录
  • 将定义组件的 js 文件和 vue 文件存放到 js 目录
Vue 组件封装的结构
在这里插入图片描述

:在编码过程中学到,Vue 中同一个 DOM 元素绑定多个点击事件:可以使用逗号分隔。

10.2.3 组件的复用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="css/my-components.css" />
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>

    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app-19">
        <header-button></header-button>
        <hr />
        <header-button></header-button>
    </div>
    <script src="js/my-components.js"></script>
    <script type="text/javascript">

        var vm = new Vue({
            el: '#app-19'
        })
    </script>
</body>
</html>

10.3 组件通信

vue 实例本身就是一个组件(模板就是 el 指定容器,data 就是组件数据,methods 就是组件的事件函数)

在 vue 实例指定的 el 容器中引用的组件称为子组件,当前 vue 实例就是父组件

注:子组件按钮模板不能触发父组件的方法,子组件的按钮可以触发子组件的方法。

10.3.1 父传子

vue 实例引用组件的时候,传递数据到引用的组件中

通过组件的属性实现父组件传递数据到子组件

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

10.3.2 子传父 – 使用 props 属性动态传递参数

通过子组件的按钮“调用”父组件的函数,通过函数传值

流程示意图
在这里插入图片描述

父组件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="css/my-components.css" />
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app-21">
        <!-- 组件的引用必须在 vue 实例指定的容器中 -->
        <header-bar :name="message" @my-event="parentMethod"></header-bar>
        子组件传到父组件的标题名称: {{title}}
        <hr />
        <header-bar name="关羽"></header-bar>
    </div>
    <script src="js/my-components-bar2.js"></script>
    <script type="text/javascript">

        var vm = new Vue({
            el: '#app-21',
            data: {
                message: "貂蝉",
                title: ""
            },
            methods: {
                parentMethod: function (res) {
                    vm.title = res;
                }
            }
        })
    </script>
</body>
</html>

子组件:

Vue.component('header-bar', {
    data: function() {
        return {
            title: "三国 -- √"
        }
    },
    template: `<div class="divStyle">
                <table class="tableStyle">
                    <tr>
                        <td width="200" align="right" valign="middle">
                            <img src="img/1.jpg" class="logoImg" />
                        </td>
                        <td>
                            <label class="nameStyle">
                                登录人: {{name}}
                            </label>
                        </td>
                        <td>
                            <button @click="childMethod">组件按钮点击次数</button>
                        </td>
                    </tr>
                </table>
            </div>`,
    props: ["name"],
    methods: {
        childMethod: function () {
            this.$emit("my-event", this.title);
        }
    }
});

在这里插入图片描述

10.3.3 总结

父组件通信子组件

  • props: 子组件通过props获取定义父组件传递的自定义属性

  • this.$refs: 引用子组件

  • this.$children: 父组件childrens属性,存储着所有的子组件

子组件通信父组件(或根组件)

  • this.$emit: 子组件通过$emit访问父组件传递的自定义事件

  • this.$parent: 访问父组件

  • this.$root: 访问根组件。根组件root就是new Vue({el: "#app"}); 中的el元素

10.4 组件插槽

当我们自定义 vue 组件时,允许组件中的部分内容在调用组件时进行定义 —— 插槽

10.4.1 插槽的使用

  • 在自定义组件时通过 slot 标签在组件的模板中定义插槽

my-components-bar-slot.js:

Vue.component('header-bar', {
    data: function() {
        return {
            title: "三国 -- √"
        }
    },
    template: `<div class="divStyle">
                <table class="tableStyle">
                    <tr>
                        <td width="200" align="right" valign="middle">
                            <img src="img/1.jpg" class="logoImg" />
                        </td>
                        <td>
                            <label class="nameStyle">
                                登录人: {{name}}
                            </label>
                        </td>
                        <td>
                            <slot></slot>
                        </td>
                        <td>
                            <button @click="childMethod">组件按钮点击次数</button>
                        </td>
                    </tr>
                </table>
            </div>`,
    props: ["name"],
    methods: {
        childMethod: function () {
            this.$emit("my-event", this.title);
        }
    }
});
  • 在父组件中调用此组件时,指定插槽填充的模板

示例1:插槽填充 搜索框

<header-bar :name="message">
     <input /> <button>搜索</button>
</header-bar>

在这里插入图片描述

示例2:插槽填充 按钮

<header-bar :name="message" @my-event="parentMethod">
     <div>
         <a href="#">首页</a>
         <a href="#">后台</a>
         <a href="#">管理</a>
         <a href="#">关于</a>
     </div>
</header-bar>

在这里插入图片描述

10.4.2 具名插槽

当组件中的插槽数量 > 1 时,需要给组件中的 slot 标签添加 name 属性指定插槽的名字

  • 定义组件
Vue.component('page-frame', {
    template:  `<div>
            <div id="header" style="width: 100%; height: 100px; background: pink">
                {{title}}<br />
                slot1 : <br />
                <slot name="slot1"></slot>
            </div>
            <div style="width: 100%; height: 580px">
                slot2 : <br />
                <slot name="slot2"></slot>
            </div>
            <div id="footer" style="width: 100%; height: 40px; background: lightblue">{{cr}}</div>
        </div>`,
    props: ["title", "cr"]
});
  • 引用组件
<div id="app-22">
     <!-- 组件的引用必须在 vue 实例指定的容器中 -->
     <page-frame title="标题" cr="地址">
         <template slot="slot1">
             <input /> <button>搜索</button>
         </template>
         <template slot="slot2">
             <div>
                 <a href="#">首页</a>
                 <a href="#">后台</a>
                 <a href="#">管理</a>
                 <a href="#">关于</a>
             </div>
         </template>
     </page-frame>
</div>

10.4.3 插槽作用域

  • 定义组件时,将组件中的数据绑定到 slot 标签

my-components-bar-slot.js:

Vue.component('page-frame-scope', {
    template:  `<div>
            <div id="header" style="width: 100%; height: 100px; background: pink">
                {{title}}<br />
                slot1 : <br />
                <slot name="slot1"></slot>
            </div>
            <div style="width: 100%; height: 580px">
                slot2 : <br />
                <slot name="slot2" v-bind:sites="sites"></slot>
            </div>
            <div id="footer" style="width: 100%; height: 40px; background: lightblue">{{cr}}</div>
        </div>`,
    props: ["title", "cr"],
    data: function () {
        return {
            sites: [
                {
                    "name": "菜鸟教程",
                    "url": "www.runoob.com"
                },
                {
                    "name": "google",
                    "url": "www.google.com"
                },
                {
                    "name": "微博",
                    "url": "www.weibo.com"
                }
            ]
        }
    }
});
  • 引用组件时,在填充插槽的模板上使用 slot-scopt 属性获取插槽绑定的值
<page-frame-scope title="标题" cr="地址">
    <template slot="slot1">
        <input /> <button>搜索</button>
    </template>
    <template slot="slot2" slot-scope="res">
        <table class="table table-bordered">
            <tr>
                <th>名称</th>
                <th>网站</th>
            </tr>
            <tr v-for="site in res.sites">
                <td>{{site.name}}</td>
                <td>{{site.url}}</td>
            </tr>
        </table>
    </template>
</page-frame-scope>

十一、axios 异步通信

11.1 axios 介绍

vue 可以实现数据的渲染,但是如何获取数据呢?

vue 本身不具备通信能力,通常结合 axios —— 一个专注于异步通信的 js 框架来使用(Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求。)

  • axios 数据通信
  • vue 数据渲染
  • 什么是 axios ?

​ Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

  • 菜鸟教程 axios 说明文档:https://www.runoob.com/vue2/vuejs-ajax-axios.html
  • 中文文档:http://www.axios-js.com/

11.2 axios 入门使用

  • axios —— 实现步骤复杂
  • JQuery 笨重
  • axios 简洁、高效,对 RESTful 支持良好

11.3 axios 异步请求方法

axios 提供了多种异步请求方法,实现对 RESTful 风格的支持

11.3.1 GET 格式的请求

  • axios.get(url).then(function);

    • 使用 response.data 读取 JSON 数据:

      axios
          .get('json/json_demo.json')
          .then(response => (this.info = response.data.sites))
          .catch(function (error) {
          console.log(error)
      })
      
  • axios.get(url,{}).then(function);

    • GET 方法传递参数格式 (使用 axios 的 get 请求传递参数,需要将参数设置在 params 下)

      // 直接在 URL 上添加参数 ID=12345
      axios.get('/user?ID=12345')
        .then(function (response) {
          console.log(response);
        })
        .catch(function (error) {
          console.log(error);
        });
       
      // 也可以通过 params 设置参数:
      axios.get('/user', {
          params: {
            ID: 12345
          }
        })
        .then(function (response) {
          console.log(response);
        })
        .catch(function (error) {
          console.log(error);
        });
      

11.3.2 POST 格式的请求

  • axios.post(url, {}).then(function);

    • axios
          .post("https://localhost:9098/blog/upload", {
          name: "张三",
          age: "20"
      
      })
          .then(response => (this.info2 = response))
          .catch(function (error) {
          console.log(error)
      })
      

11.3.3 自定义请求

自定义请求:自定义请求方式、请求参数、请求头、请求体(post)

axios({
    url: "https://localhost:9098/blog/upload",
    method: "post",
    params: {
        // 设置请求行传值
        name: "张三",
        limit: 15
    },
    headers: {
        // 设置请求头
    },
    data: {
        // 设置请求体 (post / put)
    }
}).then(function (res) {
    console.log(res)
});

11.3.4 请求方法别名

  • axios.request(config)
  • axios.get(url[, config])
  • axios.delete(url[, config])
  • axios.head(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • axios.patch(url[, data[, config]])

当使用别名方法时,不需要在config中指定url,method和data属性。

11.4 并发请求

axios.all()、axios.spread() 两个辅助函数用于处理同时发送多个请求,可以实现在多个请求都完成后再执行一些逻辑。

处理并发请求的助手函数:

  • axios.all(iterable)
  • axios.spread(callback)
<div id="app-25">
    <button type="button" @click="test">测试</button>
</div>

<script type="text/javascript">

    var vm = new Vue({
        el: "#app-25",
        data: {
        },
        methods: {
            test: function () {
                // 发送异步请求
                axios
                    .all([f1(), f2()])
                    .then(axios.spread(function (res1, res2) {
                    // 两个请求都要执行完毕
                    console.log("所有请求都完成")
                    console.log(res1);
                    console.log(res2);
                }));
            }
        }
    });
    function f1() {
        console.log('调用第一个接口')
        return axios.get("json/json_demo.json");
    }
    function f2() {
        console.log('调用第二个接口')
        return axios.get("json/json_demo2.json");
    }
</script>

注:两个请求执行完成后,才执行 axios.spread() 中的函数,且 axios.spread() 回调函数的的返回值中的请求结果的顺序和请求的顺序一致

F12 查看控制台输出情况

在这里插入图片描述

11.5 箭头函数

11.5.1 axios 回调函数的参数 res

res 并不是接口返回的数据,而是表示一个响应数据:res.data 才表示接口响应的数据

11.5.2 箭头函数

<script type="text/javascript">
    var vm = new Vue({
        el: "#app-24",
        data: {
            songs: ""
        },
        methods: {
            test4: function () {
                // 发送异步请求
                axios
                    .get("json/json_demo2.json")
                    .then((res) => {
                    // res 并不是接口返回的数据,而是表示一个响应数据:res.data 才表示接口响应的数据
                    this.songs = res.data;
                    console.log(res.data)
                })
            }
        }
    })
</script>

十二、 路由 router

router 是由 vue 官方提供的用于实现组件跳转的插件。

Vue Router 是 Vue.js (opens new window)官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。

12.1 路由插件的引用

12.1.1 离线

12.1.2 在线 CDN

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

当你要把 Vue Router 添加进来,我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        body {
            padding: 0px;
            margin: 0px;
        }
        ul {
            list-style: none;
        }
        ul li {
            display: inline;
            float: left;
            margin-left: 15px;
        }

    </style>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
    <div id="app-26">
        <div style="width: 100%; height: 70px; background: #00BFFF;">
            <table>
                <tr>
                    <td>
                        <img src="img/1.jpg" height="70" style="margin-left: 100px;" />
                    </td>
                    <td>
                        <ul>
                            <li>
                                <router-link to="/index">首页</router-link>
                            </li>
                            <li>
                                <router-link to="/java">Java</router-link>
                            </li>
                            <li>
                                <router-link to="/python">Python</router-link>
                            </li>
                            <li>
                                <router-link to="/vue">Vue</router-link>
                            </li>
                        </ul>
                    </td>
                </tr>
            </table>
        </div>
        <div style="width: 100%; height: 680px; background: salmon;">
            <router-view></router-view>
        </div>
    </div>

    <script type="text/javascript">
        <!-- vue 的路由旨在为单页面应用开发提供便携 -->
        // 定义链接跳转的模板(组件)
        const t1 = {
            template: `<p align="center">index</p>`
        };
        const t2 = {
            template: `<p align="center" >Java</p>`
        };
        const t3 = {
            template: `<p align="center">Python</p>`
        };
        const t4 = {
            template: `<p align="center">Vue</p>`
        };
        const my_router = new VueRouter({
           routes: [
               {
                   path: '/index',
                   component: t1
               },
               {
                   path: '/java',
                   component: t2
               },
               {
                   path: '/python',
                   component: t3
               },
               {
                   path: '/vue',
                   component: t4
               }
           ]
        });
        var vm = new Vue({
           el: '#app-26',
            router: my_router
        });
    </script>

</body>
</html>

点击链接,根据路由,跳转并显示对应的组件模板

在这里插入图片描述

在这里插入图片描述

12.2 动态路由匹配

12.2.1 通配符

* 可以匹配任意路径

例如:

  • /user-* 匹配所有以 user-开头的任意路径
  • /* 匹配所有路径
const my_router = new VueRouter({
    routes: [
        {
            path: '/user-*',
            component: t4
        },
        {
            path: '/*',
            component: t5
        }
    ]
});

注意:如果使用通配符定义路径,需要注意路由声明的顺序

12.2.2 路由参数

  • /index/:id 可以匹配/index/开头的路径
<div id="app-27">
	<router-link to="/index/101">首页</router-link>
	<router-view></router-view>
</div>

<script type="text/javascript">
    <!-- vue 的路由旨在为单页面应用开发提供便携 -->
    // 1. 定义链接跳转的模板(组件)
    const t1 = {
        template: `<p align="center">index {{$route.params.id}}</p>`
    };
    
    // 2. 定义路由
    const my_router = new VueRouter({
        routes: [
            {
                path: '/index/:id',
                component: t1
            }
        ]
    });
    // 3. 引用路由
    var vm = new Vue({
        el: '#app-27',
        router: my_router
    });
</script>

在这里插入图片描述

12.2.3 优先级

如果一个路径匹配了多个路由,则按照路由的配置顺序:路由定义的越早优先级就越高。

12.3 嵌套路由

在一级路由的组件中显示二级路由

<div id="app-28">
    <div style="width: 100%; height: 20px; background: #00BFFF;">
        <router-link to="/index">首页</router-link>
        <router-link to="/index/t2">首页-t2</router-link>
        <router-link to="/index/t3">首页-t3</router-link>
        <router-view></router-view>
    </div>
</div>

<script type="text/javascript">
    <!-- vue 的路由旨在为单页面应用开发提供便携 -->
    // 1. 定义链接跳转的模板(组件)
    const t1 = {
        template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >
                    index
                    <hr />
                    <router-view></router-view>
    </div>`
    };
    const t2 = {
        template: `<div>t2</div>`
    };
    const t3 = {
        template: `<div>t3</div>`
    };

    // 2. 定义路由
    const my_router = new VueRouter({
        routes: [
            {
                path: '/index',
                component: t1,
                children: [
                    {
                        path: "t2",
                        component: t2
                    },
                    {
                        path: "t3",
                        component: t3
                    }
                ]
            },

        ]
    });
    // 3. 引用路由
    var vm = new Vue({
        el: '#app-28',
        router: my_router
    });
</script>

12.4 编程式导航

12.4.1 push()

<div id="app-29">
    <div style="width: 100%; height: 20px; background: #00BFFF;">
        <!-- <router-link to="/index">首页</router-link> -->
        <button type="button" @click="test">首页按钮</button>
        <router-view></router-view>
    </div>
</div>

<script type="text/javascript">
    <!-- vue 的路由旨在为单页面应用开发提供便携 -->
    // 1. 定义链接跳转的模板(组件)
    const t1 = {
        template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >
                    index
    </div>`
    };


    // 2. 定义路由
    const my_router = new VueRouter({
        routes: [
            {
                path: '/index',
                component: t1
            }
        ]
    });
    // 3. 引用路由
    var vm = new Vue({
        el: '#app-29',
        router: my_router,
        methods: {
            test: function () {
                // js 代码实现路由跳转,编程式导航
                my_router.push("/index");
            }
        }
    });
</script>

12.4.2 push() 参数

// 1. 字符串
my_router.push("/index");

// 2. 对象
my_router.push({path: "/index"});

// 3. 命名的路由 name 参数指的是定义路由时指定的名字
my_router.push({name: "r1", params: {id: 101}});

// 4. URL 传值,相当于 /index?id=101
my_router.push({path: "/index", query: {id: 101}});

12.4.3 replace()

功能与 push() 一致,区别在于 replace() 不会向 history 添加新的浏览记录

12.4.4 go()

参数为一个整数,表示在浏览器历史记录中前进或后退多少步 相当于 windows.history.go(-1) 的作用

12.5 命名路由

命名路由:在定义路由的时候可以给路由指定 name,我们在进行路由导航时可以通过路由的名字导航

 <div id="app-30">
     <div style="width: 100%; height: 20px; background: #00BFFF;">
         <input type="text" v-model="rName" />
         <router-link :to="{name: rName}">t1</router-link>
         <button type="button" @click="test">首页按钮2</button>
         <router-view></router-view>
     </div>
</div>

<script type="text/javascript">
    <!-- vue 的路由旨在为单页面应用开发提供便携 -->
    // 1. 定义链接跳转的模板(组件)
    const t1 = {
        template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >
                    t1
    </div>`
    };
    const t2 = {
        template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >
                    t2
    </div>`
    };


    // 2. 定义路由
    const my_router = new VueRouter({
        routes: [
            {
                path: '/index',
                name: "r1",
                component: t1
            },
            {
                path: '/index2',
                name: "r2",
                component: t2
            }
        ]
    });
    // 3. 引用路由
    var vm = new Vue({
        el: '#app-30',
        data: {
            rName: "r1"
        },
        router: my_router,
        methods: {
            test: function () {
                // js 代码实现路由跳转,编程式导航
                my_router.push({name: vm.rName});

            }
        }
    });
</script>

12.6 命名视图

<div id="app-31">
    <div style="width: 100%; height: 20px; background: #00BFFF;">
        <router-link to="/index">t1</router-link>
        <router-link to="/index2">t2</router-link>
        <!-- 路由视图 -->
        <!-- 如果在 HTML 中有一个以上的路由视图 router-view,需要给 router-view 指定 name,
在路由中需要使用 components 映射多个组件根据 name 设置组件与 router-view 的绑定关系 -->
        <router-view name="v1"></router-view>
        <router-view name="v2"></router-view>
    </div>
</div>

<script type="text/javascript">
    <!-- vue 的路由旨在为单页面应用开发提供便携 -->
    // 1. 定义链接跳转的模板(组件)
    const t11 = {
        template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >
                    t11
    </div>`
    };
    const t12 = {
        template: `<div style="width: 400px; height: 200px; border: red 1px solid" >
                    t12
    </div>`
    };
    const t21 = {
        template: `<div style="width: 400px; height: 200px; border: yellow 1px solid" >
                    t21
    </div>`
    };
    const t22 = {
        template: `<div style="width: 400px; height: 200px; border: wheat 1px solid" >
                    t22
    </div>`
    };


    // 2. 定义路由
    const my_router = new VueRouter({
        routes: [
            {
                path: '/index',
                components: {
                    v1: t11,
                    v2: t12
                }
            },
            {
                path: '/index2',
                components: {
                    v1: t21,
                    v2: t22
                }
            }
        ]
    });
    // 3. 引用路由
    var vm = new Vue({
        el: '#app-31',
        data: {
            rName: "r1"
        },
        router: my_router,
        methods: {
            test: function () {
                // js 代码实现路由跳转,编程式导航
                my_router.push({name: vm.rName});

            }
        }
    });
</script>

12.7 重定向

12.7.1 重定向

访问 /index, 重定向到 /login

<div id="app-32">
    <router-link to="/login">登录</router-link>
    <router-link to="/index">首页</router-link>
    <router-view></router-view>
</div>

<script type="text/javascript">
    <!-- vue 的路由旨在为单页面应用开发提供便携 -->
    // 1. 定义链接跳转的模板(组件)
    const t1 = {
        template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >
                    登录
    </div>`
    };
    // 2. 定义路由
    const my_router = new VueRouter({
        routes: [
            {
                path: '/login',
                component: t1
            },
            {
                path: '/index',
                redirect: "/login"
            }
        ]
    });
    // 3. 引用路由
    var vm = new Vue({
        el: '#app-32',
        router: my_router
    });
</script>
  • 根据路由命名重定向
// 2. 定义路由
const my_router = new VueRouter({
    routes: [
        {
            path: '/login',
            name: "r1",
            component: t1
        },
        {
            path: '/index',
            // 根据路由路径重定向
            // redirect: "/login"
            // 根据路由命名重定向
            redirect: {name: "r1"}
        }
    ]
});

12.7.2 路由别名

<div id="app-32">
    <router-link to="/login">登录</router-link><br />
    <router-link to="/alias-login">(别名)-登录</router-link> <br />
    <router-view></router-view>
</div>

<script type="text/javascript">
    const t1 = {
        template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >
                    登录
    </div>`
    };
    // 2. 定义路由
    const my_router = new VueRouter({
        routes: [
            {
                path: '/login',
                alias: "/alias-login",
                component: t1
            }
        ]
    });
    // 3. 引用路由
    var vm = new Vue({
        el: '#app-32',
        router: my_router
    });
</script>

12.8 路由组件传参

可以通过 /url/:attr 方式实现通过路由传值给组件

<div id="app-33">
    <router-link to="/login/101">登录</router-link><br />
    <router-view></router-view>
</div>

<script type="text/javascript">
    const t1 = {
        template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >
                    登录:{{$route.params.id}}
    </div>`
    };
    // 2. 定义路由
    const my_router = new VueRouter({
        routes: [
            {
                path: '/login/:id',
                component: t1
            }
        ]
    });
    // 3. 引用路由
    var vm = new Vue({
        el: '#app-33',
        router: my_router
    });
</script>

通过 props 传参

 <div id="app-33">
     <router-link to="/index/102">首页t2</router-link><br />
     <router-view></router-view>
</div>

<script type="text/javascript">
    const t2 = {
        props:["id"],
        template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >
                    首页t2:{{id}}
    </div>`
    };
    const my_router = new VueRouter({
        routes: [
            {
                path: '/index/:id',
                component: t2,
                props: true
            }
        ]
    });
    // 3. 引用路由
    var vm = new Vue({
        el: '#app-33',
        router: my_router
    });
</script>

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[LeetCode周赛复盘] 第 119 场双周赛20231209

[LeetCode周赛复盘] 第 119 场双周赛20231209 一、本周周赛总结100130. 找到两个数组中的公共元素1. 题目描述2. 思路分析3. 代码实现 100152. 消除相邻近似相等字符1. 题目描述2. 思路分析3. 代码实现 100147. 最多 K 个重复元素的最长子数组1. 题目描述2. 思路分析3. 代码实…

4.8 构建onnx结构模型-Less

前言 构建onnx方式通常有两种&#xff1a; 1、通过代码转换成onnx结构&#xff0c;比如pytorch —> onnx 2、通过onnx 自定义结点&#xff0c;图&#xff0c;生成onnx结构 本文主要是简单学习和使用两种不同onnx结构&#xff0c; 下面以 Less 结点进行分析 方式 方法一&a…

Redis有序集合对象

一.编码 有序集合的编码可以是ziplist或者skiplist。 ziplist编码的有序集合对象使用压缩列表作为底层实现&#xff0c;每一个集合元素使用紧挨在一起的两个压缩列表节点来保存。第一个节点保存元素的成员(member)&#xff0c;而第二个元素则保存元素的分值(score)。 127.0.0.…

Javaweb之 依赖管理的详细解析

04. 依赖管理 4.1 依赖配置 依赖&#xff1a;指当前项目运行所需要的jar包。一个项目中可以引入多个依赖&#xff1a; 例如&#xff1a;在当前工程中&#xff0c;我们需要用到logback来记录日志&#xff0c;此时就可以在maven工程的pom.xml文件中&#xff0c;引入logback的依…

无参RCE [GXYCTF2019]禁止套娃1

打开题目 毫无思绪&#xff0c;先用御剑扫描一下 只能扫出index.php 我们尝试能不能用php伪协议读取flag php://filter/readconvert.base64-encode/resourceindex.php php://filter/readconvert.base64-encode/resourceflag.php 但是页面都回显了429 怀疑是不是源码泄露 用…

【GDB】

GDB 1. GDB调试器1.1 前言1.2 GDB编译程序1.3 启动GDB1.4 载入被调试程序1.5 查看源码1.6 运行程序1.7 断点设置1.7.1 通过行号设置断点1.7.2 通过函数名设置断点1.7.3 通过条件设置断点1.7.4 查看断点信息1.7.5 删除断点 1.8 单步调试1.9 2. GDB调试core文件2.1 设定core文件的…

Qt之QSlider和QProgressBar

Qt之QSlider和QProgressBar 实验结果 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);connect(ui->dial,&QDial::valueChanged,this,&Widget::do_val…

【Oracle】backup备份时报错ORA-19809,ORA-9804

Oracle备份数据库时报错 ORA-19809: limit exceeded for recovery files ORA-19804: cannot reclaim 10305536 bytes disk space from 4385144832 limit 1.清理过时的备份&#xff1a; 使用RMAN删除不再需要的过时备份&#xff0c;以释放空间。执行以下命令&#xff1a; DEL…

win系统一台电脑安装两个不同版本的mysql教程

文章目录 1.mysql下载zip包&#xff08;地址&#xff09;2.解压在你的电脑上&#xff08;不要再C盘和带中文的路径&#xff09;3.创建my.ini文件4.更改环境变量&#xff08;方便使用, 可选&#xff09;5.打包mysql服务6.初始化mysql的data7.启动刚刚打包的服务8.更改密码 1.mys…

普冉(PUYA)单片机开发笔记(8): ADC-DMA多路采样

概述 上一个实验完成了基于轮询的多路 ADC 采样&#xff0c;现在尝试跑一下使用 DMA 的 ADC 多路采样。厂家例程中有使用 DMA 完成单路采样的&#xff0c;根据这个例程提供的模板&#xff0c;再加上在 STM32 开发同样功能的基础&#xff0c;摸索着尝试。 经过多次修改和测试&…

《安富莱嵌入式周报》第328期:自主微型机器人,火星探测器发射前失误故障分析,微软推出12周24期免费AI课程,炫酷3D LED点阵设计,MDK5.39发布

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 更新一期视频教程&#xff1a; 【实战技能】 单步运行源码分析&#xff0c;一期视频整明白FreeRTOS内核源码框架和运行…

解释Spring中一个bean的注入过程

目录 1、定义Bean&#xff1a; XML配置方式&#xff1a; 2、注入方式&#xff1a; 构造器注入&#xff08;Constructor Injection&#xff09;&#xff1a; Setter方法注入&#xff08;Setter Injection&#xff09;&#xff1a; 字段注入&#xff08;Field Injection&…

【AntDB 数据库】国产分布式数据库发展趋势与难点

引言&#xff1a; 日前&#xff0c;为更好地满足亚信科技客户对于数据管理的需求&#xff0c;提高通用型数据库的产品服务能力与业务拓展能力&#xff0c;亚信科技分布式数据库AntDB发布V7.0版本产品&#xff0c;助力运营商核心系统实现全方位的自主可控与业务系统的平稳上线。…

nodejs微信小程序+python+PHP北京地铁票务APP-计算机毕业设计推荐 -安卓

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

web漏洞的攻击及抓取攻击流量

以dvwa靶场为例&#xff0c;使用wireshark抓取攻击流量&#xff0c;并定位关键字段 SQL注入 攻击 在sql注入攻击 1 and 12 union select version(),2#流量特征 在数据包中可以清晰的查看源IP和目的IP 在Wireshark选中Ethernet0网卡 点击Submit&#xff0c;进行抓包 利用…

【STM32】TIM定时器编码器

1 编码器接口简介 Encoder Interface 编码器接口 编码器接口可接收增量&#xff08;正交&#xff09;编码器的信号&#xff0c;根据编码器旋转产生的正交信号脉冲&#xff0c;自动控制CNT自增或自减&#xff0c;从而指示编码器的位置、旋转方向和旋转速度 接收正交信号&#…

达梦数据库dm8守护集群部署手册

环境说明 操作系统&#xff1a;liunx-centos7.6 服务器&#xff1a;3台虚拟机&#xff08;主备数据库各一台&#xff0c;监视器一台(可选)&#xff09; 达梦数据库版本&#xff1a;达梦V8 一、安装前准备工作 参考达梦官方文档&#xff1a;https://eco.dameng.com/documen…

记一次堆内外内存问题的排查和优化

为优化淘宝带宽成本&#xff0c;我们在网关 SDK&#xff08;Java&#xff09;统一使用 ZSTD 替代 GZIP 压缩以获取更高的压缩比&#xff0c;从而得到更小的响应包。具体实现采用官方推荐的 zstd-jni 库。zstd-jni 会调用 zstd 的 c 库。 背景 在性能压测和优化过程中&#xff0…

基于 Gin 的 HTTP 中间人代理 Demo

前面实现的代理对于 HTTPS 流量是进行盲转的&#xff0c;也就是说直接在 TCP 连接上传输 TLS 流量&#xff0c;但是我们无法查看或者修改它的内容。当然了&#xff0c;通常来说这也是不必要的。不过对于某些场景下还是有必要的&#xff0c;例如使用 Fiddler 进行抓包或者监控其…

Git 五分钟教程速度入门

Git 五分钟教程速度入门 分类 编程技术 许多人认为 Git 太混乱&#xff0c;或认为它是一种复杂的版本控制系统&#xff0c;其实不然&#xff0c;这篇文章有助于大家快速上手使用 Git。 入门 使用Git前&#xff0c;需要先建立一个仓库(repository)。您可以使用一个已经存在的…
最新文章