vue2基础知识-1

本文介绍了Vue2的基础知识,包括CDN引入Vue、Mystache插值语法、列表数据操作和计数器的两种方法。重点讲解了Vue的指令如v-bind、v-on及其各种修饰符,以及条件渲染的使用。还探讨了MVVM模型和Vue的data、methods、computed属性,强调了在methods中避免使用箭头函数的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CDN引入Vue

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>哈哈哈哈</h2>
    <div id="app"></div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            template: `<h2>cdn引入vue</h2>`
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

在这里插入图片描述

Vue体验

Mystache插值语法

插值语法:
data属性返回的对象是有添加到Vue的响应式系统中。当data中的数据发生改变时,对应的内容也会进行更新。
用法如下:

{{ data_name }}
{{ js表达式 }}
{{ 调用methods/computed属性中函数 }}

<!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>
    <h2>哈哈哈哈</h2>
    <div id="app"></div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            // 插值语法{{data_name}}
            template: `<h2>{{title}}</h2>`,
            data: function () {
                return {
                    title: "hello world"
                }
            }
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

在这里插入图片描述

列表数据

v-for 可以用来循环一个可迭代的数据。

<!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>
    <h2>哈哈哈哈</h2>
    <div id="app"></div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            // v-for 循环一个可迭代的数据
            template: 
            `<ul>
                <li v-for='item in dataArr'>{{item}}</li>    
            </ul>`,
            data: function () {
                return {
                    dataArr: ['语文', '数学', '英语']
                }
            }
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

在这里插入图片描述

计数器

methods: 里面写一些功能函数

方式一:

<!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>
    <h2>哈哈哈哈</h2>
    <div id="app"></div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            // v-for 循环一个可迭代的数据
            template: 
            `<h1>{{count}}</h1>
            <button @click="increase">+</button>
            <button @click="decrease">-</button>
            `,
            data: function () {
                return {
                    count: 0
                }
            },
            methods: {
                increase: function () { this.count++},
                decrease: function () { this.count--}
            },
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

方式二:

template里面的数据就是用来替换

元素里面的值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>哈哈哈哈</h2>
    <div id="app">
        <h1>{{count}}</h1>
        <button @click="increase">+</button>
        <button @click="decrease">-</button>
    </div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            data: function () {
                return {
                    count: 0
                }
            },
            methods: {
                increase: function () { this.count++},
                decrease: function () { this.count--}
            },
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

在这里插入图片描述

Vue的一些指令说明

v-bind(掌握)

动态的绑定一个或多个 attribute,也可以是组件的 prop。

  • 缩写:: 或者 . (当使用 .prop 修饰符)
  • 期望:any (带参数) | Object (不带参数)
  • 参数:attrOrProp (可选的)
<!-- 绑定 attribute -->
<img v-bind:src="imageSrc" />

<!-- 动态 attribute 名 -->
<button v-bind:[key]="value"></button>

<!-- 缩写 -->
<img :src="imageSrc" />

<!-- 缩写形式的动态 attribute 名 -->
<button :[key]="value"></button>

<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName" />

<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]"></div>

<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 绑定对象形式的 attribute -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

<!-- prop 绑定。“prop” 必须在子组件中已声明。 -->
<MyComponent :prop="someThing" />

<!-- 传递子父组件共有的 prop -->
<MyComponent v-bind="$props" />

<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>

v-on(掌握)

给元素绑定事件监听器。

  • 缩写:@
  • 期望的绑定值类型:Function | Inline Statement | Object (不带参数)
  • 参数:event (使用对象语法则为可选项)
  • 修饰符:
    • .stop ——调用 event.stopPropagation()。
    • .prevent ——调用 event.preventDefault()。
    • .capture ——在捕获模式添加事件监听器。
    • .self ——只有事件从元素本身发出才触发处理函数。
    • .{keyAlias} ——只在某些按键下触发处理函数。
    • .once ——最多触发一次处理函数。
    • .left ——只在鼠标左键事件触发处理函数。
    • .right ——只在鼠标右键事件触发处理函数。
    • .middle ——只在鼠标中键事件触发处理函数。
    • .passive ——通过 { passive: true } 附加一个 DOM 事件。
