Vue基础

一、简介

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='处理逻辑'

  1. 方法定义methods
var vm = new Vue({
    data:{
        num:0
    },
    methods:{
        handle:function(){
            this.num++; // this指向vm,vue的实例对象
        }
    }
});
  1. 调用方式:

    ①直接绑定函数名称

    <button v-on:click='handle'>hello</button>

    默认会携带事件对象,作为函数的第一个参数

    ②调用函数

    <button v-on:click='handle()'>hello</button>

  2. 参数传递

    <button v-on:click='handle("hi",$event)'>hello</button>

    $event固定的写法,必须放在参数最后。

    事件对象必须作为最后一个参数显示传递,并且事件对象名称必须是$event

  3. 事件修饰符

    阻止冒泡:.stop

    冒泡:子元素的事件会触发上级元素的事件

    <a v-on:click.stop='handle'></a>
    

    阻止默认行为:.prevent

    <a v-on:click.prevent='handle'></a>
    
  4. 按键修饰符

    回车键:.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='';
    }
}
  1. 对象和数据结合使用
<div v-bind:class="[activeClass,errorClass,{test:isTest}]"></div>
  1. 简化操作
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;
    }
}
  1. class和:class同时存在,默认的class会保留。

②style样式

对象语法

<div v-bind:style="{border:borderStyle,width:widthStyle}"></div>

<div v-bind:style="objStyles"></div>

data:{
	borderStyle:'1px solid red',
	widthStyle:'100px',
	objStyles:{
        border:'1px solid red',
        width:'100px'
	}
}

数组语法

<div v-bind:style="[objStyles,overridingStyles]"></div>

data:{
	objStyles:{
        border:'1px solid red',
        width:'100px'
	},
	overridingStyles:{
        border:'5px solid red',
        width:'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:实例销毁后调用
生命周期

数组响应式

image-20200819115930712

直接修改list不会响应式的修改

image-20200819120406657

posted @ 2020-08-31 14:10  wattmelon  阅读(163)  评论(0编辑  收藏  举报