VUE基础
1、vue是什么?
目前前端有三个非常流行的框架,非别是angularjs,reactjs,vuejs。而这三个当中,vuejs的受欢迎度目前是最高的,而开发vuejs的就是一个中国人尤雨溪。
其它框架的关联
- 借鉴angular的模板和数据绑定技术
- 借鉴react的组件化和虚拟DOM技术
基本概念
vue.js的官方文档中说vue是渐进式JavaScript框架。我们来一个一个解释其中的概念。
渐进式
vue全家桶其实是包含很多vue的扩展插件的,比如以下。
- vue-cli: vue脚手架
- vue-resource(axios): ajax请求
- vue-router: 路由
- vuex: 状态管理
- vue-lazyload: 图片懒加载
- vue-scroller: 页面滑动相关
- mint-ui: 基于vue的组件库(移动端)
- element-ui: 基于vue的组件库(PC端)
你可以一步一步有阶段性地来使用vue,不必一开始就使用所有的东西。这就是渐进式
。
JavaScript
:这个就不用多说了,也就是说vue本身是基于JavaScript的。
框架
我们之前经常用到一些插件,比如jQuery,swiper。我们来说一下,插件和框架之间的区别。
插件:提供某一个小功能,对项目的侵入性
较小,可以很容易切换到其它库实现需求。
框架
:是一套完整的解决方案,可以理解为一堆插件的集合;对项目侵入性较大,项目如果需要更换框架,则需要重构整个项目。
框架可以提高我们的开发效率,对于企业来说,时间就是金钱,效率就是一切。同样的工作,vue能节省很多时间,那多出来的时间我们就可以出去约女朋友,出去打游戏,是不是很爽?想得美,多的时间当然是干更多的活,你不努力,你的老板怎么换新车,换新房?
2、vue核心概念
数据驱动
通过数据驱动界面更新, 无需操作DOM来更新界面
遵循MVVM模式(关于什么是MVVM模式我们回头再说),使用Vue我们只需要关心如何获取数据, 如何处理数据, 如何编写业务逻辑代码,
我们只需要将处理好的数据交给Vue, Vue就会自动将数据渲染到模板中(界面上)
组件化开发
就像乐高积木,我们先创建我们需要的积木,然后通过积木拼接我们需要的图形。同样的,我们可以将网页拆分成一个个独立的组件来编写,再通过封装好的组件拼接成一个完整的网页。
3、vue的基本使用
3.1 引入方法
vue的使用可分为两种方法:
第一种:传统引入方法,下载vue.js文件,并在页面中引入。
第二种:使用vue-cli安装导入使用。
现阶段我们使用第一种方式即可,后面再说第二种方法的使用。
3.2 使用步骤
-
下载Vue框架
官方地址:https://cn.vuejs.org/
但是vue的官方下载地址是在GitHub上的,对于国内的同学来说,很多时候是无法访问的,所以我们可以通过菜鸟教程去下载。
https://www.runoob.com/vue2/vue-install.html
点击下载vue.js后,在新打开的页面中,右键选择另存为,选择下载地址即可成功下载。
-
导入Vue框架
<!--导入Vue.js --> <script src="js/vue.js"></script>
-
创建Vue实例对象
通过构造函数Vue就可以创建一个vue的实例。
// 创建一个Vue的实例对象 let vue = new Vue();
-
指定Vue实例对象控制的区域
<div id="app"> <p>{{ name }}</p> </div>
Vue的构造函数在调用时需要传入一个参数,该参数是一个对象,我们所有的和Vue相关的代码几乎都是写在这个对象中。
其中el是必不可少的一个选项。el的值可以是元素节点或者css选择器。其中css选择器的方式是我们用的最多的。
let vue = new Vue({ // 告诉Vue的实例对象, 将来需要控制界面上的哪个区域 el: '#app' //或者document.getElementById("app") });
-
指定Vue实例对象控制区域的数据
let vue = new Vue({ el: '#app', // 告诉Vue的实例对象, 被控制区域的数据是什么 data: { name: "李南江" } });
4、插值与表达式
双大括号{{}}
是最基本的文本插值方法,它会自动将我们vue实例中data属性中的数据取出,显示到我们的页面中。
<p>Hello {{msg}}</p>
let vm = new Vue({
el: '#app',
data: {
msg: "vue"
}
});
5、数据绑定
5.1 MVVM设计模式
我们在前面已经说了,Vue是遵循MVVM模式的,那什么是MVVM模式呢?
其实MVVM是Model-View-ViewModel的简写。
M : Model 【模型】指的是后端传递的数据。
V : View 【视图】指的是所看到的页面。
VM: View Model 【视图模型】mvvm模式的核心,它是连接view和model的桥梁。
它有两个方向:
一是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。
二是将【视图】转化成【模型】,即将所看到的页面转化成后端的数据。
这两个方向都实现的,我们称之为数据的双向绑定。
也就是说:
只要改变data中的数据值, 界面就自动更新 data ==> 模板页面
改变页面输入数据, data中的数据也可以自动改变 模板页面 ==> data
5.2 数据单向绑定
<!--这里就是MVVM中的View-->
<div id="app">
<p>{{ msg }}</p>
</div>
// 这里就是MVVM中的View Model
let vue = new Vue({
el: '#app',
// 这里就是MVVM中的Model
data: {
msg: "vue"
}
});
通过任何方法修改msg的值,HTML页面中的内容都会被实时替换。
比如我们可以直接在控制台中使用以下代码,那么p标签的内容也会随之变化。
vue.msg = "zhang"
【提示】:在data中书写的数据都会自动挂载到vue的实例中,所以我们可以直接使用实例对象来调用。
5.3 数据双向绑定
在input、textarea 等表单元素上可以用 v-model 指令创建双向数据绑定
<div id="app">
<input type="text" v-model="msg">
<p>hello,{{ msg }}</p>
</div>
<script>
// 这里就是MVVM中的View Model
let vue = new Vue({
el: '#app',
// 这里就是MVVM中的Model
data: {
msg: "vue"
}
});
</script>
在这里埋下一个坑,vue的双向绑定原理是什么?我们先不谈,过两天我们对vue使用熟了之后再回过头说说这个,这个也是面试中可能会被问到的点。
6、指令
指定是Vue模板中最常用的一项功能,是以v-开头的自定义标签属性。
6.1 v-text
想要将data中的数据显示在页面中,除了使用双大括号{{}}来进行插值外,还可以使用v-text
<span v-text="msg"></span>
<!-- 和下面的一样 -->
<span>{{ message }}</span>
new Vue({
el:"#app",
data : {
message : "今天天气不错"
}
})
v-text和插值表达式{{ }}的区别
v-text会覆盖元素中原本的内容,插值表达式{{ }}只会替换自己的这个占位符,不会把整个元素内容替换。
var app = new Vue({
el: '#app',
data: {
text:'hello'
}
})
<span v-text='text'>vue</span> <!-- vue会被覆盖,结果为 hello -->
<span>{{text}},vue</span><!--结果为 hello,vue -->
6.2 v-html
在上面的案例中,我们如果在msg的值为一个HTML标签字符串,等到页面加载时,并不会解析msg中的HTML代码,比如:
<div id="app">
{{ msg }}
</div>
<script>
let vue = new Vue({
el: '#app',
data: {
msg: "<h1>hello,vue</h1>"
}
});
</script>
在页面中,就会这样显示
如果我们想要页面去解析数据中的HTML代码,则可以使用v-html指向。
<div id="app" v-html="msg">
</div>
<script>
let vue = new Vue({
el: '#app',
data: {
msg: "<h1>hello,vue</h1>"
}
});
</script>
6.3 v-bind
作用:动态更新HTML元素上的属性。比如:ID,class,href,src等
格式:v-bind:属性名称="绑定的数据"
<img src="url"><!-- 错误写法 -->
<img v-bind:src="url">
var app = new Vue({
el:"#app",
data:{
url:"xxx.png"
}
})
语法糖
语法糖是指在不影响功能的情况下,使用某种方法实现同样的效果,从而方便程序的开发。就像我们小时候吃的糖豆,本质上是药,但是吃起来甜甜的,像是糖一样。
v-bind的使用格式使用语法糖的写法如下:
:属性名称="绑定的数据"
将上面HTML代码中的代码修改一下,效果是一样的。
<img v-bind:src="url">
6.4 v-on
作用:事件绑定。
格式:v-on:事件类型="函数名称"
它也有语法糖的写法:省略v-on:使用@符号代替
@事件类型="函数名称"
<button v-on:click="myFn()">我是按钮</button>
<!-- 两者一样一样的 -->
<button @click="myFn()">我是按钮</button>
我们需要将事件函数写在vue实例中的method属性中。
let vue = new Vue({
el: '#app',
//函数需要写在这里
methods: {
myFn(){
alert('你点击了按钮')
}
}
});
参数
可以给绑定的回调函数传递参数
访问数据
如果在绑定的函数中需要用到data中的数据必须加上this
事件对象
@click调用的方法名后跟不跟括号都可以,如果该方法有参数,我们又没有书写括号参数,默认会将原生事件对象event传入。
<button @click="myFn">我是按钮</button>
let vue = new Vue({
el: '#app',
//函数需要写在这里
methods: {
myFn(param){
console.log(param)
}
}
});
可以看看param打印出来的结果是什么
这不就是事件对象吗!
那如果方法有参数,我们也需要事件对象进行处理,比如阻止a标签的默认行为。那该如何做呢?
vue提供了一个特殊变量$event,用于访问原生DOM事件。比如:
<a href="http://www.baidu.com" @click="myFn('禁止跳转',$event)">我是按钮</a>
let vue = new Vue({
el: '#app',
methods: {
myFn(msg,event){
event.preventDefault();
console.log(msg)
}
}
});
修饰符
上面的案例,我们也可以用修饰符来做。在@绑定的事件后添加小圆点‘.’,再跟一个后缀来使用修饰符。
常见的修饰符如下:
- stop:阻止冒泡
- prevent:阻止浏览器默认行为
- once:只触发一次。
<div class="a" @click="myFn1">
<div class="b" @click.stop="myFn2">
<div class="c" @click="myFn3"></div>
</div>
</div>
let vue = new Vue({
el: '#app',
methods: {
myFn1(){
console.log("爷爷");
},
myFn2(){
console.log("爸爸");
},
myFn3(){
console.log("儿子");
}
}
});
在表单元素上监听键盘事件时,还可以使用按键修饰符,比如按下某个具体的键才调用方法:
<!-- 只有在keycode是13,也就是回车键时才会调用myFn函数 -->
<input @keyup.13="myFn">
6.5 v-if
条件渲染: 如果v-if取值是true就渲染元素, 如果为false就不渲染元素(dom不存在)
v-if可以从模型中获取数据,也可以直接赋值一个表达式
<p v-if="show">显示</p>
<p v-if="age >= 18">网吧欢迎你</p>
let vue = new Vue({
el: '#app',
data: {
show: true,
age: 17,
}
});
v-else指令
v-else可以和v-if指令配合使用, 当v-if不满足条件时就执行v-else就显示v-else中的内容
<p v-if="age >= 18">网吧欢迎你</p>
<p v-else>从后门进来</p>
let vue = new Vue({
el: '#app',
data: {
age: 17,
}
});
v-else-if指令
v-else-if可以和v-if指令配合使用, 当v-if不满足条件时就依次执行后续v-else-if, 哪个满足就显示哪个
<p v-if="score >= 80">优秀</p>
<p v-else-if="score >= 60">良好</p>
<p v-else>差</p>
let vue = new Vue({
el: '#app',
data: {
score: 70,
}
});
【注意点】
- v-if,v-else和 v-else-if之间不能有其它内容
- v-else和 v-else-if 不能单独出现
6.6 v-show
条件渲染指令
如果表达式为真,则显示该元素,如果为假,则隐藏该元素(dom存在)
<p v-show="show">显示</p>
<p v-show="age >= 18">网吧欢迎你</p>
let vue = new Vue({
el: '#app',
data: {
show: true,
age: 17,
}
});
v-if和v-show应用场景
v-if取值为false时不会创建元素, 所以如果需要切换元素的显示和隐藏, 每次v-if都会创建和删除元素
v-show取值为false时会创建元素并设置display为none, 所有如果需要切换元素的显示和隐藏,
不会反复创建和删除, 只是修改display的值
所以: 如果企业开发中需要频繁切换元素显示隐藏, 那么推荐使用v-show, 否则使用v-if
6.7 v-for
列表渲染指令
当需要将一个数组遍历或枚举一个对象的属性时,我们就可以使用v-for指令。有些类似于for in循环。
<div id="app">
<ul>
<li v-for="user in users">{{user.name}}</li>
</ul>
</div>
let vue = new Vue({
el: '#app',
data: {
users:[
{name:"张三"},
{name:"李四"},
{name:"王五"}
]
}
});
v-for还支持一个可选的参数作为当前项的索引,比如将上面的HTML代码修改一下:
<div id="app">
<ul>
<li v-for="(user,index) in users">{{index}}-{{user.name}}</li>
</ul>
</div>
除了数组以外,v-for还可以遍历,字符串,数字和对象。
<div id="app">
<ul>
<li v-for="value in person">{{value}}</li>
</ul>
</div>
let vue = new Vue({
el: '#app',
data: {
person:{
name:"张三",
age:"20",
habby:"看美女"
}
}
});
遍历对象属性时,有两个可选参数,分别表示键名和索引。
<li v-for="(value,key,index) in person">{{index}}----{{key}}-----{{value}}</li>
遍历整数:
<span v-for="n in 10">{{n}}</span>
数组更新
Vue 的核心是数据与视图的双向绑定,当我们修改数组时,Vue会检测到数据变化,所以用v-for 渲染的视图也会立即更新。
会修改源数组的数组方法:
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
不会修改源数组的数组方法:
- filter()
- concat()
- slice
需要注意的是,以下变动的数组中, Vue 是不能检测到的,也不会触发视图更新:
- 通过索引直接设置项,比如 app.books[3] = { … }.
- 修改数组长度,比如叩p.books.length = 1.
解决第一个问题可以用 Vue 内置的 set 方法:
Vue.set(app.books,3,{
id:"3",
name:"诡秘之主"
})
排序案例:
<div id="app">
<ul>
<li v-for="(p, index) in persons">
{{p.id}}--{{p.name}}--{{p.age}}
</li>
</ul>
<button @click="sortType(1)">按年龄升序</button>
<button @click="sortType(2)">按年龄降序</button>
</div>
new Vue({
data: {
sortType: 1, // 排序的类型, 1: 升序, 2: 降序
persons: [
{id: 1, name: 'Tom', age: 15},
{id: 2, name: 'Jack', age: 12},
{id: 4, name: 'Bob', age: 17},
{id: 6, name: 'Rose', age: 16},
{id: 8, name: 'Else', age: 13}
],
},
methods: {
sortType (type) {
arr.sort((p1, p2) => {
if (type===1) { // 升序
return p1.age - p2.age
} else { // 降序
return p2.age - p1.age
}
})
return arr
}
},
})
6.8 v-once
vue是双向绑定的,如果数据发生变化,视图也会发生变化,如果你不想让vue中的视图发生变化,就可以使用v-once指令。
作用:定义它的元素或组件只渲染一次,包括元素或组件的所有子节点。首次渲染后,不再随数据的变化重新渲染,将被视为静态内容。
<div id="app">
<p v-once>原始数据: {{ name }}</p>
<p>当前数据: {{ name }}</p>
</div>
let app = new Vue({
el: '#app',
data: {
name: "zhangsan",
}
});
此时我们在控制台中输入
app.name="lisi"
你会发现,第一个p标签中的内容并没有变化。第二个p标签中的内容会随着数据变化而变化。这就是v-once的用处。
7、表单数据绑定
Vue 提供了`v-model`指令,用于在表单类元素上双向绑定数据,例如在输入框上使用时,输入的内容会实时映射到绑定的数据上。关于表单中的输入框,我们之前的案例已经演示过了。这里不再多说,接下来我们来说下其他的表单元素,
7.1 单选框
多个单选框如果想要达到互斥的效果,也就是说想成为一组,它们v-model的值必须相等。
<div id="app">
<input type="radio" value="html" v-model="inputdata" />html<br>
<input type="radio" value="css" v-model="inputdata"/> css<br>
<input type="radio" value="javascript" v-model="inputdata" />javascript<br>
</div>
var app = new Vue({
el:"#app",
data:{
inputdata:"javascript"
}
})
当data中的数据与单选按钮的value值一致时,该单选按钮将会被选中。
7.2 复选框
复选框的使用可以分为单独使用和组合使用。
7.2.1 单独使用
在input标签中,使用v-model来绑定一个布尔值。在被勾选时,被绑定的数据data的值就变为了 true, 反之,则变成了false;
<div id="app">
<input type="checkbox" v-model="isChecked"/>同意协议<br>
<p>选择状态:{{isChecked}}</p>
</div>
var app = new Vue({
el:"#app",
data:{
isChecked:false
}
})
7.2.2 组合使用
组合使用时,也是 v-model
和value
一起使用,多个勾选框都绑定到同一个数组类型的数据,注意,必须是同一个,而且是数组类型。举例如下:
<div id="app">
<input type="checkbox" v-model="checkData" value="诛仙"/>诛仙<br>
<input type="checkbox" v-model="checkData" value="无限恐怖"/>无限恐怖<br>
<input type="checkbox" v-model="checkData" value="惊悚乐园"/>惊悚乐园<br>
<p>
您选择的是:{{checkData}}
</p>
</div>
var app = new Vue({
el:"#app",
data:{
checkData:["无限恐怖","惊悚乐园"];
}
})
在多选框被勾选时,它的值就会被push到绑定的数据checkData中,这一过程是双向的,也就是说修改checkData中的值,也会更新多选框的选中状态。
7.3 下拉框
下拉框也分为单选和多选
7.3.1 单选
先来看实例代码
<div id="app">
<select v-model="isSelected">
<option value="诛仙">诛仙</option>
<option value="无限恐怖">无限恐怖</option>
<option value="封不觉">惊悚乐园</option>
</select>
</div>
var app = new Vue({
el:"#app",
data:{
isSelected:"诛仙"
}
})
下拉框也就是下拉列表,v-model需要绑定在select标签中。option标签是必选项,之前学HTML的时候我们知道,select的值是由被选中的option选项的value属性决定的。但是在vue中,如果我们没有value,那么数据将会匹配被选中option的文本内容。也就是说,如果选中了第三个选项,则isSelected的值将是 `封不觉` 而不是 `惊悚乐园`
7.3.2 多选
给select标签添加 multiple属性 就可以多选了,此时v-model绑定的是一个数组,与复选框用
法类似。
<div id="app">
<select v-model="isSelected" multiple>
<option value="诛仙">诛仙</option>
<option value="无限恐怖">无限恐怖</option>
<option value="封不觉">惊悚乐园</option>
</select>
<p>
您选择的是:{{checkData}}
</p>
</div>
var app = new Vue({
el:"#app",
data:{
isSelected:["诛仙","无限恐怖"]
}
})