<!-- 方法处理函数 -->
<button v-on:click="doThis"></button>

<!-- 动态事件 -->
<button v-on:[event]="doThis"></button>

<!-- 内联声明 -->
<button v-on:click="doThat('hello', $event)"></button>

<!-- 缩写 -->
<button @click="doThis"></button>

<!-- 使用缩写的动态事件 -->
<button @[event]="doThis"></button>

<!-- 停止传播 -->
<button @click.stop="doThis"></button>

<!-- 阻止默认事件 -->
<button @click.prevent="doThis"></button>

<!-- 不带表达式地阻止默认事件 -->
<form @submit.prevent></form>

<!-- 链式调用修饰符 -->
<button @click.stop.prevent="doThis"></button>

<!-- 按键用于 keyAlias 修饰符-->
<input @keyup.enter="onEnter" />

<!-- 点击事件将最多触发一次 -->
<button v-on:click.once="doThis"></button>

<!-- 对象语法 -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>

条件渲染 (掌握)

v-if :

  • 基于表达式值的真假性,来条件性地渲染元素或者模板片段。
  • 期望的绑定值类型:any
  • 详细信息
    • 当 v-if 元素被触发,元素及其所包含的指令/组件都会销毁和重构。如果初始条件是假,那么其内部的内容根本都不会被渲染。
    • 可用于 表示仅包含文本或多个元素的条件块。
    • 当条件改变时会触发过渡效果。
    • 当同时使用时,v-if 比 v-for 优先级更高。我们并不推荐在一元素上同时使用这两个指令 — 查看列表渲染指南详情。
<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>
template元素

因为v-if是一个指令,所以必须将其添加到一个元素上,但是如果我们希望切换的是多个元素呢?此时我们渲染的是div,但是我们并不希望div这种元素被渲染。此时,我们可以使用template。

        <div v-if="{条件}">
            <h1>xxxx</h1>
            <h2>xxxx</h2>
        </div>
        <!-- 推荐使用template,不会增加多余的div元素 -->
        <template v-if="{条件}">
            <h1>xxxx</h1>
            <h2>xxxx</h2>
        </template>
案例
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        [v-cloak] {
            display: none;
        }
    </style>
</head>
<body>
    <div id="app">
       <!--1.默认传递event对象-->
       <button @click="btn1Click">事件1</button>
       <!--2.只有自己的参数-->
       <button @click="btn2Click('李四', 18)">事件2</button>
       <!--3.event对象和自己的参数-->
       <!-- 在模板中想要明确的获取event对象:$event -->
       <button @click="btn3Click('李四', 17, $event)">事件3</button>
    </div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            data: function () {
                return {
                    name: '张三',
                    age: 12,
                    sex: '男'
                }
            },
            methods: {
                // 1.默认参数:event对象
                // 如果在绑定事件的时候,没有传递任何的参数,那么event对象会被默认传递进来
                btn1Click: function (event) {
                    console.log(event)
                },
                btn2Click: function (name, age) {
                    console.log(name, age)
                },
                btn3Click: function (name, age, event) {
                    console.log(name, age, event)
                }
            },
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

在这里插入图片描述

v-show

  • 基于表达式值的真假性,来改变元素的可见性。
  • 期望的绑定值类型:any
  • 详细信息
    v-show 通过设置内联样式的 display CSS 属性来工作,当元素可见时将使用初始 display 值。当条件改变时,也会触发过渡效果。

注意:
v-show是不支持template
v-show不可以和v-else一起使用

v-once(了解)

只渲染一次,即使该改变了data_name的值,也不会重新渲染加了此指令的标签。可用于性能优化。

<h1 v-once>{{ data_name }}<h1>

在这里插入图片描述
如果是子节点,也是只会渲染一次:

<div v-once>
	<h1>{{ data_name }}</h1>
</div>

