Featured image of post 第一章 Vue 基础

第一章 Vue 基础

Vue 简介

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面(基于数据渲染出用户所看到的页面)的渐进式(使用核心包进行局部模块设计改造,或利用构建工具及插件等进行工程化开发)框架(快速开发中大型项目)。

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

1
2
3
4
5
6
title: '清仓大促',
products: [
    { id: 1, name: '手机', price: '1999元' },
    { id: 2, name: '平板', price: '2999元' },
    { id: 3, name: '电脑', price: '3999元' }
]

软件工具

VScode

下载:Visual Studio Code - Code Editing. Redefined

Node.js

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境(后端)node.js 详解_nodejs-CSDN博客

下载:Node.js 中文网 (nodejs.com.cn)Node.js (nodejs.org)

Vue.js

Vue2官网:Vue2.js (v2.cn.vuejs.org)

Vue3官网:Vue3.js - 渐进式 JavaScript 框架 | Vue3.js (cn.vuejs.org)

引入

实例

① 准备容器(Vue所管理的范围)

1
<div id="app">	</div>

② 引包(开发环境版本 ✔ / 生产环境版本)https://v2.cn.vuejs.org

③ 创建实例

1
const app = new Vue({})

④ 添加配置项=>完成渲染

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="box">
        // 插值表达式
        {{ msg }}
    </div>
    <div id="app">
        <!-- 编写用于渲染的代码 -->
        {{ msg }}
        <h5> {{m1}} </h5>
    </div>

    <script src="/MyPra/vue.js"></script>

    <script>
        // 一旦引入VueJS核心包,在全局环境,就有了Vue构造函数
        const app = new Vue({
            // el建立关联
            el: '#app',
            // data提供数据
            data: {
                msg: 'Hello World',
                m1: 'this is m1'
            }
        })
    </script>
</body>

</html>

插值表达式 ⭐

插值表达式是一种 Vue 的模板语法

① 作用: 利用表达式进行插值,渲染到页面中

​ 表达式:是可以被求值的代码,JS 引擎会将其计算出一个结果

② 语法: {{ 表达式 }}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
## 下列差值表达式,书写正确的有哪些?

<h3>{{ title }}</h3>

<p>{{ nickname.toUpperCase() }}</p>

<p>{{ age >= 18 ? '成年' : '未成年' }}</P>

<p>{{ obj.name }}</p>

<p>{{ if }}</p>

<p title="{{ uesrname }}">HelloWorld</p>

③ 注意点:

​ (1) 使用的数据必须存在

​ (2) 支持的是表达式,而非语句,比如:iffor

​ (3) 不能在标签属性中使用 {{ }} 插值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id='app'>
        <p>{{ m1.toUpperCase() }}</p>
        <p>{{ m1 + " and green" }}</p>
        <p>{{ friend.age - age }}</p>
        <p>{{ name + '和' + friend.name + '是朋友' }}</p>
        <p>{{ friend.gender }}</p>
        <!-- <p>{{ if }}</p> -->
    </div>

    <script src="/MyPra/vue.js"></script>

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                m1: 'red',
                age: '17',
                name: '张三',
                friend: {
                    name: '李四',
                    age: '18',
                    hobby: '篮球'
                }
            }
        })
    </script>
</body>

</html>

练习差值表达式。

Vue 响应式特性

响应式:数据发生变化,视图自动更新

① 访问数据:“实例.属性名”

② 修改数据:“实例.属性名” = “值”

当我们修改数据时,Vue 监听到数据修改,在底层进行 Dom 操自动更新视图。

开发者工具安装

极简插件官网_Chrome插件下载_Chrome浏览器应用商店 (zzzmh.cn)

创建 Vue 工程(废案)

使用 vue-cli 创建

