Skip to content

安装&使用

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

vue2:Vue.js (vuejs.org)

简单使用

html
<div id="app"></div>
<script>
    const myVue = new Vue({
        template: '<h1>hello world</h1>',
    });
    myVue.$mount('#app');
</script>

注意事项:直接调用vue函数会报错,必须new实例;vue给构造参数options参数必须是一个纯粹的js对象,里面有大量的key:value

template配置项:

  1. template后面跟的是模板语句,模板语句是html、vue特殊规则、html+vue特殊规则的形式
  2. template只能有一个根元素,<h1></h1><h1></h1> 这个就是错误的范例
  3. 如果data选项中的数据发生变化,模板语句一定会重新编译
  4. 如果挂载位置中有内容的话,在挂载之后会被替换清空
  5. 也可以不使用template属性编写模板语句,直接在html标签中进行书写加上 {{key}} 也可以正常显示

每个vue实例都有一个$mount方法,用处为将vue实例挂在到指定位置

模板数据来源

往模板语句中插入数据需要data选项加上插值语法(胡子语法)

html
<div id="app"></div>
<script>
    new Vue({
        template: '<h1>{{message}}</h1>',
        data: {
            message: 'hello vue'
        }
    }).$mount('#app');
</script>

原理:会对template的值进行编译,当遇到 {{key}} 格式的数据时回去data选项里面找相对应的数据,并把值插入到该位置

挂载

在挂载的时候也可以不使用 .$mount('#app') 来进行挂载

html
<div id="app"></div>
<script>
    new Vue({
        // 挂在位置
        el: "#app",
        template: '<h1>{{message}}</h1>',
        data: {
            message: 'hello vue'
        }
    });
</script>

在vue中有一个配置项叫 el 它的值就是你要挂载的位置,它和 .$mount('#app') 的效果一样

在挂载时 #app 是ID选择器,也可以使用其他选择器如:类选择器、标签、name...

注意:vue只跟匹配到的第一个容器进行配对,如:类选择器,vue只会跟第一个匹配到的元素进行配对,剩余的不管,容器和vue也是一样

模板语法 - 插值

语法:{{key}}

写法(key可以是什么):

  1. data选项中所声明的全部key
  2. 所有常量,如:{{123}}{{"hello"}}{{3.14159}}
  3. 合法的JavaScript表达式,如:{{1 + 1}}{{"hello" + "vue"}}{{data.key + 1}}{{data.key ? "是" : "否"}}
  4. 在vue白名单里面的:InfinityundefinedNaNisFiniteisNaNparseFloatparseIntdecodeURIdecodeURIComponentencodeURIencodeURIComponentMathNumberDateArrayObjectBooleanStringRegExpMapSetJSONIntlrequire

模板语法 - 指令

官方API文档 - 指令篇

语法:v-???

写法:

  1. vue中所有的指令语法都是以 v- 开头
  2. vue框架所有指令写在html标签的属性位置
  3. 完整语法规则:<html 标签 v-指令名:参数="表达式"></html>;表达式:插值中可以些什么表达式中就可以些什么,不是所有的指令都有参数和表达式

指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM

指令

  • v-once:只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能
  • v-if="表达式":表达式执行结果需要一个布尔值;为true则指令所在的标签会被渲染,反之则不会
  • v-for="item in items":基于源数据多次渲染元素或模板块
  • v-text:可以将指令中的内容拿出来填充到标签体当中,会覆盖
  • v-html:可以将指令中的内容拿出来填充到标签体当中,会覆盖,会解析内容中的html标签
  • v-cloak:该指令配合css是用来解决插值语法闪现问题
  • v-pre:提高vue的编译效率,有该指令的标签不会被vue编译,适合没有写vue语法的标签

v-cloak

当网络加载延迟的时候会导致vue文件无法进行加载编译页面,这时候如果页面上有插值语法会一直展示原始内容,直到vue文件加载完成之后才会展示正常数据

html
<style>
    [v-cloak] {
        display: none !important;
    }
</style>
<div id="app">
    <h1 v-cloak>hello world</h1>
</div>

在上面的代码中,对有 v-cloak 属性的标签进行隐藏,等到vue文件加载完成编译文件的时候会去除掉所有的 v-cloak 文件这时候元素正常展示,解决胡子闪现问题

单向绑定

指令:v-bind

缩写::

作用:让html某个标签的值产生动态效果

格式:<html 标签 v-bind:参数="表达式"></html 标签>

编译:在编译完成之后参数会被编译为html标签的属性名;表达式会关联data,data变表达式结果变,连带产生动态效果

