什么是Vue
是目前最火的前端框架,React是最流行的一个前端框架 (React除了开发网站,还可以开发手机App,Vue语法也可以用户进行手机App开发的,需要借助于Weex)
vue.js是前端主流框架之一,和Angular.js、React.js一起,并称为前端主流三大框架!
vue.js,不仅容易上手,还便于与第三方你库或既有项目整合。
前端主要工作,主要负责mvc中的v这一层;主要工作是和界面打交道;
为什么要学习流行框架
- 企业为了提高开发效率:在企业中,时间就是效率,效率就是金钱;
- 提高开发效率的历程:原生js --jquery之类的类库—前端模板引擎—Angular.js/Vue.js
- 在Vue中,一个核心的概念,就是让用户不再操作DOM元素,解放了用户的双手,让程序员可以更多 的时间去关注业务逻辑;
框架和库的区别
- 框架:是一套完整的解决方案;对项目的侵入性较大,项目如果需要换框架,则需要重新架构整个项目。
- 库(插件):提供某一个小功能,对项目的侵入性较小,如果开某个库无法完成某些需求可以很容易切换到其它库实现需求
MVC和MVVM的区别
- MVC是后端分层开发的概念
- MVVM是前端视图层的概念,主要关注于视图层分离,也就是说:MVVM把前端视图层,分喂了三部分Model,VIew,VM ViewModel
Vue.js基本代码和MVVM之间的对应关系
<!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提供的指令,很方i版的就能把数据渲染到页面上,程序员不再手动操作DOM元素【前端的Vue之类的框架,不提倡我们去手动操作DOM元素了】
}
})
</script>
</body>
</html>
v-cloak,v-text,v-html
<!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>
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<!-- 将来new 的Vue实例,会控制这个元素中的所有内容 -->
<!-- Vue 实例所控制的这个元素区域,就是我们的V -->
<div id="app">
<!-- 使用v-cloak 能够解决插值表达式闪烁的问题 -->
<p v-cloak >{{ msg }}</p>
<!-- 默认 v-text 是没有闪烁问题的 -->
<!-- v-text 会覆盖元素原本的内容,但是插值表达式只会替换自己的这个占位符,不会把整个元素的内容清空 -->
<h4 v-text='msg'></h4>
<!-- v-html会把字符串当作html代码来处理 -->
<div v-html='msg2'></div>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'123',
msg2:'<h1>ljlj;jlk;jl;jkl;j;l</h1>'
}
})
</script>
</body>
</html>
跑马灯例子
<!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>
<!-- 2.创建一个控制区域 -->
<div id="app">
<input type="button" value="浪起来" @click="lang">
<input type="button" value='别浪' @click="stop">
<h4>{{msg}}</h4>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'猥琐发育,别浪',
intervalId:null//在data上定义定时器id
},
methods:{
lang(){//es6的方法格式
console.log(this.msg)//在vm实例中,如果想要获取data上的数据,或者想要调用methods中的方法,必须通过this.属性名或者this.方法名来进行访问。这里的this就表示我们new出来的vm实例
if(this.intervalId!==null)return;
this.intervalId = setInterval(()=>{//es6语法,这时候内部的this就指向了外部的this
//获取到头一个字符
var start = this.msg.substring(0,1)
//获取到后面的所有字符
var end = this.msg.substring(1)
//重新拼接得到新的字符串,并赋值给this.msg
this.msg = end + start
//注意:vm实例,会监听自身上data中所有数据的改变,只要数据一发生改变,就会自动把最新的数据,从data上同步到页面中去(好处:减少了程序员对dom的操作,只需要关心数据不需要考虑如何重新渲染页面)
},400)
},
stop(){//停止定时器
clearInterval(this.intervalId)
//停止定时器之后需要把intervalId重新赋值为null
this.intervalId = null;
}
}
})
//分析:
//1.给【浪起来】按钮,绑定一个事件
//2.在按钮的事件处理函数中,写相关的业务处理代码:拿到msg字符串,然后调用字符串substring方法来进行字符串的街区操作,把第一个字符截取出来,放到最后一个位置即可;
//3.为了实现点击按钮,自动截取的功能,需要把2步骤中的代码,放到一个定时器中去
</script>
</body>
</html>
事件修饰符
-
.stop 阻止冒泡
-
.prevent 阻止默认事件
-
.capture 添加事件监听器时使用事件捕获模式
-
.self 只当事件在该元素本身(比如不是子元素)触发时触发回调
-
.once 事件只触发一次
.self只会阻止自己身上冒泡行为的触发,并不会真正阻止冒泡行为
v-model及简易计算器案例
<!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">
<h4>{{msg}}</h4>
<!-- v-bind 只能实现数据的单向绑定,从M 自动绑定到view,无法实现数据的双向绑定 -->
<!-- <input type="text" :value="msg" style="width:100%;"> -->
<!-- 使用v-model指令,可以实现 表单元素和Model中的数据双向绑定 -->
<!-- 注意:v-model只能运用在表单元素中例如:input、select、checkbox、textarea等 -->
<input type="text" v-model="msg" style="width:100%;">
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'开心起来把。'
},
methods:{
}
})
</script>
</body>
</html>
简易计算器
<!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="text" v-model="n1">
<select name="" id="" 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="calc">
<input type="text" v-model="result">
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
n1:0,
n2:0,
result:0,
opt:'+'
},
methods:{
calc(){
// switch(this.opt){//方式一
// case '+':
// this.result = parseInt(this.n1) + parseInt(this.n2);
// break;
// case '-':
// this.result = parseInt(this.n1) - parseInt(this.n2);
// break;
// case '*':
// this.result = parseInt(this.n1) * parseInt(this.n2);
// break;
// case '/':
// this.result = parseInt(this.n1) / parseInt(this.n2);
// break;
// }
var codeStr = 'parseInt(this.n1)' + this.opt + 'parseInt(this.n2)'//方式二
this.result = eval(codeStr)
}
}
})
</script>
</body>
</html>
在Vue中使用样式
<!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>
<style>
.red{
color:red;
}
.thin{
font-weight: 200;
}
.italic{
font-style: italic;
}
.active{
letter-spacing: 0.5em;
}
</style>
</head>
<body>
<div id="app">
<!-- 第一种使用方式,直接传递一个数组,注意这里class需要是以哦那个 v-bind 做数据绑定 -->
<h1 :class="['thin','italic']">直接传递一个数组</h1>
<!-- 在数组中使用三元表达式 -->
<h1 :class="['thin','italic',flag?'active':'']">在数组中使用三元表达式</h1>
<!-- 在数组中使用对象来代替三元表达式,提高代码可读性 -->
<h1 :class="['thin','italic',{'active':flag}]">在数组中使用对象来代替三元表达式</h1>
<!-- 在为 class 使用v-bind绑定对象的时候,对象的属性类名,由于对象的属性可带银行,也可以不带银行,所以这里我没写引号; 属性的值是一个标识符 -->
<!-- <h1 :class="{red:true,thin:true,italic:false,active:false}">在数组中使用对象来代替三元表达式</h1> -->
<h1 :class="classObj">在数组中使用对象来代替三元表达式</h1>
<!-- 使用内联样式 -->
<!-- 对象就是无序键值对的集合 -->
<h1 :style="{color:'red','font-weight':200}">这是一个h1</h1>
<h1 :style="styleObj1">styleObj1</h1>
<!-- 对象的数组 -->
<h1 :style="[styleObj1,styleObj2]">对象的数组</h1>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
flag:true,
classObj:{red:true,thin:true,italic:false,active:false},
styleObj1:{color:'red','font-weight':200},
styleObj2:{'font-style':'italic'}
},
methods:{
}
})
</script>
</body>
</html>
v-for和key属性
<!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">
<!-- 普通数组 -->
<p v-for="(item,i) in list">索引值:{{i}} 每一项:{{item}}</p>
<!-- 对象数组 -->
<p v-for="(user,i) in list2">索引:{{i}}--{{user.id}}-----{{user.name}}</p>
<!-- 遍历对象,除了有key,val,在第三个位置还有一个索引值 -->
<p v-for="(val,key,i) in user">索引:{{i}} 值:{{val}} 键:{{key}}</p>
<!-- 迭代数字,in后面我们可以放普通数组,对象数组,对象,还可以放数字,如果使用v-for迭代数字,count值从1开始 -->
<p v-for="count in 10">这是第{{count}}次循环</p>
<!-- 注意:v-for循环的时候,key属性只能使用number获取string
key在使用的时候,必须使用v-bind属性绑定的形式,指定key的值
在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果v-for有问题,必须在是以哦那个
v-for的同事,指定唯一的字符串/数字类型:key值 -->
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
list:[1,2,3,4,5,6],
list2:[
{id:1,name:'zs1'},
{id:2,name:'zs2'},
{id:3,name:'zs3'},
{id:4,name:'zs4'},
{id:5,name:'zs5'},
],
user:{
id:1,
name:'齐天大圣',
gender:'男'
}
},
methods:{
}
})
</script>
</body>
</html>
v-if和v-show
<!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="toggle" @click="flag = !flag">
<!-- v-if的特点:每次都会重新删除或创建元素
v-show的特点:每次不会重新进行dom的删除和创建操作,只切换了元素的display:none样式 -->
<!-- v-if 有较高的切换性能消耗,v-show有较高的初始渲染消耗
如果元素涉及到频繁的切换,最好不要使用v-if,则推荐v-show
如果元素可能永远也不会被显示出来被用户看到,则推荐使用v-if -->
<h3 v-if="flag">这是v-if控制的元素</h3>
<h3 v-show="flag">这是v-show控制的元素</h3>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
flag:true
},
methods:{
}
})
</script>
</body>
</html>