备注:目前 vue-cli 已处于维护模式,官方推荐基于 Vite 创建项目。(点击查看官方文档

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue --version

## 安装或者升级你的@vue/cli 
npm install -g @vue/cli

## 执行创建命令
vue create vue_test

##  随后选择3.x
##  Choose a version of Vue.js that you want to start the project with (Use arrow keys)
##  > 3.x
##    2.x

## 启动
cd vue_test
npm run serve

使用 vite 创建

vite 是新一代前端构建工具,官网地址:https://vitejs.cnvite 的优势如下:

  • 轻量快速的热重载(HMR),能实现极速的服务启动
  • TypeScriptJSXCSS 等支持开箱即用,不需要配置其他文件
  • 真正的按需编译,不再等待整个应用编译完成。
  • webpack 构建 与 vite 构建对比图如下:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
## 1.创建命令
npm create vue@latest

## 2.具体配置
## 配置项目名称
     Project name: vue3_test
## 是否添加TypeScript支持
     Add TypeScript? » Yes
## 是否添加JSX支持
     Add JSX Support? » No
## 是否添加路由环境
     Add Vue Router for Single Page Application development? » No
## 是否添加pinia环境
     Add Pinia for state management? » No
## 是否添加单元测试
     Add Vitest for Unit Testing? » No
## 是否添加端到端测试方案
     Add an End-to-End Testing Solution? » No
## 是否添加ESLint语法检查
     Add ESLint for code quality? » Yes
## 是否添加Prettiert代码格式化
     Add Prettier for code formatting? » No

问题:

npm create vue@latest、和 npm install 速度慢或无法执行。

解决方法:

查看 npm 代理 → npm config get registry

更换 npm 镜像 → npm config set registry=https://registry.npmmirror.com

1
2
3
4
5
## 安装依赖 node_modules
    npm i

## 让 ts 能够识别 .jpg .txt 等文件
    /// <reference types="vite/client" /> 

安装官方推荐的 vscode 插件:

梳理项目的结构:使用vite创建项目-CSDN博客

  • node_modules 目录用来存放第三方依赖包

  • public 是公共的静态资源目录

  • src 是项目的源代码目录(程序员写的所有代码都要放在此目录下)

  • gitignore 是 Git 的忽略文件

  • index.html 是 SPA 单页面应用程序中唯一的 HTML 页面

  • package.json 是项目的包管理配置文件

  • assets 目录用来存放项目中所有的静态资源文件(css、fonts等)

  • components 目录用来存放项目中所有的自定义组件

  • App.vue 是项目的根组件

  • index.css 是项目的全局样式表文件

  • main.js 是整个项目的打包入口文件

自己动手编写一个 App 组件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<template>
  <div class="app">
    <h1>你好啊</h1>
  </div>
</template>

<script lang="ts">
  export default {
    name:'App' //组件名
  }
</script>

<style>
  .app {
    background-color: #ddd;
    box-shadow: 0 0 10px;
    border-radius: 10px;
    padding: 20px;
  }
</style>

总结:

  • Vite 项目中,index.html 是项目的入口文件,在项目最外层。
  • 加载 index.html 后,Vite 解析 <script type="module" src="xxx"> 指向的 JavaScript
  • Vue3 中是通过 createApp 函数创建一个应用实例。

Vue 指令

Vue 会根据不同的 【指令】(带有 v- 前缀的特殊标签属性。),针对标签实现不同的 【功能】

v-html

插值表达式不具备解析标签的能力,v-html 相当于动态的设置元素的 innerHTML

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<div id = 'app'>
    {{m1}}
    {{m2}}
</div>

<script>
    const app = new Vue({
        el: '#app',
        data: {
            m1: '<a href="https://www.baidu.com/">百度官网</a>',
            m2: '<p>这是一个段落</p>'
        }
    })
</script>

-------------------------------------------------------------------------------------

<div id = 'app'>
    <div v-html="m1"></div>
    <div v-html="m2"></div>
</div>

v-show 和 v-if ⭐

作用:控制元素显示或者隐藏,其中 v-show 仅控制显示隐藏,而 v-if 本质上为条件渲染

语法:v-show/v-if = "表达式" 表达式的值为 true显示该元素,为 false隐藏

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <style>
        .box {
            width: 500px;
            height: 300px;
            line-height: 300px;
            text-align: center;
            margin: 30px 0px 30px 200px;
            border: 5px solid black;
            font-size: 50px
        }
    </style>
</head>

<body>
    <div id="test">
        <div v-show="m1" class="box">v-show</div>
        <div v-if="m1" class="box">v-if</div>
    </div>

    <script src="/MyPra/vue.js"></script>

    <script>
        const test = new Vue({
            el: '#test',
            data: {
                m1: false,
                m2: true
            }
        })
    </script>
</body>

</html>

v-show 通过切换 css 中的 display:none 来控制元素显示或隐藏,v-if 根据判断条件渲染或者销毁元素;由于渲染元素需要消耗资源,因此 v-show 适用于频繁切换显示隐藏效果的场景,如购物车列表,下拉栏等,v-if 适用于广告栏,提示登录或注册等情况。

v-else 和 v-else-if

作用:辅助 v-if 进行判断渲染。

语法: v-else v-else-if = "表达式",需要紧挨着 v-if 一起使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!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>Document</title>
</head>

<body>
    <div id="app">
        <p>姓名:{{name}}</p>
        <p v-if="gender === 1">性别:♂ 男</p>
        <p v-else>性别:♀ 女</p>
        <p>年龄:{{age + '岁'}}</p>
        <p v-if="math + chinese + english >= 270">数学{{math}}分,语文{{chinese}}分,英语{{english}}分,成绩优秀</p>
        <p v-else-if="math + chinese + english >= 240">数学{{math}}分,语文{{chinese}}分,英语{{english}}分,成绩较好</p>
        <p v-else-if="math + chinese + english >= 210">数学{{math}}分,语文{{chinese}}分,英语{{english}}分,成绩一般</p>
        <p v-else-if="math + chinese + english >= 180">数学{{math}}分,语文{{chinese}}分,英语{{english}}分,成绩较差</p>
        <p v-else>完了</p>
    </div>

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

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                name: '张三',
                age: 19,
                gender: 1,
                math: 95,
                chinese: 75,
                english: 86
            }
        })
    </script>