v-text(了解)

用于更新元素的textContent

<h1 v-text="data_name"></span>
等价于
<h1>{{ data_name }}</h1>

v-html(了解)

默认情况下,如果我们栈式的内容本身是html,vue并不对其进行解析。
如果希望这个内容被Vue进行解析,可以使用v-html

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h1>{{content}}</h1>
        <h1 v-html="content"></h1>
    </div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            data: function () {
                return {
                    content: '<span style="font-size: 20px;">哈哈哈</span>'
                }
            },
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

v-pre(了解)

v-pre用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签:

  • 跳过不需要编译的节点,加快编译速度

在这里插入图片描述

<!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">
        <h1>没有用v-pre {{ content }}</h1>
        <h1 v-pre>用了v-pre {{content}}</h1>

    </>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            data: function () {
                return {
                    content: '哈哈哈哈'
                }
            },
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

v-cloak(了解)

这个指令保持在元素上直到关联组件实例结束编译。
v-cloak和CSS规则一起使用。比如:[v-cloak] {display: none},这个指令可以隐藏未编译的Mustache标签直到组件实例准备完成。

<!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>
        [v-cloak] {
            display: none;
        }
    </style>
</head>
<body>
    <div id="app">
        <h1 v-cloak> {{ content }}</h1>
    </>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        setTimeout(() => {
            // 使用VUE
            const app = Vue.createApp({
                data: function () {
                    return {
                        content: '哈哈哈哈'
                    }
                },
            })
            // 挂在
            app.mount("#app")
        }, 3000)
    </script>
</body>
</html>

v-memo(了解)

期望的绑定值类型:any[]
详细信息:
缓存一个模板的子树。在元素和组件上都可以使用。为了实现缓存,该指令需要传入一个固定长度的依赖值数组进行比较。如果数组里的每个值都与最后一次的渲染相同,那么整个子树的更新将被跳过。举例来说:

<div v-memo="[valueA, valueB]">
  ...
</div>

当组件重新渲染,如果 valueA 和 valueB 都保持不变,这个

及其子项的所有更新都将被跳过。实际上,甚至虚拟 DOM 的 vnode 创建也将被跳过,因为缓存的子树副本可以被重新使用。

<!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>
        [v-cloak] {
            display: none;
        }
    </style>
</head>
<body>
    <div id="app">
      <div v-memo="[name]">
        <h1> {{ name }}</h1>
        <h1> {{ age }}</h1>
        <h1> {{ sex }}</h1>
      </div>
      <button @click="changeName">改变名字</button>
      <button @click="changeAge">改变年龄</button>
    </div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            data: function () {
                return {
                    name: '张三',
                    age: 12,
                    sex: '男'
                }
            },
            methods: {
                changeName: function () {
                    console.log('改变名字')
                    this.name = '李四'
                },
                changeAge: function () {
                    console.log('改变年龄')
                    this.age = 18
                }
            },
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

这个例子中只有点击改变name值才会重新渲染。
在这里插入图片描述

MVVM模型

Vue虽然并没有完全遵守MVVM的模型,但是整个设计是收到它的启发。
在这里插入图片描述

Vue一些属性说明

data属性

  • Vue2.x: 可以是一个函数(建议),也可以是一个对象;
  • Vue3.x: 必须是一个函数,否则浏览器中会报错。
const app = Vue.createApp({
            data: function () {
                return {
                    count: 0
                }
            },
        })

methods属性

methods属性是一个对象,通常我们会在这个对象中定义很多的方法:

  • 这些方法可以绑定到模板中
  • 在这些方法中,我们可以使用this关键字来直接访问到data中返回的对象的属性

为什么不能使用箭头函数?

不应该使用箭头函数来定义method函数(例如:plus: () => this.a++)。
原因:箭头函数绑定了父级作用域的上下文,所以this将不会按照期望指向组件实例,this.a将是undefined。

