目录
Vue的介绍
Vue是一套用于构建用户界面的渐进式JavaScript框架
特点:1.采用组件化模式,提高代码复用率且代码更好维护;2.声明式编码,无需直接操作DOM,提高开发效率;3.虚拟DOM
Vue实例和容器一一对应,真实开发中只有一个Vue实例,配合其他组件一起使用。
<div id='root'>
<h1>{{name}}</h1> //模板语法——{{}}插值语法
<input v-bind:value='name' /> //模板语法——v-xxx指令语法
</div>
//创建Vue实例对象
const vm=new Vue({
//指定为哪个容器服务(方式一)
el:'#root',
//对象式
data:{
name:'hua'
}
//函数式
data:function(){
return {
name:'hua'
}
}
})
//指定为哪个容器服务(方式二)
vm.$mount('#root');
MVVM模型:M对应data中的数据 V模板 VM对应Vue实例对象
_data数据代理,更方便操作data中的数据:
- 通过Object.defineProperty()把data对象中的所有属性加到vm上;
- 为每一个添加到vm的属性,指定一个getter/setter;
- 在getter/setter内部去操作(读/写)data中对应的属性。
模板语法:
- 插值语法{{}},用在标签体里,接受表达式
- 指令语法v-xx,用在标签属性
Vue的系统指令
常用的指令语法:
v-bind单向绑定,数据只能从data流向页面;
v-model双向绑定,数据既能从data流向页面,也能从页面流向data ;
<input :value='name' /> //v-bind:简写为:
<input v-model:value='name /> //表单类元素,v-model:value简写省略value
v-on:绑定事件,
⭐常用的事件修饰符:(一个事件允许同时使用多个事件修饰符)
.prevent阻止默认行为(如链接跳转);
.stop阻止冒泡; .self触发对象是自己时才回调;
.once只触发一次。
<div id='root'>
<button v-on:click='fn'></button> //v-on:click简写为@click
<div @click='fun'>
<a href='' @click.prevent.stop></a> //先阻止默认行为再阻止冒泡
</div>
</div>
const vm=new Vue({
el:'#root',
data:{},
methods:{
fn:function(){},
fun(){}
}
})
v-on:keeyup/keepdown键盘事件,系统修饰键.ctrl .alt .shift .meta一般配合keydown使用
<div id='root'>
<input v-modle:value='firstname'/>
<input v-model:='lastname'/>
<h1>{{fullname}}</h1>
</div>
const vm=new Vue({
el:'#root',
data:{},
//计算属性
computed:{
fullname:{
get(){}
set(){}//一般只读,所以可以不用写set
}
}
})
<div id='root'>
<h1>{{flag}}</h1>
</div>
<script>
const vm=new Vue({
el:'#root',
data:{
flag:true
},
//监听属性,可以写在里面
watch:{
flag:{
//immediate:true //初始化的时候也调用一下handler
//deep:true //深度监视 默认false不监测对象内部值对象(一层)配置后可以(多层)
handler:function(newValue,oldVaule){} //监听对象发生变换时被调用
}
}
})
//监听属性,可以写在外面
vm.$watch('flag',{
handler(newV,oldV){}
})
</script>
计算属性能够做到的,监听属性都可以做到;反之不行,因为watch可以进行异步操作,如弄个定时器。
tips:
被Vue管理的函数,写成普通函数的形式;不被Vue管理的函数写成箭头函数,如定时器、ajax回调、Promise回调。
类样式,可通过v-bind绑定
<style>
.head{
border: 1px solid black;
background-color: cornflowerblue;
}
.fontSize1{
font-size: 2em;
}
.fontSize2{
font-size: 0.5em;
}
</style>
① 字符串
<div id='root'>
<h1 class='head' :class='font'>类样式</h1>
<button @click='fn'>点击切换样式</button>
</div>
<script>
const vm=new Vue({
el:'#root',
data:{
font:'fontSize1'
},
methods:{
fn(){
this.font='fontSize2'
}
}
})
</script>
② 数组
const vm=new Vue({
el:'#root',
data:{
font:['fontSize1','fontSize2']
},
})
③ 对象
<h1 :class='{fontSize1:false,fontSize2:true}'></h1>
v-show:设置元素的显示和隐藏(在元素上添加/移除style="display:none"
属性)
<div id='root'>
<h1 v-show='flag'>隐藏/显示</h1>
</div>
const vm=new Vue({
el:'#root',
data:{
flag:true
},
})
v-if:设置元素的显示和隐藏(添加/删除DOM元素)
<div id='root'>
<h1 v-if='flag'>添加/删除</h1>
</div>
const vm=new Vue({
el:'#root',
data:{
flag:true
},
})
v-for:循环遍历
<div class="root" >
<ul>
//数组
<li v-for="(item,index) of arr" :key="">{{item}}::{{index}}</li>
</ul>
<ol>
//对象数组
<li v-for="(item,index) of objArr" :key='item.id'>{{item}}++{{index}}</li>
</ol>
<ol>
//对象
<li v-for="(item,index) of obj">{{item}}--{{index}}</li>
</ol>
</div>
<script>
const myVue=new Vue({
el:'.root',
data:{
arr:[1,'a','b','c','d','e'],
objArr:[
{id:1,name:'a'},
{id:2,name:'b'},
{id:3,name:'c'}
],
obj:{
name:'hua',age:18
}
},
})
:key唯一标识,
key是虚拟DOM对象的标识,当状态中的数据发生变化时,比较新旧虚拟DOM的差异,相同的直接复用。在不破坏顺序的情况下,给key赋值index没问题。
Vue收集表单数据
<div class="root">
<form action="">
昵称:<input type="text" v-model.lazy="form.name"> <br/><br/>
性别:<input type="radio" name="sex" id="man" v-model="form.sex" value="man">
<label for="man">男</label>
<input type="radio" name="sex" id="women" v-model="form.sex" value="women">
<label for="women">女</label> <br/><br/>
爱好:<input type="checkbox" name="" id="" v-model="form.hobby" value="play">玩
<input type="checkbox" name="" id="" v-model="form.hobby"value="sing">唱 <br/><br/>
<button>提交</button>
</form>
</div>
const vm=new Vue({
el:'.root',
data:{
form:{
name:"",
sex:"women",
hobby:[]
}
}
})
- 使用v-model指令绑定,这样才能使数据从页面流向data
- 表单类型为输入类型的,如text、password,输入的内容即为绑定数据;
- 单选框radio,要在标签内写明属性value,不然返回null;
- 复选框checkbox,标签内没写明value返回布尔值(勾选true),data中的该项数据类型不是数组也返回布尔值;
- v-model的三个修饰符:lazy失去焦点再收集数据,number字符串转数字,trim过滤输入的首尾空格。
自定义指令
私有自定义指令,只有在当前vue对象指定的el容器里有效
//html
<span v-big='v'></span>
//vue
new Vue({
el:'.root',
data{
v:1
}
directives:{
//函数写法
big(element,bingding){//完整写法:'big':function(ele,bin){}
element.innerText=binding.value*10;
}
}
})
上面的函数相当于省去了下面的配置对象写法中的inserted步骤
directives:{
'big':{
//在指令与元素成功绑定时调用
bind(ele,binding){
ele.innerText = binding.value*10;
},
//在元素被插入页面时
inserted(ele,binding){},
//指令所在模板被重新解析时调用
update(ele,binding){
ele.innerText = binding.value*10;
}
}
}
全局自定义指令,
//写法一:回调函数
Vue.directive('big', function(ele,binding){
ele.innerText = binding.value*10;
})
//写法二:配置对象
Vue.directive('big',{
bind(ele,binding){},
inserted(ele,binding){},
update(ele,binding){}
})
注意,指令操作的是DOM元素,里面的this通通指向Windows。
生命周期
生命周期 钩子函数 生命周期事件
组件基础
模块化和组件化的区别
-
模块化:是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一
-
组件化:是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用
//3.编写组件标签
<div class='root'>
<Student></Student>
</div>
<script>
//1.创建组件
const student=Vue.extend({
template:`<h1>{{d}}</h1>`,
data(){
return ({
d:'hhh'
})
}
})
new Vue({
el:'.root',
//2.注册私有组件
components:{
Student:student
}
})
</script>
上面展示的是完整版的组件创建方式,注意:
Vue.extend可以省略,因为组件实例对象会自动调用;template里面只能有一个根节点,所以用一个<div></div>包起来最好;data得写成函数的形式,这样当组件复用时,数据互不干扰;
//3.编写组件标签
<div class='root'>
<Student></Student>
</div>
<script>
//1.创建组件
const student={
template:`<h1>{{d}}</h1>`,
data(){
return ({
d:'hhh'
})
}
}
//2.注册全局组件
Vue.component('Student',student)
new Vue({
el:'.root',
})
</script>
组件嵌套:在父组件创建里进行子组件的注册
const Father=({
template:'
<div>
<Son></Son>
</div>',
components:{Son},
data(){}
})
App组件管理所有组件