</body>

</html>

v-on ⭐

  • 缩写@

  • 预期Function | Inline Statement | Object

  • 参数event

  • 修饰符

    • .stop - 调用 event.stopPropagation()
    • .prevent - 调用 event.preventDefault()
    • .capture - 添加事件侦听器时使用 capture 模式。
    • .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
    • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
    • .native - 监听组件根元素的原生事件。
    • .once - 只触发一次回调。
    • .left - (2.2.0) 只当点击鼠标左键时触发。
    • .right - (2.2.0) 只当点击鼠标右键时触发。
    • .middle - (2.2.0) 只当点击鼠标中键时触发。
    • .passive - (2.3.0) 以 { passive: true } 模式添加侦听器
  • 用法

    绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。

    用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件

    在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 $event property:v-on:click="handle('ok', $event)"

    2.4.0 开始,v-on 同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的。

  • 语法:

    ① 事件名 = “内联语句”(添加监听)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!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>Document</title>
</head>

<body>
    <div id="app">
        <button @mouseenter="count--">-</button>
        <span>{{ count }}</span>
        <button v-on:click="count++">+</button>
    </div>

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

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                count: 100
            }
        })
    </script>
</body>

</html>

拓展:使用 v-on 写一个抽取随机数字的程序。

int randomInt = (int)(Math.random() * (35 - 10 + 1)) + 10;

// 输出结果为:10 到 34 的随机整数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="test">
        <button id="btn" @click="count = Math.floor(Math.random() * (35 - 1 + 1)) + 1;">抽取一个幸运同学</button>
        {{count}}
    </div>

    <script src="/MyPra/vue.js"></script>

    <script>
        const t = new Vue({
            el: '#test',
            data: {
                count: 0
            }
        })
    </script>
</body>

</html>

② 事件名 = “methods中的函数名”(提供处理逻辑)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!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>Document</title>
    <style>
        h1 {
            color: rgb(50, 209, 50);
        }
    </style>
</head>

<body>
    <div id="app">
        <button @click="func">切换显示隐藏</button>
        <h1 v-show="flag">Vue</h1>
    </div>

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

    <script>
        const app4 = new Vue({
            el: '#app',
            data: {
                flag: true
            },
            methods: {
                func() {
                    console.log('执行函数func')
                    this.flag = !this.flag
                }
            }
        })
    </script>
</body>

</html>
  • v-on 调用传参

mothods 中创建带参方法,使用 v-on 绑定点击事件,完成自动贩售机案例。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<!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>Document</title>
    <style>
        .box {
            border: 3px solid #000000;
            border-radius: 10px;
            padding: 20px;
            margin: 20px;
            width: 200px;
            text-align: center;
        }

        h3 {
            margin: 10px 0 20px 0;
        }

        p {
            margin-left: 70px;
        }

        button {
            margin: 5px 1px 0px 0px;
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="box">
            <h3>24小时自动贩售机</h3>
            <button @click="buy(3)">可口可乐3元</button>
            <button @click="buy(7)">雀巢咖啡7元</button>
            <button @click="buy(6)">光明牛奶6元</button>
            <button @click="buy(9)">珍珠奶茶9元</button>
        </div>
        <p>当前余额:{{ money }}元</p>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                money: 100
            },
            methods: {
                buy(price) {
                    this.money -= price
                }
            }
        })
    </script>
