vue学习笔记(一) ---- vue指令(总体大纲)
一、什么是Vue
官方文档:https://cn.vuejs.org/v2/guide/
关键字:
渐进式框架
自底向上增量开发
视图层
单文件组件
复杂的单页应用
复杂的单页应用
: 顾名思义,单页应用一般指的就是一个页面就是应用,当然也可以是一个子应用,比如说知乎的一个页面就可以视为一个子应用。单页应用程序中一般交互处理非常多,而且页面中的内容需要根据用户的操作动态变化。
组合的视图组件
: Vue.js通过组件,把一个单页应用中的各种模块拆分到一个一个单独的组件(component)中,我们只要先在父级应用中写好各种组件标签(占坑),并且在组件标签中写好要传入组件的参数(就像给函数传入参数一样,这个参数叫做组件的属性),然后再分别写好各种组件的实现(填坑),然后整个应用就算做完了。
响应式数据绑定
:换句话说,p标签里面通过{{ message }}这个写法与input标签中的value绑定在了一起,其中变化,另外一个和它绑定的数据就跟着变化。
Vue的简单介绍:
- Vue.js 是前端的主流框架之一,目前和Angular.js、React.js 一起,并成为前端三大主流框架!
- Vue.js 是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue有配套的第三方类库,可以整合起来做大型项目的开发)
- Vue.js是一个轻巧、高性能、可组件化的MVVM库,同时拥有非常容易上手的API。
- Vue 完全有能力驱动采用单文件组件和 Vue 生态系统支持的库开发的复杂单页应用。
- Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
参考博客:https://blog.csdn.net/liang377122210/article/details/71545459
二、Vue与其他框架/库的区别
官方文档:https://cn.vuejs.org/v2/guide/comparison.html
三、Vue作为前端框架的特点
- 构建用户界面,只需要关系view层
- 简单易学,轻量快速
- 渐进式框架
四、 为什么要学习流行框架
- 企业中,使用框架,能够提高开发的效率;
- 提高开发效率的发展历程:
原生JS -> Jquery之类的类库 -> 前端模板引擎 -> Angular.js / Vue.js(能够帮助我们减少不必要的DOM操作;提高渲染效率;双向数据绑定的概念【通过框架提供的指令,我们前端程序员只需要关心数据的业务逻辑,不再关心DOM是如何渲染的了】) - 在Vue中,一个核心的概念,就是让用户不再操作DOM元素,解放了用户的双手,让程序员可以更多的时间去关注业务逻辑;
五、框架和库的区别
- 框架:是一套完整的解决方案;对项目的侵入性较大,如果我们的项目在开发的时候选择了一款框架后,当开发到中期或者后期的时候,如果想更换其他框架的话,就需要重新架构整个项目。比如,如果在node中选择了express作为后端开发框架,如果想摒弃express而选择原生的http模块去搞后端开发,这时候整个项目需要重新架构,框架的好处在于,提供一整套的API
- 库(插件):提供某一个小功能,对项目的侵入性较小,如果我们在开发过程中发现某些库在某些方面有功能的限制,并不能完全满足我们的项目需求,那我们就可以很容易切换到其它库实现需求。
比如:从Jquery 切换到 Zepto 或者 从 EJS 切换到 art-template
六、 Node(后端)中的 MVC 与 前端中的 MVVM 之间的区别
MVC 是后端的分层开发概念:
M
:也就是我们的Model层,主要处理数据的C(create)
R(read)
U(update)
D(delete)
也就是增删改查V
:视图层View ,一般把它看作是前端页面C
:是业务逻辑层Controller,其实路由也可以看作是业务逻辑层的一小部分,比如登录,注销等业务的逻辑
MVVM是前端视图层的概念:
- 主要关注于 视图层分离,也就是说:MVVM把前端的视图层,分为了 三部分 Model, View , ViewModel
M
:Model层,这里的M保存的是每个页面中单独的数据V
:View层VM
:View+Model的集合,是一个调度者,分割了M和V,每当V层想要获取和保存的时候,都要由VM做中间的处理,前端页面中使用了MVVM的思想,主要是为了让我们开发更加方便,因为MVVM提供了数据的双向数据绑定,数据的双向绑定是由VM提供的
MVC和MVVM的关系图解
七、hello world
1. 安装vue
方法一:通过npm来安装(前提已经下载了node.js和npm)
$ npm install vue
方法二:script标签导入
<script src="xxxxx"></srcipt>
2.创建容器
创建一个区域,使用vue就可以用来控制或操作这个区域(容器)中的所有DOM元素
<div id="app">
</div>
3.创建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元素了
}
})
也可以这样来写:
var vm = new Vue({
data: {
msg: '欢迎学习Vue'
}
});
vm.$mount('#app')
栗子:
<!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="./vue2.6.10.min.js"></script>
</head>
<body>
<div id="app">
<p>{{ msg }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '欢迎学习Vue'
}
})
</script>
</body>
</html>
来吧展示:
八、v-cloak
在没有使用v-cloak之前,页面如果切换到网速很慢的情况下去运行文件的话,页面的hello vue会出现闪烁 (也就是一打开页面不会立马出现hello vue而每次刷新页面的时候都会在 {{msg}} 和 hello vue 之间闪烁)
的问题
之前:
<div id="app">
<p>{{ msg }}</p>
</div>
给p标签加上v-clock属性再之后:
<!--要给v-cloak设置一下style-->
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app">
<p v-cloak>{{ msg }}</p>
</div>
.......
</body>
九、v-text
与插值表达式一样
<div id="app">
<p v-cloak>{{ msg }}</p>
<h1 v-text="msg"></h1>
</div>
十、插值表达式与v-text的区别
- 如果插值表达式不设置v-cloak的话,会有闪烁的问题
但是v-text默认没有闪烁的问题 - 插值表达式可以在前后放任意的内容,v-text不能
<div id="app">
<p v-cloak>-------- {{ msg }} --------</p>
<h1 v-text="msg">---------</h1>
</div>
如果v-text还没有被解析的话,那么h1的--------
就会被解析,如果解析到了v-text
执行,那么msg
中的hello vue
就会把-------
覆盖
总结:
v-text会覆盖元素中原本的内容,但是 插值表达式 只会替换自己的这个占位符,不会把 整个元素的内容清空
十一、v-html,v-text与插值表达式的区别
<body>
<div id="app">
<p v-cloak>------ {{ msg }} ------</p>
<h1 v-text="msg">---------</h1>
<div>{{msg2}}</div>
<div v-text="msg2"></div>
<div v-html="msg2"></div>
</div>
<script src="./vue2.6.10.min.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: 'hello vue',
msg2:'<h2>哼~~~~谁还不是一个可爱的小公主呢</h2>'
}
})
</script>
</body>
来吧展示:
总结:
1.v-text
和v-html
都会覆盖元素中原本的内容,插值表达式
不会覆盖,可以在前面添加任意内容
2.v-text
和插值表达式
只会在页面渲染字符串的内容,不会识别并渲染出带有标签形式的内容,v-html
会以标签的形式去渲染页面内容
十二、v-bind
属性绑定
参考博客: https://www.cnblogs.com/Chinatsu/p/13870619.html
十三、v-on
事件绑定
参考博客 : https://www.cnblogs.com/Chinatsu/p/13870633.html
十四、浪起来~~~哦耶 的案例
参考博客:https://www.cnblogs.com/Chinatsu/p/13870648.html
十五、v-model
实现数据双向绑定
<body>
<div id="app">
<p>{{ msg }}</p>
<!-- <input type="text" v-bind:value="msg"/> -->
<!--简写成:-->
<input type="text" :value="msg"/>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'我怎么这么好看!!!'
}
})
</script>
</body>
注意:
v-bind只能是实现把data中的数据渲染到绑定的属性中渲染到页面上,不能把数据逆向的同步到data属性中
所以v-bind只能实现数据的单项绑定,从data自动同步到 view上
想要实现双向数据绑定 v-model,当前元素中的值已经和data中的数据做了双向绑定
也就是说data会把自己的值同步到文本框中去,然后监听文本框的改变,自动同步回去
<body>
<div id="app">
<p>{{ msg }}</p>
<!-- <input type="text" :value="msg"/> -->
<input type="text" v-model="msg"/>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'我怎么这么好看!!!'
}
})
</script>
</body>
来吧展示:
总结:
- v-bind只能是实现把data中的数据渲染到绑定的属性中渲染到页面上,不能把数据逆向的同步到data属性中
- 所以v-bind只能实现数据的单项绑定,从data自动同步到 view上
- 想要实现双向数据绑定 v-model,当前元素中的值已经和data中的数据做了双向绑定
- 也就是说data会把自己的值同步到文本框中去,然后监听文本框的改变,自动同步回去
- 在vue中,只有v-model实现了数据的双向绑定,其他的都没有
而且v-model只能应用在表单元素中
表单元素包括input radio text checkbox textarea select
十六、简易的计算器案例
方法一:
<!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="./vue2.6.10.min.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="n1"/>
<select v-model="opt">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="text" v-model="n2"/>
<input type="button"/ value="=" @click="cal()">
<input type="text" v-model="res"/>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
n1:0,
opt:'+',
n2:0,
res:0
},
methods:{
//calculation计算
cal(){
switch (this.opt) {
case '+':
this.res = parseInt(this.n1) + parseInt(this.n2)
break;
case '-':
this.res = parseInt(this.n1) - parseInt(this.n2)
break;
case '*':
this.res = parseInt(this.n1) * parseInt(this.n2)
break;
case '/':
this.res = parseInt(this.n1) / parseInt(this.n2)
break;
}
}
}
})
</script>
</body>
</html>
方法二:
methods:{
//calculation计算
cal(){
var codeStr = 'parseInt(this.n1) ' + this.opt + ' parseInt(this.n2)'
this.res = eval(codeStr)
}
}
来吧展示:
十七、事件修饰符 ---- .stop
阻止冒泡
<style>
#innner{
background-color: pink;
width: 400px;
height: 200px;
}
</style>
<body>
<div id="app">
<div id="innner" @click="innerClick()">
<input type="button" value="按钮" @click="btnClick"/>
</div>
</div>
<script src="./vue2.6.10.min.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
},
methods: {
innerClick(){
console.log('这是inner外部的点击事件')
},
btnClick(){
console.log('这是btn的点击事件')
}
}
})
</script>
</body>
冒泡机制的影响:
如果给外层div绑定一个点击事件,按钮也有一个点击事件,事件各不相同,
但是触发按钮的点击事件的话,div的点击事件也会相应的触发
如果不想让内部的事件冒泡到外部去执行,vue怎么解决 ?
解决方法:
事件修饰符 .stop
<div id="innner" @click="innerClick()">
<input type="button" value="按钮" @click.stop="btnClick"/>
</div>
十八、事件修饰符 ----- .prevent
阻止默认事件
<body>
<div id="app">
<a href="http://www.baidu.com" @click="linkClick">百度一下,我还是什么都不知道</a>
<script src="./vue2.6.10.min.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
},
methods: {
linkClick(){
console.log('okkkkkk')
}
}
})
</script>
</body>
超链接有自己的默认行为,因为请求中间有个延时,所以它会先触发点击事件,然后默认行为紧接着就会跟着触发
来吧展示:
vue怎么解决阻止默认行为
<a href="http://www.baidu.com" @click.prevent="linkClick">百度一下,我还是什么都不知道</a>
来吧展示:
阻止表单默认行为
<body>
<div id="app">
<!-- <a href="http://www.baidu.com" @click.prevent="linkClick">百度一下,我还是什么都不知道</a> -->
<form @submit="formClick()">
<input type="text" value="" name="name" />
<input type="text" value="" name="password"/>
<input type="submit" value="提交"/>
</form>
</div>
<script src="./vue2.6.10.min.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
},
methods: {
// linkClick(){
// console.log('okkkkkk')
// }
formClick(){
console.log('触发了表单的submit事件')
}
}
})
</script>
</body>
没有处理之前:
.prevent阻止之后:
<form @submit.prevent="formClick()">
<input type="text" value="" name="name" />
<input type="text" value="" name="password"/>
<input type="submit" value="提交"/>
</form>
十九、事件修饰符 ----- .capture
添加事件侦听器时使用事件捕获模式
<style>
#innner{
background-color: pink;
width: 400px;
height: 200px;
}
</style>
</head>
<body>
<div id="app">
<div id="innner" @click.capture="innerClick()">
<input type="button" value="按钮" @click="btnClick"/>
</div>
//捕获:先触发外层div的点击事件再触发自己的input点击事件
//注意:事件捕获执行和事件冒泡执行只能存在一个
</div>
<script src="./vue2.6.10.min.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
},
methods: {
innerClick(){
console.log('这是inner外部的点击事件')
},
btnClick(){
console.log('这是btn的点击事件')
}
}
})
</script>
</body>
二十、事件修饰符 ----- .self
只有事件在该元素本身触发时才触发回调
<div id="app">
<div id="innner" @click.self="innerClick()">
<input type="button" value="按钮" @click="btnClick"/>
</div>
</div>
self只有点击的时当前的元素才能触发点击事件,当给inner加上self时,
当点击按钮,只有按钮的btnClick事件才会被触发
二十一、事件修饰符 ----- .once
事件只执行一次
<div id="app">
<div id="innner" @click.capture="innerClick()">
<input type="button" value="按钮" @click.once="btnClick"/>
</div>
</div>
来吧展示:
二十二、.self
与 .stop
的区别
从效果上来看,两者都可以做到阻止冒泡
<div id="innner" @click="innerClick()">
<input type="button" value="按钮" @click.stop="btnClick"/>
</div>
<div id="innner" @click.self="innerClick()">
<input type="button" value="按钮" @click.once="btnClick"/>
</div>
他们之间的区别在于
.stop
<style>
#out{
background-color: hotpink;
width:400px;
height: 300px
}
#innner{
background-color: pink;
width: 300px;
height: 200px;
}
</style>
</head>
<body>
<div id="app">
<div id="out" @click="outClick">
<div id="innner" @click="innerClick()">
<input type="button" value="按钮" @click.stop="btnClick"/>
</div>
</div>
</div>
<script src="./vue2.6.10.min.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
},
methods: {
innerClick(){
console.log('这是inner外部的点击事件')
},
btnClick(){
console.log('这是btn的点击事件')
},
outClick(){
console.log('这是out最外部的点击事件')
}
}
})
</script>
</body>
.stop
阻止全部的冒泡行为(全管)
.self
<div id="app">
<div id="out" @click="outClick">
<div id="innner" @click.self="innerClick()">
<!--<input type="button" value="按钮" @click.stop="btnClick"/>-->
<input type="button" value="按钮" @click="btnClick"/>
</div>
</div>
input执行自己的事件
inner并不是事件源,所以没有触发自己的点击事件
out最外部被冒泡执行
.self
(自管自己,别的我不管)
各司其职:
<div id="app">
<div id="out" @click="outClick">
<div id="innner" @click.stop="innerClick()">
<input type="button" value="按钮" @click.stop="btnClick"/>
</div>
</div>
来吧展示:
二十三、在vue中使用样式的方式
参考博客:https://www.cnblogs.com/Chinatsu/p/13870761.html
二十四、vue指令之v-for
和key
属性
参考博客:https://www.cnblogs.com/Chinatsu/p/13870747.html
二十五、v-if
和v-show
的使用
当点击按钮的时候设置下面的h标签的显示和隐藏,显示ture则显示,显示flase则隐藏:
<div id="app">
<p>{{flag}}</p>
<input type="button" value="点击切换" @click="flag=!flag"/>
<h2 v-if="flag">我是v-if的-----------哈哈哈哈哈哈哈哈哈</h2>
<h3 v-show="flag">我是v-show的-----------嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿</h3>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
flag:true
},
methods:{
tooggle(){
this.flag = !this.flag
}
}
})
</script>
来吧展示:
通过展示可以看到两者的作用效果看起来是一致的,但是他们有本质上的区别
相同点:v-if和v-show的作用只有一个:根据指定的标识符,切换元素的显示和隐藏状态
两者的区别:
v-if是实时的创建元素,从而达到元素的显示和隐藏
v-show是通过为元素添加或隐藏 display:none来显示元素的显示和隐藏
如果需要经常的切换元素的显示和隐藏的状态,那么v-show的效率会高一些
如果元素被创建出来之后,可能不会进行状态的切换
v-if的话,假设状态值一上来就是false,页面一打开默认是false,根据条件发现并不需要被创建,能够减少元素性的创建后造成的损耗
如果是v-show的话,哪怕不会显示,但是元素也已经被创建了
总结:v-if有更高的切换消耗而v-show有更高的初始渲染消耗(v-if初始为false不会创建元素,v-show初始为false,也会创建元素),因此,如果需要频繁切换,使用v-show,如果在运行时条件不大可能改变时,使用v-if
二十六、菜单列表案例(添加和查找)
参考博客:https://www.cnblogs.com/Chinatsu/p/13870733.html