html
<div id="app">
    <img v-bind:src="res" width="100px">
</div>
<script>
    new Vue({
        el: "#app",
        data: {
            res: "../favicon.ico"
        }
    });
</script>

注意:不可以直接在属性值中写插值语法,会报错;需要标签体中的内容动态使用插值,需要标签属性动态使用指令

双向绑定

指令:v-model

简写:v-model="xxx" == v-model:value="xxx"

限制:<input><select><textarea>、components

作用:跟bind不同的是,当在input中更改属性值之后data中的属性值也会跟着改变

html
<div id="app">
    // 变化展示
    <p>bind:{{text1}}</p>
    <p>model:{{text2}}</p>
    // 更改
    v-bind:<input type="text" :value="text1"><br>
    v-model:<input type="text" v-model:value="text2"><br>
</div>
<script>
    new Vue({
        el: "#app",
        data: {
            text1: "bind",
            text2: "model"
        }
    });
</script>

v-model 只能作用在指定标签中

事件绑定

指令:v-on

缩写:@

参数:event

示例:

html
<div id="app">
    <!-- 点击事件 可以省略"()"(前提不传参) -->
    <button @click="popUps(name)">java</button>
</div>
<script>
    const vm = new Vue({
        el: "#app",
        data: {
            name: "张三"
        },
        methods: {
            popUps(val) {
                alert(val)
            }
        }
    })
</script>

Vue在调用函数的时候会自动传一个对象(不传参数的情况下),这个对象就是当前发生事件的对象,如果传递参数会重写参数数据,不会在传递对象,如果依然想传递对象需要在括号中写上占位符:$event

html
...
<!-- 纯调用 -->
<button @click="popUps">java</button>
...
popUps(event) {
	console.log(event);
}
...

事件修饰符

官方文档 | 事件

对事件做一些自定义操作

格式:@click.prevent="xx"

常用修饰符:

  • .stop - 停止冒泡事件,等同于调用 event.stopPropagation()
  • .prevent - 阻止事件默认行为,等于调用 event.preventDefault()
  • .capture - 添加事件侦听器时使用 capture 模式(包括两种不同的模式,冒泡:从内到外;捕获:从外到内)。
  • .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
  • .once - 只触发一次回调。
  • .passive - 立即执行事件的默认行为,不管是否有未完成的事(跟prevent是相互对立的)

使用方式(阻止事件默认行为):<button @click.prevent="xx">xxx</button>

事件修饰符可以联合使用 .stop.self 类似于Java的链式编程,有先后顺序之分

按键修饰符

官方文档 | 按件

通过按下某个按键做对应的事情

格式:@keyup.xxx="xx"

常用修饰符:

  • .enter
  • .tab(无法触发keyup事件,只能触发keydown事件)
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

以上通过按下对应的按键触发(前提是那个组件有焦点比如input)

获取某个按键的真实名字

可以通过 event.key 获取某个按键的真实名字,把这个真实名字以 kebab-case 风格进行命名

PageDown 按键通过命名为 page-down

自定义按键修饰符

通过特定的语句来进行命名

Vue.config.keyCodes.命名 = 按键对应的数字

html
<div id="app">
    <input type="text" @keyup.huiche="keyup">
</div>
<script>
    // 定义快捷键 huiche :回车
    Vue.config.keyCodes.huiche = 13;
    const vm = new Vue({
        el: "#app",
        data: {},
        methods: {
            keyup(event) {
                console.log(event.key);
            }
        }
    })
</script>

系统修饰键

有四个按键比较特殊,它们按下就是 keydown 事件,和别的按键一起按下去然后松开按键之后是 keyup 事件

  • .ctrl
  • .alt
  • .shift
  • .meta

注意:在 Mac 系统键盘上,meta 对应 command 键 (⌘)。在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)

html
<div id="app">
    <!-- 按下ctrl触发 -->
    <input type="text" @keydown.ctrl="keyup">
    <!-- 按下ctrl+i触发 -->
    <input type="text" @keydown.ctrl.i="keyup">
</div>
<script>
    const vm = new Vue({
        el: "#app",
        data: {},
        methods: {
            keyup(event) {
                console.log(event.key);
            }
        }
    })
</script>

Class && Style

Class 与 Style 绑定

本质就是操作元素的class,让在其特定的时候增加或者减少某些样式,因为都是 attribute,所以可以用 v-bind 进行处理。由于字符串拼接麻烦且易错,因此,在将 v-bind 用于 classstyle 时,Vue.js 做了专门的增强

表达式结果的类型除了字符串之外,还可以是对象或数组。

