Vue.js的概念
什么是Vue.js
Vue.js 是前端的主流框架之一,和 Angular.js、React.js 一起,并称为前端三大主流框架
Vue.js 是一套构建用户界面的框架,只关注视图层,他不仅易于上手,还便于与第三方库或既有项目整合。
框架和库的区别
- 框架:是一套完整的解决方案;对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目 。
- 库(插件):提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其他库实现需求
Node(后端)中的 MVC 与前端中的 MVVM 之间的区别
- MVC 是后端的分层开发概念
- MVVM是前端视图层的概念,主要关注于 视图层分离,也就是说:MVVM吧前端的视图层,分为了三部分 Model, View, VM ViewModel,其中 VM是 MVVM思想的核心:因为VM是M和V之间的调度者
- M保存的是每个页面中单独的数据
- V 就是每个页面中的HTML结构
- VM 是一个调度者,分割了M和V 使M和V互相不能调用。当V层想要获取后保存数据的时候,都要由VM做中间的处理。
Vue 代码
Vue.js基本代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 1. 导入vue的包 -->
<script src="lib/vue.js"></script>
</head>
<body>
<!-- 将来 new 的 vue 实例,会控制这个 元素中的所有内容 -->
<!-- Vue 实例所控制的这个元素区域,就是 V -->
<div id="app">
<p>{{ msg }}</p>
</div>
<script>
//2.创建一个Vue的实例
//当导入包之后,在浏览器的内存中,就多了 Vue 构造函数
// 注意:new 出来的这个 VM 对象 就是 MVVM中的 VM调度者
var vm = new Vue({
el: '#app', //表示,当前 new 的这个 Vue实例,要控制页面上的哪个区域
// 这里的 data 就是 MVVM中的 M 专门用来保存 每个页面的数据
data: { //data 属性中,存放的是 el 中要用的数据
msg: '欢迎学习vue' //通过 vue 提供的指令,很方便的就能把数据渲染到页面上,程序员不再手动操作DOM元素了【前端的vue之类的框架,不提倡手动操作DOM元素了】
}
})
</script>
</body>
</html>
v-cloak、v-text、v-html、v-bind和v-on
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app">
<!-- 使用 v-cloak 能够解决 插值表达式闪烁问题 -->
<p v-cloak>{{ msg }}</p>
<h4 v-text="msg"></h4>
<!-- 默认 v-text 是没有闪烁问题的 -->
<!-- v-text 会覆盖元素中原本的内容,但是 插值表达式 只会替换自己的占位符,不会把整个元素的内容清空 -->
<div>{{ msg2 }}</div>
<div v-text="msg2"></div>
<div v-html="msg2">121212</div>
<!-- v-bind: 是 Vue 中,提供的用于绑定属性的指令 -->
<!-- 注意:v-bind: 指令可以简写为 :要绑定的属性 -->
<!-- v-bind 中,可以写合法的JS表达式 -->
<!-- Vue 中提供了 v-on: 事件绑定机制 -->
<!-- <input type="button" value="按钮" v-bind:title="mytitle + '123'" v-on:click="alert('hello')"> -->
<input type="button" value="按钮" v-on:click="show">
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '123',
msg2: '<h1>我是一个H1</h1>',
mytitle: '这是一个自己定义的title'
},
methods: { //这个 methods属性中定义了当前 vue实例所有可用的方法
show: function() {
alert('hello');
}
}
})
// document.getElementById('btn').onclick = function() {
// alert('Hello');
// }
</script>
</body>
</html>
- 如何定义一个基本的vue代码结构
- 插值表达式和 v-text的区别
- v-cloak
- v-html
- v-bind vue提供的属性绑定机制 缩写是 :
- v-on vue提供的事件绑定机制 缩写是 @
案例:跑马灯效果制作
案例分析:
- 给 浪起来 按钮,绑定一个点击事件 v-on @
- 在按钮的事件处理函数中,写相关的业务逻辑代码:拿到 msg字符串,然后 调用字符串的 substring 来进行字符串的截取操作,把 第一个字符截取出来,放到最后一个位置即可
- 为了实现点击按钮,自动截取的功能,需要把第2步骤中的代码放入一个定时器中去。
- 代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="lib/vue.js"></script>
</head>
<body>
<div id="app">
<input type="button" value="浪起来" @click="lang">
<input type="button" value="低调" @click="stop">
<h4>{{ msg }}</h4>
</div>
<script>
//注意:在VM实例中,如果想要调用 data 上的数据,或者 想要调用 methods 中的方法,必须通过 this 数据属性名,或者 this.方法名 来进行访问,这里的 this 表示 new 的 VM实例对象
var vm = new Vue({
el: '#app',
data: {
msg: '孟鹤堂,周九良~~!',
intervalId: null //在data 上定义 定时器id
},
methods: {
lang() {
// console.log(this.msg);
if (this.intervalId != null) return;
this.intervalId = setInterval(() => {
//获取到头的第一个字符
var start = this.msg.substring(0, 1);
//获取到 后面的所有字符
var end = this.msg.substring(1);
//重新拼接得到新的字符串,并复制给this.msg
this.msg = end + start;
}, 400)
//注意: vm实例,会监听自己身上 data 中所有数据的变化,只要数据发生改变,就自动把最新数据,从data 上同步到页面中去
},
stop() {
clearInterval(this.intervalId);
//每当清除了定时器之后,需要重新把this.intervalId = null;
this.intervalId = null;
}
}
})
</script>
</body>
</html>
事件修饰符
- stop 阻止冒泡
- prevent 阻止默认事件
- capture 添加事件侦听器时使用事件捕获模式
- self 只当事件在该元素本身(比如不是子元素)触发时触发回调
- once 事件只触发一次
<!-- 使用 .stop 来阻止冒泡 -->
<!-- <div class="inner" @click="divHandler">
<input type="button" value="戳他" @click.stop="btnHandler">
</div> -->
<!-- 使用 .prevent 阻止默认行为 -->
<!-- <a href="http://www.baidu.com" @click.prevent="linkClick">有问题去百度</a> -->
<!-- 使用 .capture 实现捕获触发事件的机制
<div class="inner" @click.capture="divHandler">
<input type="button" value="戳他" @click="btnHandler">
</div> -->
<!-- 使用 .self 实现只有点击当前元素的时候,才会触发机制
<div class="inner" @click.self="divHandler">
<input type="button" value="戳他" @click="btnHandler">
</div> -->
<!-- 使用 .once 只触发一次事件处理函数
<a href="http://www.baidu.com" @click.prevent.once="linkClick">有问题去百度</a> -->
v-model 和 双向数据绑定
简易计算器案例
<body>
<div id="app">
<input type="text" v-model="n1">
<select v-model="opt">
<option value="0">+</option>
<option value="1">-</option>
<option value="2">×</option>
<option value="3">÷</option>
</select>
<input type="text" v-model="n2">
<input type="button" value="=" @click="calc">
<input type="text" v-model="result">
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
n1: 0,
n2: 0,
opt: '0',
result: 0
},
methods: {
calc() {
switch (this.opt) {
case '0':
this.result = parseInt(this.n1) + parseInt(this.n2);
break;
case '1':
this.result = parseInt(this.n1) - parseInt(this.n2);
break;
case '2':
this.result = parseInt(this.n1) * parseInt(this.n2);
break;
case '3':
this.result = parseInt(this.n1) / parseInt(this.n2);
break;
default:
break;
}
}
}
})
</script>
</body>
在vue中使用样式
使用class样式
- 数组
<h1 :class="['red', 'thin']"></h1>
- 数组中使用三元表达式
<h1 :class="['red','thin',isactive?'active':'']"></h1>
- 数组中嵌套对象
<h1 :class="['red','thin',isactive?'active':'']"></h1>
- 直接使用对象
<h1 :class="{red:true, italic:true, active:true, thin:true}"></h1>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="lib/vue.js"></script>
<style>
.red {
color: red;
}
.thin {
font-weight: 200;
}
.italic {
font-style: italic;
}
.active {
letter-spacing: 0.5em;
}
</style>
</head>
<body>
<div id="app">
<!-- <h1 class="red thin">这是一个H1,这是一个H1</h1> -->
<!-- 第一种使用方式,直接传递一个数组,注意:这里的 class 需要使用 v-bind 做数据绑定 -->
<!-- <h1 :class="['thin', 'italic']">这是一个H1,这是一个H1</h1> -->
<!-- 在数组中使用三元表达式 -->
<!-- <h1 :class="['thin', 'italic',flag?'active':'']">这是一个H1,这是一个H1</h1> -->
<!-- 在数组中使用 对象来代替三元表达式,提高代码的可读性 -->
<!-- <h1 :class="['thin', 'italic',{'active':flag}]">这是一个H1,这是一个H1</h1> -->
<!-- 在为 class 使用 v-bind 绑定对象的时候,对象的属性是类名,由于对象的属性可用引号,也可以不带引号,所以这里不写引号,属性的值 是一个标识符 -->
<h1 :class="classobj">这是一个H1,这是一个H1</h1>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
flag: true,
classobj: {
red: true,
thin: true,
italic: false,
active: false
}
},
methods: {}
})
</script>
</body>
使用内联样式
- 直接在元素上通过 :style 的形式,书写样式对象
- 将样式对象,定义到data中,并直接引用到 :style 中
- 在 :style 中通过数组,引用多个 data 上的样式对象
<body>
<div id="app">
<!-- 对象就是无序赋值对的集合 -->
<h1 :style="[styleObj1,styleObj2]">这是一个H1</h1>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
styleObj1: {
color: 'red',
'font-weight': '200'
},
styleObj2: {
'font-style': 'italic'
}
},
methods: {},
})
</script>
</body>
Vue指令之 v-for 和 key 属性
迭代数组
- 迭代普通数组
<body>
<div id="app">
<!-- <p v-for="item in list">{{item}}</p> -->
<p v-for="(item,i) in list">索引值:{{i}} --- 每一项:{{item}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
list: [1, 2, 3, 4, 5, 6]
},
methods: {
},
})
</script>
</body>
- 迭代对象数组
<body>
<div id="app">
<p v-for="(user,i) in list">索引:{{i}} --- ID:{{user.id}} --- 名字:{{user.name}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
list: [{
id: 1,
name: 'zs1'
}, {
id: 2,
name: 'zs2'
}, {
id: 3,
name: 'zs3'
}, {
id: 4,
name: 'zs4'
}, {
id: 5,
name: 'zs5'
}, ]
},
methods: {
},
})
</script>
</body>
迭代对象中的属性
<div id="app">
<!-- 注意:在遍历对象身上的键值对的时候,出了 有 val key ,在第三个位置还有一个 索引 -->
<p v-for="(val,key,i) in user">值:{{val}} --- 键:{{key}} --- 索引:{{i}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
user: {
id: 1,
name: 'tony',
gender: '男'
}
},
methods: {
},
})
</script>
注意:当在组件中使用 v-for 时,key 是必须写的
<div id="app">
<div>
<label for="">Id:
<input type="text" v-model="id">
</label>
<label for="">Name:
<input type="text" v-model="name">
</label>
<input type="button" value="添加" @click="add">
</div>
<!-- 注意: v-for循环的时候,key 属性只能使用 number获取string -->
<!-- 注意:key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值 -->
<!-- 在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果 v-for 有问题,必须 在使用 v-for 的同时,指定唯一的字符串/数字,类型:key 值 -->
<p v-for="item in list" :key="item.id">
<input type="checkbox">{{item.id}} --- {{item.name}}
</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
list: [{
id: 1,
name: '李斯'
}, {
id: 2,
name: '嬴政'
}, {
id: 3,
name: '赵高'
}, {
id: 4,
name: '韩非'
}, {
id: 5,
name: '荀子'
}]
},
methods: {
add() { //添加方法
// this.list.push({
// id: this.id,
// name: this.name
// })
this.list.unshift({
id: this.id,
name: this.name
})
}
},
})
</script>
迭代数字
这是第 {{count}} 次循环
Vue指令之 v-if 和 v-show
v-if 的特点:每次都会重新删除或创建元素
v-show 的特点:每次不会重新进行DOM的删除和创建,只是切换了元素的 display:none 样式
v-if 有较高的切换性能消耗
v-show 有较高的初始渲染消耗
如果元素涉及到频繁的切换,最好不要使用v-if
如果元素可能永远也不会被显示出来被用户看到,则推荐使用 v-if