</body>

</html>

v-bind ⭐

  • 缩写:

  • 预期any (with argument) | Object (without argument)

  • 参数attrOrProp (optional)

  • 修饰符

    • .prop - 作为一个 DOM property 绑定而不是作为 attribute 绑定。(差别在哪里?)
    • .camel - (2.1.0+) 将 kebab-case attribute 名转换为 camelCase。(从 2.1.0 开始支持)
    • .sync (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器。
  • 用法

    动态的设置 html 的标签属性,如 srcurltitle 等。

    在绑定 classstyle attribute 时,支持其它类型的值,如数组或对象。可以通过下面的教程链接查看详情。

    在绑定 prop 时,prop 必须在子组件中声明。可以用修饰符指定不同的绑定类型。

    没有参数时,可以绑定到一个包含键值对的对象。注意此时 classstyle 绑定不支持数组和对象。

  • 语法:

    v-bind : 属性名 = “表达式”。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="test">
        <img v-bind:src="url" :title="title" alt="">
    </div>

    <script src="/MyPra/vue.js"></script>

    <script>
        const t1 = new Vue({
            el: '#test',
            data: {
                url: '/MyPra/img/4f385747a4a5f33cbd1ee49224725e42a69dfd2852e57-BI49c0.png',
                title: '水滴'
            }
        })
    </script>
</body>

</html>

练习:编写程序,通过按钮来切换图片。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!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>Document</title>
    <style>
        img {
            height: 500px;
        }
    </style>
</head>

<body>
    <div id="app">
        <button v-show="index > 0" @click="index--">上一页</button>
        <div>
            <img :src="list[index]" :title="desc" alt="">
        </div>
        <button v-show="index < list.length - 1" @click="index++">下一页</button>
    </div>

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

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                index: 0,
                list: [
                    './img/animal_01.png',
                    './img/animal_02.png',
                    './img/animal_03.png',
                    './img/animal_04.png',
                    './img/animal_05.png',
                ],
                desc: '动物'
            }
        })
    </script>
</body>

</html>

v-for

作用:基于数据循环,多次渲染整个元素,如数组、对象、数字等。

语法:v-for = "(item, index) in 数组"

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!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>Document</title>
</head>

<body>
    <div id="app">
        <p v-for="(item, index) in list">{{ item }} 索引号为 {{ index }}</p>
    </div>

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

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                list: [15, 64, 32, 48, 29]
            }
        })
    </script>
</body>

</html>

案例:使用 v-for 渲染书籍列表

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!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>Document</title>
    <style>
        div li span {
            line-height: 30px;
        }
    </style>
</head>

<body>
    <div id="app">
        <li v-for="(item, index) in book">
            <span>{{item.name}}</span>
            <span>{{book[index].author}}</span>
            <span><button @click="del(item.id)">删除</button></span>
        </li>
    </div>

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

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                book: [
                    { id: 1, name: '《红楼梦》', author: '曹雪芹' },
                    { id: 2, name: '《西游记》', author: '吴承恩' },
                    { id: 3, name: '《水浒传》', author: '施耐庵' },
                    { id: 4, name: '《三国演义》', author: '罗贯中' }
                ]
            },
            methods: {
                del(id) {  // 优先使用id来删除
                    console.log('删除id为' + id + '的元素');
                    this.book = this.book.filter(item => item.id !== id);
                }
            }
        })
    </script>
</body>

</html>

v-for 的默认行为会尝试原地修改元素(就地复用)。

可以使用 key 属性给列表项添加的唯一标识,便于 Vue 进行列表项的正确排序复用。

key 的值只能是字符串或数字类型

key 的值必须具有唯一性

③ 推荐使用 id 作为 key (唯一),不推荐使用 index 作为 key (会变化,不对应)

v-for 中的 key

语法:key = "唯一标识

在上述案例中,为第一个 li 元素加上 background: pink ,删除 li 元素,添加 key 属性进行比较。

1
<li v-for="(item, index) in book" :key="item.id">

v-model ⭐

作用:给表单元素使用,双向数据绑定(视图变化数据自动更新),可以快速获取或设置表单元素内容

语法:v-model = '变量'

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!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>Document</title>
</head>

