vue学习
一.Vue.js 是什么
-
-
Vue.js 是前端的主流框架之一,和Angular.js、React.js 一起,并成为前端三大主流框架!
-
Vue.js 是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue有配套的第三方类库,可以整合起来做大型项目的开发)
-
前端的主要工作?主要负责MVC中的V这一层;主要工作就是和界面打交道,来制作前端页面效果;
二.Vue入手以及基本语法
1. vue的使用要从创建Vue对象开始 var vm = new Vue(); //注意Vue第一个字母大写 2. 创建vue对象的时候,需要传递参数,是json对象,json对象对象必须至少有两个属性成员 var vm = new Vue({ el:"#app", //指定容易,要控制哪一个标签作为容器 data: { //数据,传到页面的数据,和页面的数据双向绑定 数据变量:"变量值", 数据变量:"变量值", 数据变量:"变量值", }, }); el:设置vue可以操作的html内容范围,值就是css的id选择器。 data: 保存vue.js中要显示到html页面的数据。 3. vue.js要控制器的内容外围,必须先通过id来设置。 <div id="app"> <h1>{{message}}</h1> <p>{{message}}</p> </div>
三.Vue.js的M-V-VM思想
1. MVVM就是Model-View-ViewModel的缩写,他是基于前端框架的开发思想
2. Model指代的是vm对象的data里面的数据,这里的数据要显示到页面中
3. view指代就是Vue中数据要显示到HTMl页面中,在Vue中也成为视图模板
4. ViewModel指代的是我们编写的vm对象了,他是Vue.js的核心,负责连接View和MOdel保证视图和数据的一致性 ,
所以在前面代码中,data的数据被显示中的p标签就是vm对象自动完成的
四.一个简单的实例
1.一个简单的实例
<!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="js/vue.js"></script> </head> <body> <div id='box'> <h1>{{msg}}</h1> <!-- 通过v-model把数据展现在input标签 --> <input type="text" v-model="msg"> <!-- 字母变大写 --> <p>{{msg.toUpperCase()}}</p> <!-- img标签不能这么直接放 这就是结构,<img src="imgs/1.jpg">,要以v-html的形式 --> <!-- 就是说img标签不会被解析 --> <p>{{img}}</p> <span v-html='img'></span> <!-- 双花括号中支持js代码,但是开发中不建议使用复杂的代码到html视图中--> <!-- 数字可以进行简单的计算 --> <p>{{num+10}}</p> <!-- 三元运算 --> <p>{{num1>num?num1:num}}</p> </div> <script> //为了防止要控制的标签比script完加载出来找不到标签 //创建对象,注意Vue是大写的 window.onload=function(){ let vm=new Vue({ el:'#box', data:{ msg:'hello', //这种标签传过去是标签的要以v-html解析 img:'<img src="imgs/1.jpg" width="50px">', num:10, num1:20 } }) } </script> </body> </html>
效果:
在浏览器中可以在 console.log通过 vm对象可以直接访问el和data属性,甚至可以访问data里面的数据
console.log(vm.$el) # #box vm对象可以控制的范围
console.log(vm.$data); # vm对象要显示到页面中的数据
console.log(vm.message);# 这个 message就是data里面声明的数据,也可以使用 vm.变量名显示其他数据,message只是举例.
总结:
1. 如果要输出data里面的数据作为普通标签的内容,需要使用插值表达式 插值表达式 {{}} v,-cloak , v-text ,v-html 用法: vue对象的data属性: data:{ name:"小明",
msg:'我曹' } 标签元素: <h1>{{ name }}</h1>
<!-- 使用 v-cloak 能够解决 插值表达式闪烁的问题 -->
<p v-cloak>++++++++ {{ msg }} ----------</p>
<h4 v-text="msg">==================</h4>
<!-- 默认 v-text 是没有闪烁问题的 -->
<!-- v-text会覆盖元素中原本的内容,但是 插值表达式 只会替换自己的这个占位符,不会把 整个元素的内容清空 -->
2. 如果要输出data里面的数据作为表单元素的值,需要使用vue.js提供的元素属性v-model 用法: vue对象的data属性: data:{ name:"小明", } 表单元素: <input v-model="name"> 使用v-model把data里面的数据显示到表单元素以后,一旦用户修改表单元素的值,则data里面对应数据的值也会随之发生改变,甚至,页面中凡是使用了这个数据都会发生变化。
3.双花括号仅用输出文本内容,如果要输出html代码,则不能使用这个.要使用v-html来输出.
v-html必须在html标签里面作为属性写出来.
4. 可以在普通标签中使用{{ }} 或者 v-html 来输出data里面的数据
可以在表单标签中使用v-model属性来输出data里面的数据,同时还可以修改data里面的数据
<input type="text" v-model="username">
五.常用指令
指令 (Directives) 是带有“v-”前缀的特殊属性。每一个指令在vue中都有固定的作用。
在vue中,提供了很多指令,常用的有:v-if、v-model、v-for等等。
指令会在vm对象的data属性的数据发生变化时,会同时改变元素中的其控制的内容或属性。
因为vue的历史版本原因,所以有一部分指令都有两种写法:
vue1.x写法 vue2.x的写法
v-html ----> {{ }}
v-bind:属性名 ----> :属性 <!-- v-bind: 是 Vue中,提供的用于绑定属性的指令 -->
v-on:事件名 ----> @事件名 <!-- Vue 中提供了 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> <script src="js/vue.js"></script> </head> <body> <div id='box'> <p>{{p1}}</p> <p v-html='p1'></p> <!-- 如果是标签需要要指令展示 --> <!-- 给标签绑定属性v-bind ,以下来那种方法都可以--> <img v-bind:src="img" width="50"> <img :src='img' width="50"> <!-- 给标签绑定事件 ,以下来那种方法都可以 --> <span v-on:click="func">点击弹出一个窗口 </span> <span @click='func2'>{{num}}</span> </div> <script> //这边的Vue第一个字母大写的 let vm=new Vue({ el:'#box', data:{ p1:"一个段落", img:"imgs/1.jpg", num:10 }, methods:{ func:function(){ alert("hello world"); }, func2:function(){ this.num+=1 //这里是视图中@click事件绑定以后执行的方法,可以直接通过this.变量名 获取保存在data属性里面的数据 } } }) </script> </body> </html>
总结:
1. 使用@事件名来进行事件的绑定 语法: <h1 @click="num++">{{num}}</h1> 2. 绑定的事件的事件名,全部都是js的事件名: @submit ---> onsubmit @focus ---> onfocus ....
商城的使用:购物车的增减
<!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="js/vue.js"></script> </head> <body> <div id='box'> <span>{{num}}</span> <button @click="num+=1">增加</button> <button @click="num<=0?num:num-=1">减少</button> <!-- 给标签绑定点击的事件 --> <button @click='num+=1'>+</button> <input type="text" v-model='num'> <button @click='(num<=1)?(num=1):(num-=1)'>-</button> <!-- 这边的三元运算符用括号括起易读性比较强 --> </div> <script> let vm=new Vue({ el:'#box', data:{ num:0, } }) </script> </body> </html>
六.操控属性
其实就是给标签绑定一个属性
格式: <h1 :class="值">元素</h1> 值可以是对象、对象名、数组
例子:
<!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> .box1{ color:dimgrey; backgroud:teal; bored:1px solid red } .box2{ color:tomato; backgroud:violet; bored: 2px solid black; font-size: 32px } </style> <script src="js/vue.js"></script> </head> <body> <div id='box'> <!-- 添加class类名,值是布尔值 多个类名{ class类名1:布尔值1, class类名:布尔值2, } --> <!-- 添加了类名,值是从数据取出来的布尔值 --> <p :class="{box1:myclass1}">这是一个段落</p> <p @click='myclass3=!myclass3' :class="{box1:myclass2,box2:myclass3}">这是另外一个段落</p> </div> <script> let vm=new Vue({ el:'#box', data:{ myclass1:true,//布尔值如果为false,则不会添加类名对应的样式作为其样式 myclass2:true,//布尔值如果是true,则把类名对应的样式作为其样式 myclass3:true } }) </script> <!-- 上面的代码可以:class的值保存到data里面的一个变量,然后使用该变量作为:class的值 --> <style> .box3{ font-size: 32px } .box4{ color:dimgrey } </style> <div id='app'> <button @click='mycls.box3=!mycls.box3'>改变字体</button> <button @click='mycls.box4=!mycls.box4'>改变颜色</button> <p :class='mycls'>这是一个待改变的p标签</p> </div> <script> let vm2=new Vue({ el:'#app', data:{ mycls:{ box3:false, box4:true, } }, }) </script> <!-- 批量给多个元素增加多个class样式类 --> <style> .box5{color:red} .box6{font-size: 32px} .box7{background:forestgreen} </style> <div id="ll"> <p :class="[cls1,cls2]">这是另外一个待改变的标签</p> </div> <script> let vm3=new Vue({ el:"#ll", data:{ cls1:{ box5:true, box6:true, }, cls2:{ box7:true } } }) </script> </body> </html>
总结:
1. 给元素绑定class类名,最常用的就是第二种。
vue对象的data数据:
data:{
myObj:{
complete:true,
uncomplete:false,
}
}
html元素: <div class="box" :class="myObj">2222</div>
最终浏览器效果: <div class="box complete">2222</div>
七.操控行内样式:
1. 行内样式其实就是给标签绑定style属性 v-bind:style 或者 :style
<!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="js/vue.js"></script> </head> <body> <div id='box'> <p :style='{color:mycolor,background:mybc}'>这是一个美丽的段落</p> </div> <!-- 控制行内样式,值是一个对象 --> <!-- :style="{color:样式值1,font-size:样式值2}" 样式值是保存在打他中的一个变量 --> <script> let vm=new Vue({ el:'#box', data:{ mycolor:'red', mybc:'yellow' } }) </script> <!-- 同时增加多个样式 --> <div id='app'> <p :style='mycls'>这是一个待改变的p标签</p> </div> <script> let vm2=new Vue({ el:'#app', data:{ mycls:{ color:'red', background:'green' } }, }) </script> <!-- 批量元素增加多个style样式类 --> <div id="ll"> <p :style="[style1,style2]">这是另外一个待改变的标签</p> </div> <script> let vm3=new Vue({ el:"#ll", data:{ style1:{ color:'red' }, style2:{ fontSize:'32px' } } }) </script> </body> </html>
2.vue版本的选项卡
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> #card{ height: 350px; width: 500px; } .title span{ height: 50px; width: 80px; line-height: 50px; text-align: center; /*字体居中*/ background:#ccc; display:inline-block } .title .current{ background-color: rgb(255, 255, 0); } .content .list{ height: 300px; width: 500px; background: rgb(255, 255, 0); display:none; } .content .active{ display: block; } </style> <script src="js/vue.js"></script> </head> <body> <div id='card'> <div class='title'> <span @click="num=0" :class="num==0?'current':''">标题一</span> <span @click="num=1" :class="num==1?'current':''">标题二</span> <span @click="num=2" :class="num==2?'current':''">标题三</span> </div> <div class='content'> <div class="list" :class="num==0?'active':''">花边新闻</div> <div class="list" :class="num==1?'active':''">桃色新闻</div> <div class="list" :class="num==2?'active':''"> 你懂得哈哈哈</div> </div> </div> <script> // 动态效果实现的思路,给设置一个数字,如果是这个数字则给他一个展示的属性,否则就不给 //当用户点击标题栏的按钮[span]时,显示对应索引下标的内容块[.list] let vm=new Vue({ el:'#card', data:{ num:0 } }) </script> </body> </html>
八.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-2.4.0.js"></script> </head> <body> <div id="app"> <h4>{{ msg }}</h4> <!-- v-bind 只能实现数据的单向绑定,从 M 自动绑定到 V, 无法实现数据的双向绑定 --> <!-- <input type="text" v-bind:value="msg" style="width:100%;"> --> <!-- 使用 v-model 指令,可以实现 表单元素和 Model 中数据的双向数据绑定 --> <!-- 注意: v-model 只能运用在 表单元素中 --> <!-- input(radio, text, address, email....) select checkbox textarea --> <input type="text" style="width:100%;" v-model="msg"> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { msg: '大家都是好学生,爱敲代码,爱学习,爱思考,简直是完美,没瑕疵!' }, methods: { } }); </script> </body> </html>
九.几个小例子
1.简易计算器
<!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="js/vue.js"></script> </head> <body> <!-- v-bind只能实现单向数据绑定 --> <!-- v-model 能实现表单元和model的双向数据绑定 --> <!-- v-model只能使用在表单元素中 --> <!--input radio ,text,email,address --> <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='result'> </div> <script> let vm=new Vue({ el:'#app', data:{ n1:0, n2:0, result:0, opt:'+' }, methods:{ //计算方法 cal(){ 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>
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="js/vue.js"></script> </head> <body> <div id="app"> <input type="button" value='别浪' @click='lang'> <input type="button" value='不浪了' @click='stop'> <p>{{msg}}</p> </div> <script> let vm=new Vue({ el:'#app', data:{ msg:'别浪,猥琐发育~~~`', intervalId:null }, methods:{ lang:function(){ //判断定时器id是否存在,一句话,花括号可以省累,直接return if(this.intervalId!=null) return; // 箭头函数的作用,内部的this和外部的this保持一致 this.intervalId = setInterval(() => { var start=this.msg.substring(0,1) var end=this.msg.substring(1) this.msg=end+start }, 400); }, stop:function(){ clearInterval(this.intervalId) //必须要清除定时器id,否则上面开启定时器的时候,定时器id一致存在着,就无法开启 this.intervalId=null; }, } }) </script> </body> </html>
3.选项卡效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> #card{ height: 350px; width: 500px; } .title span{ height: 50px; width: 80px; line-height: 50px; text-align: center; /*字体居中*/ background:#ccc; display:inline-block } .title .current{ background-color: rgb(255, 255, 0); } .content .list{ height: 300px; width: 500px; background: rgb(255, 255, 0); display:none; } .content .active{ display: block; } </style> <script src="js/vue.js"></script> </head> <body> <div id='card'> <div class='title'> <span @click="num=0" :class="num==0?'current':''">标题一</span> <span @click="num=1" :class="num==1?'current':''">标题二</span> <span @click="num=2" :class="num==2?'current':''">标题三</span> </div> <div class='content'> <div class="list" :class="num==0?'active':''">花边新闻</div> <div class="list" :class="num==1?'active':''">桃色新闻</div> <div class="list" :class="num==2?'active':''"> 你懂得哈哈哈</div> </div> </div> <script> // 动态效果实现的思路,给设置一个数字,如果是这个数字则给他一个展示的属性,否则就不给 //当用户点击标题栏的按钮[span]时,显示对应索引下标的内容块[.list] let vm=new Vue({ el:'#card', data:{ num:0 } }) </script> </body> </html>