<!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>
    <h2>哈哈哈哈</h2>
    <div id="app">
        <h1>{{count}}</h1>
        <button @click="increase">+</button>
        <button @click="decrease">-</button>
    </div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            data: function () {
                return {
                    count: 0
                }
            },
            methods: {
                increase: () => console.log(this),
                // decrease: function () { this.count--}
            },
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

在这里插入图片描述

this到底指向了什么?

事实上Vue的源码当中就是对methods中所有函数进行了遍历,并且通过bind绑定了this:

<!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>
    <h2>哈哈哈哈</h2>
    <div id="app">
        <h1>{{count}}</h1>
        <button @click="increase">+</button>
        <button @click="decrease">-</button>
    </div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            data: function () {
                return {
                    count: 0
                }
            },
            methods: {
                increase: function () { console.log(this)},
                decrease: function () { this.count--}
            },
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

在这里插入图片描述

computed属性

总体来说,methods和computed使用上差不多,但是需要主要的是computed是有缓存的。下面这个例子中computed和methods的方法同样是引入了三次,但是computed的方法只调用了一次。
注意:computed必须要有返回值

<!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>
        [v-cloak] {
            display: none;
        }
    </style>
</head>
<body>
    <div id="app">
        <h1>{{ cFullName }}</h1>
        <h1>{{ cFullName }}</h1>
        <h1>{{ cFullName }}</h1>
        <h1>{{ fullName() }}</h1>
        <h1>{{ fullName() }}</h1>
        <h1>{{ fullName() }}</h1>
    </div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            data: function () {
                return {
                    name: '三',
                    firstName: '张',
                }
            },
            methods: {

                fullName () {
                    console.log('methods调用了')
                    return this.firstName + this.name
                }
            },
            computed: {
                cFullName () {
                    console.log('计算属性调用了')
                    return this.firstName + this.name
                }
            }
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

在这里插入图片描述

computed语法格式
<!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>
        [v-cloak] {
            display: none;
        }
    </style>
</head>
<body>
    <div id="app">
        <h1>{{ cFullName }}</h1>
        <button @click="changeName">改变名字</button>
    </div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            data: function () {
                return {
                    name: ['三', '张']
                }
            },
            methods: {

                changeName () {
                    this.cFullName = '李四'
                }
            },
            computed: {
                // 语法糖的写法
                // cFullName () {
                //     console.log('计算属性调用了')
                //     return this.firstName + this.name
                // }

                // 完整写法
                cFullName: {
                    get: function () {
                        return this.name[0] + this.name[1] 
                    },
                    set: function (value) {
                        console.log(value)
                        const arr = value.split('')
                        this.name[0] = arr[0]
                        this.name[1] = arr[1]
                    }
                }
            }
        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>

监听器watch

开发中我们在data返回的对象中定义了数据,这个数据通过插值语法等方式绑定到template中;当数据变化时,template会自动进行更新来显示最新的数据;但是在某些情况下,我们希望在代码逻辑中监听某个数据的变化,这个时候就需要用监听器watch来完成了。

<!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>
        [v-cloak] {
            display: none;
        }
    </style>
</head>
<body>
    <div id="app">
        <h1>{{ fullName.name }}</h1>
        <button @click="changeName">改变名字</button>
    </div>
    <!--CDN地址-->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        // 使用VUE
        const app = Vue.createApp({
            data: function () {
                return {
                    fullName: {name: '张三'}
                }
            },
            methods: {
                changeName () {
                    this.fullName = {name: '李四'}
                }
            },
            watch: {
                // 监听函数的名字和所监听的属性名字一致
                // 默认不进行深度监听
                fullName (newValue, oldValue) {
                    console.log(newValue)
                    console.log(oldValue)
                },
                
                // 进行深度监听
                // fullName: {
                //     handler (newValue, oldValue) {

                //     },
                //     // 开启深度监听
                //     deep: true,
                //     // 第一次渲染直接执行一次监听器
                //     immediate: true
                // }

                // 只监听对象的某个属性
                "fullName.name" (newValue, oldValue) {

                }
            }

        })
        // 挂在
        app.mount("#app")
    </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值