<body>
    <div id="app">
        账户:<input type="text" v-model="username"> <br><br>
        密码:<input type="password" v-model="password"> <br><br>
        <button @click="login">登录</button>
        <button @click="reset">重置</button>
    </div>

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

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                username: '',
                password: ''
            },
            methods: {
                login() {
                    console.log(this.username, this.password)
                },
                reset() {
                    this.username = ''
                    this.password = ''
                }
            }
        })
    </script>
</body>

</html>

案例练习

图片切换

编写程序,当鼠标滑入图片时切换图片,且能够循环切换。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!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>Document</title>
  <style>
    img{
        height: 500px;
    }
  </style>
</head>
<body>
  <div id="app">
    <img :src="list[index%5]" @mouseenter="index++" alt="">
  </div>

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

  <script>
    const app = new Vue({
      el: '#app',
      data: {
        index: 0,
        list: [
          './img/animal_01.png',
          './img/animal_02.png',
          './img/animal_03.png',
          './img/animal_04.png',
          './img/animal_05.png',
        ],
        desc:'动物'
      }
    })
  </script>
</body>
</html>

备忘录

案例模板:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<!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" />
    <link rel="stylesheet" href="/MyPra/major/index.css" />
    <title>备忘录</title>
</head>

<body>
    <div id="app">
        <!-- 输入框 -->
        <header class="header">
            <h1>备忘录</h1>
            <input placeholder="请输入..." class="new-todo" />
            <button class="add">添加笔记</button>
        </header>
        <!-- 列表区域 -->
        <section class="main">
            <ul class="todo-list">
                <li class="todo">
                    <div class="view">
                        <span class="index">1.</span> <label>周三下午开会</label>
                        <button class="destroy"></button>
                    </div>
                </li>
            </ul>
        </section>
        <!-- 统计和清空 -->
        <footer class="footer">
            <!-- 统计 -->
            <span class="todo-count">合 计:<strong> 1 </strong></span>
            <!-- 清空 -->
            <button class="clear-completed">
                清空
            </button>
        </footer>
    </div>

    <script src="/MyPra/vue.js"></script>

    <script>
        const app = new Vue({
            el: '#app',
            data: {

            }
        })
    </script>
</body>

</html>

编写程序,完成数据显示、数据统计、添加、删除、清空等功能。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<!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" />
    <link rel="stylesheet" href="/MyPra/major/index.css" />
    <title>备忘录</title>
</head>

<body>
    <div id="app" class="noteMain">
        <!-- 输入框 -->
        <header class="header">
            <h1>备忘录</h1>
            <input placeholder="请输入..." class="new-todo" v-model="input" />
            <button class="add" @click="add">添加笔记</button>
        </header>
        <!-- 列表区域 -->
        <section class="main">
            <ul class="todo-list">
                <li class="todo" v-for="(item, index) in list" :key="item.id">
                    <div class="view">
                        <span class="index">{{index+1}}.</span> <label>{{item.name}}</label>
                        <button class="destroy" @click="del(item.id)"></button>
                    </div>
                </li>
            </ul>
        </section>
        <!-- 统计和清空 -->
        <footer class="footer" v-show="list.length > 0">
            <!-- 统计 -->
            <span class="todo-count">合 计:<strong> {{list.length}} </strong></span>
            <!-- 清空 -->
            <button class="clear-completed" @click="clear">
                清空
            </button>
        </footer>
    </div>

    <script src="/MyPra/vue.js"></script>

    <script>
        const app = new Vue({
            el: '#app',
            data: {
                list: [
                    { id: 1, name: '周三下午开会' },
                    { id: 2, name: '周末出去吃火锅' },
                    { id: 3, name: '周五前提交作业' },
                    { id: 4, name: '放假期间完成三门功课预习' }
                ],
                input:'' 
            },
            methods:{
                del(id){
                    console.log(id)
                    this.list = this.list.filter(item => item.id !== id)
                },
                add(){
                    if(this.input === ''){
                        alert('请输入正确的内容')
                        return
                    }
                    this.list.unshift({
                        id: +new Date(),
                        name: this.input
                    })
                    this.input = ''
                },
                clear(){
                    this.list = []
                }
            }
        })
    </script>
</body>

</html>

