一、简介
vue:渐进式JavaScript框架
声明式渲染->组件系统->客户端路由->集中式状态管理->项目构建
二、使用
new Vue:初始化
el:"#id":渲染开始的地方,元素的挂载位置(可以是CSS选择器或者DOM元素)
data:{}:变量,模型数据,对象
{{msg}}:插值表达式,支持基本计算操作
<div>{{msg}}</div>
new Vue({
el:"#box",
data:{
msg:"hello vue"
}
});
三、指令
指令的本质就是自定义属性。指令的格式:以v-开始。
数据响应式:
①html5中的响应式(屏幕尺寸的变化导致样式的变化)
②数据的响应式(数据的变化会导致页面内容的变化)
数据绑定:将数据填充到标签中。
1.v-cloak 去除闪动
直接使用插值表达式时,会有闪动。
闪动:当网络不佳时,先显示模板字符串,再显示数据。
原理:先通过样式隐藏内容,然后在内存中进行值的替换,替换好之后再显示最终的效果。
1.style样式中定义
[v-cloak]{
display:none;
}
2.在插值表达式所在的标签中添加v-cloak
<div v-cloak>{{msg}}</div>
2.v-text 填充纯文本
没有闪动问题。
3.v-html 填充html片段
存在安全问题:危险,容易导致xss攻击。
本网站内部数据可以使用,来自第三方的数据不可用。
4.v-pre 填充原始信息
显示原始信息,跳过编译过程。
可以直接显示{{msg}}原始文本。
5.v-once 只编译一次
显示内容之后不再具有响应式功能。
应用场景:显示的信息后续不需要再修改,可以提高性能。
6.v-model 双向绑定
双向绑定,绑定对应的一个值
<div>{{msg}}</div>
<input type='text' v-model='msg'>
用户修改页面input内容,数据改变。
数据改变,页面中div内容也改变。
使用v-on
+v-bind
实现v-model
<input :value='msg' @input='msg=$event.target.value'>
MVVM设计思想
不同业务放在不同模块中,通过逻辑组织到一起。
双向绑定方式:
视图——>模型:事件监听
模型——>视图:数据绑定
- Model:data中的数据
- View:Dom
- VM(view-model):控制逻辑,把两者结合在一起
7.v-on 事件绑定
v-on:click='处理逻辑'
简写@click='处理逻辑'
- 方法定义methods
var vm = new Vue({
data:{
num:0
},
methods:{
handle:function(){
this.num++; // this指向vm,vue的实例对象
}
}
});
-
调用方式:
①直接绑定函数名称
<button v-on:click='handle'>hello</button>
默认会携带事件对象,作为函数的第一个参数
②调用函数
<button v-on:click='handle()'>hello</button>
-
参数传递
<button v-on:click='handle("hi",$event)'>hello</button>
$event固定的写法,必须放在参数最后。
事件对象必须作为最后一个参数显示传递,并且事件对象名称必须是$event
-
事件修饰符
阻止冒泡:.stop
冒泡:子元素的事件会触发上级元素的事件
<a v-on:click.stop='handle'></a>
阻止默认行为:.prevent
<a v-on:click.prevent='handle'></a>
-
按键修饰符
回车键:.enter
应用场景:表单最后一个input回车提交
<input v-on:keyup.enter='handle'>
删除键:.delete
应用场景:清空input内容
<input v-on:keyup.delete='handle'>
自定义按键修饰符
Vue.config.keyCodes.aa=65 全局定义
// 可以直接用数值 <a v-on:keyup.65='handle'></a> <a v-on:keyup.aa='handle'></a>
8.v-bind 属性绑定
v-bind:href="url"
简写:href="url"
<a v-bind:href="url"></a>
data:{
url:"www.baidu.com"
}
9.v-bind 样式绑定
① class样式
对象语法
<div v-bind:class="{active:isActive,error:isError}"></div>
data:{
isActive:true,
isError:true
}
数组语法
<div v-bind:class="[activeClass,errorClass]"></div>
data:{
activeClass:'active',
errorClass:'error'
}
// 操作类名
methods:{
handle:function(){
this.activeClass='';
}
}
- 对象和数据结合使用
<div v-bind:class="[activeClass,errorClass,{test:isTest}]"></div>
- 简化操作
1.数组简化
<div v-bind:class="arrClass"></div>
data:{
arrClass:['active','error']
}
// 操作类名
// 操作数组
——————————————————————————————————————————————————————————————
2.对象简化
<div v-bind:class="objClass"></div>
data:{
objClass:{
active:true,
error:true
}
}
//操作类名
methods:{
handle:function(){
this.objClass.error=false;
}
}
- class和:class同时存在,默认的class会保留。
②style样式
对象语法
<div v-bind:style="{border:borderStyle,widthStyle}"></div>
<div v-bind:style="objStyles"></div>
data:{
borderStyle:'1px solid red',
widthStyle:'100px',
objStyles:{
border:'1px solid red',
'100px'
}
}
数组语法
<div v-bind:style="[objStyles,overridingStyles]"></div>
data:{
objStyles:{
border:'1px solid red',
'100px'
},
overridingStyles:{
border:'5px solid red',
'100px'
}
}
10.分支循环结构
①分支
v-if
:控制元素是否渲染到页面
v-else-if
v-else
v-show
:控制元素样式是否显示。把div渲染出来了,设置diplay:none。
应用:频繁显示/隐藏,控制样式性能比操作dom小。
②循环
v-for
遍历数组
// 1.基本用法
<ul>
<li v-for="item in fruits">{{item}}</li>
</ul>
// 2.索引,从0开始
<ul>
<li v-for="(item, index) in fruits">{{item+'-----'+index}}</li>
</ul>
// 3.复杂数组
<ul>
<li v-for="item in myFruits">
<span>{{item.ename}}</span>
<span>{{item.cname}}</span>
</li>
</ul>
// 4.对象,顺序固定
<div v-for="(value,key,index) in obj">{{value+'---'+key+'---'+index}}</div>
// 5.对象结合v-if
<div v-if="value==13" v-for="(value,key,index) in obj">{{value+'---'+'key'+'---'+index}}</div>
data:{
fruits:['apple','orange','banana'],
myFruits:[{
ename:'apple',
cname:'苹果'
}],
obj:{
uname:'lisi',
age:13,
gender:'male'
}
}
key
:帮助vue区分不同的元素,从而提高性能
<li :key='item.id' v-for="(item, index) in fruits">
// key
<ul>
<li :key='index' v-for="(item, index) in fruits">{{item+'-----'+index}}</li>
</ul>
data:{
fruits:['apple','orange','banana']
}
四、常用特性
1.表单 v-model绑定
-
单选
-
多选 数组
-
下拉select
- 单选
- 多选 multiple=true,occupation:[]
-
文本域
-
修饰符
-
number:转化为数值
v-modle.number='age'
-
trim:去掉开始和结尾的空格
-
lazy:将input事件切换为change事件(失去焦点时触发)
应用场景:登录注册时,验证用户名,失去焦点时进行验证
-
2.自定义指令
Vue.drective(指令名称,业务逻辑)
el:指令所绑定的元素
binding:对象,包含一系列属性
钩子函数:
- inserted
①全局指令
//自动获取元素焦点
Vue.drective('focus',{
inserted:function(el){
el.focus();
}
});
<input type="text" v-focus>
// 改变元素背景颜色 带参数
Vue.drective('color',{
inserted:function(el,binding){
el.style.backgroundColor=binding.value.color;
}
});
<input type="text" v-color='color:"orange"'>
②局部指令
写在vm中,和data同级
directives:{
color:{
bind:function(el,binding){
el.style.backgroundColor=binding.value.color;
}
},
focus:{
inserted:function(el){
el.focus();
}
}
}
3.计算属性
抽取复杂的计算逻辑,使模板更加简洁。
应用场景:计算复杂,耗时
computed
基于data中的数据
data:{
msg:'nihao'
}
computed:{
reverseString:function(){
return this.msg.split('').reverse().join('');
}
}
<div>{{reverseString}}</div>
计算属性与方法的区别
-
计算属性基于依赖缓存,data中的数据不发生变化,计算属性结果始终缓存。同样的计算只计算一次,可以节省性能。
使用多次,console只执行一次。
-
方法不存在缓存。
使用多次,console执行多次
4.侦听器
应用场景:数据变化时,执行异步或开销较大的操作。
data:{
firstName:'jim',
lastName:'Green',
fullName:'jim Green'
}
// 侦听器实现 名字和data中属性一致
watch:{
firstName:function(val){
this.fullName = val +' '+ this.lastNameName;
},
lastName:function(val){
this.fullName = this.firstName +' '+ val;
}
}
// 计算属性实现
computed:{
fullName:function(){
return this.firstName + ' ' + this.firstName;
}
}
<div>{{fullName}}</div>
案例:验证用户名是否可用
需求:输入框中输入姓名,失去焦点时 验证 是否存在。
①通过v-model数据绑定
②提供提示信息
data:{
uname:'',
tip:''
}
③需要侦听器监听输入信息的变化
/*
1.采用侦听器监听用户名变化
2.调用后台接口进行验证
3.根据验证的结果调整提示信息
*/
methods:{
checkName:function(uname){
// setTimeout中的this是window
var that = this;
// 调用接口
setTimeout(function(){
if(uname == 'admin'){
that.tip = '用户名已经存在,请更换一个';
}else{
that.tip = '用户名可以使用';
}
},2000);
}
}
watch:{
uname:function(val){
// 调用后台接口验证用户名合法性
this.checkName(val);
// 修改提示信息
this.tip = '正在验证....';
}
}
④修改触发的事件,将input事件切换为change事件(失去焦点时触发)
<input type="text" v-modle.lazy='uname'>
5.过滤器
格式化数据,处理数据
①全局过滤器
Vue.filter('过滤器名称',function(value){
// 业务逻辑
});
// 带参数的过滤器
Vue.filter('过滤器名称',function(value,arg1){});
<div>{{date | format('yyyy-MM-dd')}}</div>
// 首字母大写
Vue.filter('upper',function(val){
return val.charAt(0).toUpperCase() + val.slice(1);
});
// 首字母小写
Vue.filter('lower',function(val){
return val.charAt(0).toLowerCase() + val.slice(1);
});
// 插值表达式
<div>{{msg | upper}}</div>
// 级联使用
<div>{{msg | upper | lower}}</div>
// 属性绑定
<div :abc="msg | upper"></div>
②局部过滤器
filters:{
capitalize:function(val){
// 业务逻辑
}
}
格式化日期
// 带参数的过滤器,从第二个参数开始处理
Vue.filter('format',function(value,arg){
// 不够完善,可以使用正则匹配,网上找一个js
if(arg == 'yyyy-MM-dd')
var ret = '';
ret + value.getFullYear() + '-' +(value.getMonth() + 1)+'-'+value.getDate();
return ret;
}
});
<div>{{date | format('yyyy-MM-dd')}}</div>
6.生命周期
主要阶段
- 挂载(初始化相关属性,如watch,methods)
- beforCreate:在实例初始化后,数据观测和事件配置之前被调用
- created:实例创建完成后立即调用
- beforeMount:挂载开始之前被调用
- mounted:调用后台数据,填充模板。el被新创建的vm.$el替换,并挂载到实例上去之后调用
- 更新(元素或组件的变更操作)
- beforeUpdate:数据更新时调用,发生在虚拟DOM打补丁之前
- updated:由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该狗子
- 销毁(销毁相关属性)
- beforeDestory:实例销毁之前调用
- destoryed:实例销毁后调用
数组响应式
直接修改list不会响应式的修改