起步
安装&使用
官网:Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org)
vue2:Vue.js (vuejs.org)
简单使用
<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配置项:
- template后面跟的是模板语句,模板语句是html、vue特殊规则、html+vue特殊规则的形式
- template只能有一个根元素,
<h1></h1><h1></h1>
这个就是错误的范例 - 如果data选项中的数据发生变化,模板语句一定会重新编译
- 如果挂载位置中有内容的话,在挂载之后会被替换清空
- 也可以不使用template属性编写模板语句,直接在html标签中进行书写加上
{{key}}
也可以正常显示
每个vue实例都有一个$mount
方法,用处为将vue实例挂在到指定位置
模板数据来源
往模板语句中插入数据需要data选项加上插值语法(胡子语法)
<div id="app"></div>
<script>
new Vue({
template: '<h1>{{message}}</h1>',
data: {
message: 'hello vue'
}
}).$mount('#app');
</script>
原理:会对template的值进行编译,当遇到
{{key}}
格式的数据时回去data选项里面找相对应的数据,并把值插入到该位置
挂载
在挂载的时候也可以不使用 .$mount('#app')
来进行挂载
<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可以是什么):
- data选项中所声明的全部key
- 所有常量,如:
{{123}}
,{{"hello"}}
,{{3.14159}}
- 合法的JavaScript表达式,如:
{{1 + 1}}
,{{"hello" + "vue"}}
,{{data.key + 1}}
,{{data.key ? "是" : "否"}}
- 在vue白名单里面的:
Infinity
,undefined
,NaN
,isFinite
,isNaN
,parseFloat
,parseInt
,decodeURI
,decodeURIComponent
,encodeURI
,encodeURIComponent
,Math
,Number
,Date
,Array
,Object
,Boolean
,String
,RegExp
,Map
,Set
,JSON
,Intl
,require
模板语法 - 指令
语法:v-???
写法:
- vue中所有的指令语法都是以
v-
开头 - vue框架所有指令写在html标签的属性位置
- 完整语法规则:
<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文件加载完成之后才会展示正常数据
<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变表达式结果变,连带产生动态效果
<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-midel:value="xxx"
限制:<input>
、<select>
、<textarea>
、components
作用:跟bind不同的是,当在input中更改属性值之后data中的属性值也会跟着改变
<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
示例:
<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
...
<!-- 纯调用 -->
<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.命名 = 按键对应的数字
<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 徽标键 (⊞)
<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,让在其特定的时候增加或者减少某些样式,因为都是 attribute,所以可以用 v-bind
进行处理。由于字符串拼接麻烦且易错,因此,在将 v-bind
用于 class
和 style
时,Vue.js 做了专门的增强
表达式结果的类型除了字符串之外,还可以是对象或数组。
Class绑定
使用场景:
- 字符串:当确定动态绑定的样式个数只有1个,但是名字不确定的时候
- 数组:当样式的个数不确定,并且样式的名字也不确定的时候
- 对象:当样式的个数是固定的,并且样式的名字也是固定的,但是需要动态的决定样式是否使用的时候
示例
<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绑定
总结以下六点:......
示例
<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-show
温度案例
<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-if
、v-else-if
、v-else
中间不能有其他元素,上面的案例 v-show
指令也可以完成,他们两个的区别就是 v-show
控制display属性而 v-if
是不断在DOM树上创建和删除
在某些场景下v-if需要判断很多,解决方法就是在最外层包裹上 <template>
标签,这个标签属于Vue所有,因为他不会编译到页面中所以不会破坏整体整体骨架
列表渲染
主要指令 v-for
,作用在循环项上
语法:v-for="(变量名,下标) [in|of] 数组"
案例
<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算法:可以快速比对处两组数据不同之处