Class绑定

使用场景:

  • 字符串:当确定动态绑定的样式个数只有1个,但是名字不确定的时候
  • 数组:当样式的个数不确定,并且样式的名字也不确定的时候
  • 对象:当样式的个数是固定的,并且样式的名字也是固定的,但是需要动态的决定样式是否使用的时候

示例

html
<style>
    .box {
        width: 100px;
        height: 100px;
        background-color: black;
    }

    .red {
        background-color: red;
    }

    .green {
        background-color: green;
    }

    .blue {
        background-color: blue;
    }
</style>
<div id="app">
    <!-- 字符串 -->
    <div class="box" :class="clazz"></div>
    <button @click="clazz = 'red'">红</button>
    <button @click="clazz = 'green'">绿</button>
    <button @click="clazz = 'blue'">蓝</button>
    <!-- 数组 -->
    <div class="box" :class="clazzArray"></div>
    <!-- 对象 -->
    <div class="box" :class="clazzObj"></div>
</div>
<script>
    const vm = new Vue({
        el: "#app",
        data: {
            clazz: "",
            clazzArray: [
                "red",
                "green",
                "blue"
            ],
            clazzObj: {
				red: true,
                green: false,
                blue: false
            }
        }
    })
</script>

Style绑定

总结以下六点:......

示例

html
<style>
    .box {
        width: 100px;
        height: 100px;
        border: 1px solid #000;
    }
</style>
<div id="app">
    <!-- 字符串 -->
    <div class="box" :style="clazz"></div>
    <!-- 数组 -->
    <div class="box" :style="clazzArray"></div>
    <!-- 对象 -->
    <div class="box" :style="clazzObj"></div>
</div>
<script>
    const vm = new Vue({
        el: "#app",
        data: {
            clazz: "backgroundColor: red;",
            clazzArray: [
                {
                    backgroundColor: "green"
                }
            ],
            clazzObj: {
                backgroundColor: "blue"
            }
        }
    })
</script>

条件渲染

动态渲染有两种指令可以完成,一个是 v-if 还有一个是 v-showv-if 的底层实现是通过操作 DOM 树来完成的(也就是删除和添加元素),而 v-show 是通过操作元素的 display 属性来完成的(也就是元素还在 DOM 树中,只是被蕴藏了)

温度案例

html
<div id="app">
    温度:<input type="number" v-model="num"><br>
    天气:
    <span v-if="num < 10">寒冷</span>
    <span v-else-if="num >= 10 && num < 20">舒适</span>
    <span v-else>炎热</span>
</div>
<script>
    const vm = new Vue({
        el: "#app",
        data: {
            num: 1
        }
    })
</script>

v-ifv-else-ifv-else 中间不能有其他元素

在某些场景下 v-if 需要判断很多,解决方法就是在最外层包裹上 <template> 标签,这个标签属于Vue所有,因为他不会编译到页面中所以不会破坏整体整体骨架

列表渲染 v-for

主要指令 v-for,作用在循环项上

语法:v-for="(变量名,下标) [in|of] 数组"

案例

html
<div id="app">
    <!-- 遍历数组 -->
    <ul>
        <li v-for="(n,index) of num" :key="index">{{n}} — {{index}}</li>
    </ul>
    <!-- 遍历对象 -->
    <ul>
        <li v-for="(key,value) of user" :key="key">{{key}} — {{value}}</li>
    </ul>
    <!-- 遍历字符串 -->
    <ul>
        <li v-for="(char,index) of str" :key="index">{{char}} — {{index}}</li>
    </ul>
</div>
<script>
    const vm = new Vue({
        el: "#app",
        data: {
            num: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
            user: {
                id: "1",
                name: "张三",
                age: 18
            },
            str: "hello"
        }
    })
</script>

在数组和字符串遍历第二个参数就是下标,对象遍历第二个参数就是值

:key 作用

这个key相当于当前dom元素的身份证号,配合虚拟DOM和diff算法进行快速更改数据内容,key的值如果你不写则默认为第二个参数

流程:当你已经渲染好页面,此时对数据做出了更改,diff算法会通过key值找到dom元素并对其内的内容进行比对,发现不一样的数据时进行重新渲染,否则一切照旧

当你在数组前加上数据的时候,index会从新加的数据开始算,本来key为1的dom变为2这时,diff算法进行比较的时候就会开始重新渲染(解决方法就是让key值为一个不会轻易改变且唯一的值)

image-20240418195323953

前置知识

虚拟DOM:相当于存在于内存中的DOM对象

diff算法:可以快速比对处两组数据不同之处