选择题

  1. 在 Vue 中,被用来响应地更新 HTML 属性的指令是()。

    • A. v-on

    • B. v-if

    • C. v-bind

    • D. v-model

  2. 在 Vue 中,下列不属于条件渲染指令的是()。

    • A. v-if

    • B. v-else

    • C. v-show

    • D. v-on

  3. 在Vue中,下列关于Vue实例对象说法不正确的是()。

    • A. Vue 实例对象是通过 new Vue({ }) 方式创建的。

    • B. Vue 实例对象只允许有唯一的一个根标签。

    • C. 通过 methods 参数可以定义事件处理函数。

    • D. Vue 实例对象中 data 数据不具有响应特性。

  4. Vue中表单元素上数据双向绑定的指令是()。

    • A. v-if

    • B. v-show

    • C. v-model

    • D. v-for

  5. 在Vue中,以下表达式正确的是()。

    • A. {{ if(ok) return msg }}

    • B. {{ var str = “你好” }}

    • C. {{ ok ? “Yes” : “No” }}

    • D. {{ msg, num }}

  6. 在Vue中,以下关于 Vue 插值下列说法错误的是()。

    • A. {{ 文本 }} 用于插入与绑定文本。

    • B. {{ 表达式 }} 可以使用 JavaScript 表达式进行简单的运算。

    • C. {{ }} 中只支持单个表达式。

    • D. {{ }} 支持语句和流控制。

  7. 在Vue中,当遍历大数组或者做大量计算时,使用一下哪个选项效率最高。

    • A. methods

    • B. computed

    • C. components

    • D. data

  8. Vue常用选项参数中必须的参数是()。

    • A. data

    • B. el

    • C. mothods

    • D. filters

  9. 在Vue中,下列说法正确的是()。

    • A. vue 是后端框架。

    • B. vue 是基于 jQuery 开发的框架。

    • C. vue 是前端框架。

    • D. 以上说法都不对。

  10. 在Vue中,下列说法错误的是()。

    1
    2
    3
    
    <div v-show='flag'>使用v-show控制</div>
    
    <div v-if='flag'>使用v-if控制</div>
    
    • A. 当 flag 是 true 时,两个 div 都能显示出来。

    • B. 当 flag 是 false 时,第一个 div 进行了渲染。

    • C. 当 flag 是 false 时,第一个 div 设置了 display: none。

    • D. 当 flag 是 false 时,第二个 div 设置了 visible: hidden。

  11. 在 HTML 页面中,下列选项不属于键盘相关事件的是()。

    • A. onkeyup。

    • B. onkeydown。

    • C. oncontextmenu。

    • D. onkeypress。

  12. 在 Vue 中,能够实现页面单击事件绑定的代码是( )。

    • A. v-on:enter。

    • B. v-on:click。

    • C. v-on:mouseenter。

    • D. v-on:doubleclick。

vue 实现随机抽题

见 JavaScript 第二章 WebAPI(二)2.1.1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            width: 800px;
            height: 400px;
            border: 2px solid black;
            text-align: center;
            font-size: 36px;
            position: absolute;
        }

        .msg {
            height: 150px;
        }

        button {
            width: 100px;
            height: 50px;
            font-size: 30px;
            position: relative;
            top: 100px;
        }
    </style>
</head>

<body>
    <div class="box" id="app">
        <div class="msg">
            <p>{{msg}}</p>
        </div>
        <button class="start" @click="b1" :disabled="this.ques.length === 1">开始</button>
        <button class="end" @click="b2" :disabled="this.ques.length === 1">结束</button>
    </div>
    <script src="/MyPra/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                ques: [
                    'v-show 和 v-if 有什么区别?',
                    'v-on 的作用是什么?缩写是什么?',
                    'v-for 多次渲染元素的语法是?',
                    ':src="list[index]" 使用的是哪个 vue 指令?',
                    'vue 中哪个指令可以实现数据双向绑定?',
                ],
                random: 0,
                s1: 0,
                msg: 'v-show 和 v-if 有什么区别?',
            },
            methods: {
                b1() {
                    console.log(this.ques[2]);
                    const start = document.querySelector('.start');
                    const end = document.querySelector('.end');
                    s1 = setInterval(this.r1, 30);

                },
                b2() {
                    clearInterval(s1);
                    this.ques.splice(this.random, 1);
                },
                r1(){
                    const p = document.querySelector('p');
                    this.random = Math.floor(Math.random() * this.ques.length);
                    this.msg = this.ques[this.random];
                }
            }
        })
    </script>
</body>

</html>
Blog for Sandy Memories