VUE.js基础
数据驱动视图
通过对数据的逻辑修改,数据变化会更新到视图中,简化DOM操作(单向数据绑定)。基于MVVM实现
组件化开发
允许将网页功能封装成自定义HTML标签,复用时书写自定义标签名即可
el选项
使用vue时需要将DOM元素作为Vue实例的挂载目标。挂载内部才可以被Vue处理,外部为普通Html元素,只能在一个元素上挂载,但不可以是body或者html上
var vm = new Vue({
el: '#app'
})
//或者
var app = document.querySelector('#app');
var vm = new Vue({
el:'#app'
})
挂载以后使用vm.$el访问
console.log(vm.$el)
如果定义时没有赋值,可以用vm. m o u n t ( ) 进行挂载 ‘ v a r v m = n e w V u e ( ) ; v m . mount()进行挂载`var vm = new Vue({}); vm. mount()进行挂载‘varvm=newVue();vm.mount(‘#app’)`
插值表达式
挂载元素可以使用vue.js的模板语法,通过插值表达式为元素动态内容设置,用两个大括号包含<li>比较结果为{{1+2+3}}<li>
。插值表达式只能书写在内容区域,不可与其他内容混合。内部只能书写js表达式而不可书写js语句
<div id="app">
<ul>
<li>第一段示例内容:{{ 10 + 20 + 30 }}</li>
<li>第二段示例内容:{{ 22 > 3 ? '22比3大' : '3比22大' }}</li>
<!-- <li id="{{ 1 + 2 }}"></li> --> //只能写在内容区域,混合书写报错
<!-- <li>{{ var num = 100; }}</li> --> //书写js语句报错
</ul>
</div>
<script>
new Vue({
el: '#app' //将元素挂载到vue实例
});
</script>
Data属性
data属性时Vue基础选项,用来存储数据
var vm = new Vue({
el:'#app',
data:{
title:'标题内容'
}
})
console.log(vm.$data.title);
console.log(vm.title);
data中的数据可以直接在视图中通过插值表达式访问。data中的数据为响应式数据,重新修改属性或赋值以后视图会自动更新。但是无法通过索引的方式赋值和修改length的值更新视图(属性值会改变不会表示在视图上)。只能通过set()方法更新视图,或可以通过pop()等数组方法更新视图。
<ul>
<li>{{ arr[0] }}</li>
<li>{{ arr[1] }}</li>
<li>{{ arr[2] }}</li>
</ul>
<script>
var vm = new Vue({
el: '#app',
data: {
title: '标题文本',
arr: ['内容1', '内容2', '内容3']
}
});
console.log(vm.$data.title);
// console.log(vm.title); // 更常用
</script>
vm.title = '111’可以给属性赋值并且可以更新到视图中,而使用vm.arr[0]='111’可以更新数值,但无法显示到视图中。可以使用Vue.set(vm.arr,0,'修改数据')
或vm.arr.push('111')
修改并且更新视图。在new Vue时将data中的数据设置成响应式,对于已经创建的实例,vue不允许动态添加根级别的响应式属性,可以用Vue.set(object,propertyName,value)方法向对象添加响应式数据
method选项
存储需要在Vue 需要使用的函数
<div id="app">
<p>{{ title1.split('-').join('') }}</p>
<p>{{ title2.split('-').join('') }}</p> //逻辑代码和展示写在一个地方不利于分离
<p>{{ fn(title1) }}</p> //调用函数实现
</div>
var vm = new Vue({
el:'#app',
data:{
prefix:'结果为'
title:'111',
arr:['1','2','3']
},
method:{
fn (val) {
console.log(this)
this.fn1()
this.fn2()
return this.prefix + val.split('-').join();
}
fn1(){console.log('这是fn1')}
fn2(){console.log('这是fn2')}
}
console.log(vm)
})
method中的方法可以通过Vue.用户名
访问。方法中的this指向实例,console.log(this.title,this.content)
vue.js指令
指令的本质就是HTML自定义属性 。 vue.js指令就是以v-开头的自定义属性
内容处理指令
v-once
使元素内部插值表达式只生效一次
<p v-once>数据只更新一次{{content}}</p>
<p>数据随时更新{{content}}</p>
<script>
var vm = new Vue({
el: '#app',
data: {
content: '内容文本'
}
})
vm.content = 'aaa'//修改后添加v-voce的不会改变
</script>
v-text/v-html
元素内容整体替换成指定纯文本数据,覆盖标签原始内容
<body>
<div id="app">
<p v-text="100">这是 p 标签的原始内容</p> //设置常量替换标签中的文字
<p v-text="content">这是 p 标签的原始内容</p> //将标签内容替换成数据内容(数据驱动视图效果)
<p v-text="content2"></p> //只能替换内容而无法替换结构样式(可以使用v-html指令)
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
content: '内容文本',
content2: '<span>span的内容</span>'
}
});
</script>
属性绑定指令
v-bind指令
用于动态绑定HTML属性 。语法:在标签内部添加v-bind:属性名=属性值
<div id="app">
<p v-bind:title="myTitle">p标签的内容</p>
<p :title="myTitle">p标签的内容</p> //可以简化书写为:
<p :class="'num' + 1 + 2 + 3">p标签的内容</p>
<p :class="prefix + num"></p>
<p :class="var a = 1"></p>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
myTitle: '这是title的内容',
prefix: 'demo',
num: 10
}
});
</script>
如果一次绑定多个属性,还可以绑定对象.通过添加键值对的方式绑定对象。对象写在date中
<div id="app">
<p v-bind="attrObj">这是 p 标签的内容</p> //绑定时直接属性对象名
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
attrObj: {
id: 'box',
title: '示例内容',
class: 'clearFix',
'data-title': '这是 data-title 的内容' //自定义属性需要用引号包括
}
}
});
</script>
Class 绑定
class 是HTML属性可以通过v-bind 绑定多可class可以共存,只有v-bind绑定 的能够动态设置。多个类名无法用空格连接值的方式书写<p class ="a b c " :class = "c d e">错误写法</p>
。可以使用用空格分隔的多个类名即可实现多个类名绑定cls:'a b c '
。
<div id = "app">
<p v-bind:class="cls1" class="a">标签内容</p>
<!--错误绑定方式
<p :class = "a b c "> //表达式不可书写为空格链接值的形式
-->
<p :class = "cls"> </p>
</div>
<script>
var vm = new Vue({
el:'#app'
data:{
cls : 'a b c ',
cls1:'x'
}}
vm.cls1 = 'y' //可以修改绑定的class属性值
)
</script>
可以通过用类名检测判断类名。提供了特殊方式处理class绑定
<p :class="{ x: isX, y: false, z: true }"></p> //可以使用键为类名,值为布尔值判断类名是否生效。
<p :class="['a', classB, {c: isC}]"></p> //无需条件类名和需要条件类名同时存在时使用数组方式绑定类名。
<script>
var vm = new Vue({
el: '#app',
data: {
isC: true
isX: true //可以设置值为其他变量
/* bool: true,
ClassB:'b',
cls: 'q w e',
cls1: 'x',
cls2: 'y',
cls3: 'z' */
}
});
</script>
Style 绑定
普通的style属性和绑定的style属性重复时,以绑定的style属性为准。多个样式对象可以用数组设置
<div id="app">
<p v-bind:style="{width: '100px', height: '100px'}"></p>
<p :style="styleObj">标签内容</p>
<p style="width: 100px" :style="styleObj"></p>
<p :style="[styleObj , styleObj1]">标签内容</p> //数组设置多个样式对象
</div>
<script>
var vm = new Vue({
el :'#app',
data:{
styleObj:{
width:'100px',
heigth:'200px',
backgroundColor:'blue'
}
styleObj1:{
position:'absolute'
}
}
})
</script>
渲染指令
v-for 指令
遍历数据渲染结构,用于数组和对象的遍历。遍历数组时可以传(元素内容,索引下标)两个参数,遍历对象时可获取(元素内容,键值,索引下标)参数。使用v-for 时必须设置唯一的key值。。设置key避免由于为了提高渲染效率,渲染时只改变视图结构部分。而不改变用户操作导致无法正常匹配。不可使用index作为key值是由于元素位置改变时,索引值位置也发生改变,index不是唯一的。
<li v-for="item in arr">元素内容为:{{ item }}</li> //遍历数组
<li v-for="(item, index) in arr">元素内容为:{{ item }}, 索引为:{{ index }}</li> //遍历数组添加index下标
<li v-for="val in obj">元素内容为{{val}}</li>
<li v-for="(val,key,index )in obj" :key="itemlist.id">元素内容为{{val}},键为{{ key }},下标值为{{ index }}</li>
<li v-for="(item, index) in 5">这是第{{ item }}个元素,索引值为:{{ index }}</li> //可设置遍历个数
<script>
new Vue({
el: '#app',
data: {
arr: ['内容1', '内容2', '内容3'],
obj: {
content1: '内容1',
content2: '内容2',
content3: '内容3'
},
itemlist:[
{id:1,value:2},
{id:2,value:3},
{id:3,value:3}
]
}
});
</script>
为了使多个元素可以集中操作,为其添加了一个虚拟template标签。无需设置key属性
<div id="app">
<template v-for="item in obj">
<span>{{ item }}</span>
<br>
</template>
</div>
v-show 指令
控制元素的显示与隐藏,适用于显示隐藏显示切换频繁时使用。通过设置v-show=“true”和false来控制显示和隐藏。true和false也可以通过表达式来指代。template标签无法使用v-show属性,是由于该属性使用元素的display属性控制,display是真实存在的元素属性。设置为false时将display属性设置为了none
<p v-show="bool">标签内容</p>
<script>
var vm=new Vue({
el:'#app',
data:{
bool:true
}
})
</script>
v-if指令
根据条件控制元素的创建和移除操作。为同类型的元素绑定指令时需要添加key属性;避免v-if与v-for同时绑定到同一个标签。v-for的优先级更高
<div id="app">
<p v-if="type===username" :key='username'>用户名登录</p> <!--从上到下有一个满足就会执行并且停止向下执行操作。如果都不满足执行v-else操作-->
<p v-else-if="type===emali" :key='email'>邮箱登录</p>
<p v-else :key="type===telepone">手机登录</p>
<ul v-if="false"> <!--将v-if设置到父级元素-->
<li v-for="item in items">{{item}}</li>
</ul>
</div>
<script>
var vm=new Vue({
el:"#app",
data:{
bool: true ,
type:'username'
}
})
</script>
事件处理
v-on指令
用于元素事件绑定。绑定的方法中可以传入参数event查看事件的对象。vue允许给事件对象传参,可以自己为对象参数传入并且同时使用事件对象,在视图中可以通过$event访问事件对象。v-on:click="content='new content'"
可以简化书写成@click="content='new content'"
<div id="app">
<p>{{content}}</p>
<button v-on:click="content='this is a new content '">1st</button>
<button @click="content='this is a 2nd content '">2nd</button>
<button @click="fn">3rd</button>
<button @click="fn2(200,$event)">4th</button>
</div>
<script>
new Vue({
el:'#app',
data:{ //访问事件对象
content:'this defint content',
},
mothods:{
fn(event){
console.log(event) //查看事件对象
this.content='3bt show content'; //this代表vue实例,通过this绑定数据或方法
}
fn2(content, event){
console.log(content);
console.log(event);
}
}
})
</script>
v-model
用于给input,textarea.select 等元素设置双向元素绑定。(使得文本框的内容和value中的值相同)
- 绑定文本框,绑定后的内容为输入值
<div id = "app">
<p>元素内容为{{ value }}</p>
<input type='text' v-model='value'> //绑定以后视图和元素双向绑定
</div>
<script>
var vm = new Vue({
el:'app',
data:{
value = ''
}
})
</script>
- 绑定单选框 (绑定后的内容为value中的值 )
绑定后选项的值和value的值相同
div id="app">
<p>radio 的内容为: {{ value3 }}</p>
<input type="radio" id="one" value="1" v-model="value3">
<label for="one">选项1</label>
<input type="radio" id="two" value="2" v-model="value3">
<label for="two">选项2</label>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
value3: ''
}
});
</script>
- 绑定复选框(绑定单选框后的内容为Boolean值,选中为true,绑定多个复选框的内容为value值)
绑定单个复选框时value的值用字符串来保存。多个复选框value用数组来保存。
<p>单个复选框的值: {{value4}}</p> //单个复选框的value值默认为布尔值,提交表单时提交value值
<input
type="checkbox"
value="选项内容"
id="one"
v-model="value4">
<label for="one">选项内容</label>
<p>多个复选框的值:{{ value5 }}</p>
<input
type="checkbox"
id="cb1"
value="选项1"
v-model="value5"
>
<label for="cb1">选项1</label>
<input
type="checkbox"
id="cb2"
value="选项2"
v-model="value5"
>
<script>
var vm = new Vue({
el: '#app',
data: {
value4: '',
value5: []
}
});
</script>
- 选择框绑定(绑定后的内容为value值)
<div id="app">
<!-- 单选选择框 -->
<p>单选选择框的内容: {{ value6 }}</p>
<select v-model="value6">
<option value="">请选择</option>
<option value="1">选项1</option>
<option value="2">选项2</option>
<option value="3">选项3</option>
</select>
<!-- 多选选择框 -->
<p>多选选择框的内容:{{ value7 }}</p>
<select v-model="value7" multiple> //multiple属性为多选选择框
<option value="1">选项1</option>
<option value="2">选项2</option>
<option value="3">选项3</option>
</select>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
value6: '',
value7: []
}
});
</script>
修饰符
以点开头的指令后缀
事件修饰符
.prevent修饰符
阻止默认行为,相当于event.preventDefult()。例如a标签的跳转
<div id="app">
<a @click.prevent="fn" href="https://kaiwu.lagou.com/">链接</a>
<a @click.prevent href="https://kaiwu.lagou.com/">链接</a>
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: { },
methods: {
fn() {
console.log('这是 a 标签的点击事件')
}}
});
</script>
.stop修饰符
阻止事件传播,相当于event.stopPropagation()。可以连续打点添加多个修饰符
<div id="app">
<div @click="fn1">
<!-- <button @click.stop="fn2">按钮</button> -->
<a @click.prevent.stop="fn2" href="https://kaiwu.lagou.com/">链接</a>
</div>
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
},
methods: {
fn1 () {
console.log('div 的点击事件');
},
fn2 () {
// console.log('button 的点击事件');
console.log('a 的点击事件');
}
}
})
</script>
once修饰符
只执行一次
<div id="app">
<button @click="fn">按钮1</button>
<button @click.once="fn">按钮2</button> //只会执行一次
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: { },
methods: {
fn () {
console.log('按钮被点击了');
}
}
})
</script>
按键修饰符
可以通过使用内置别名和键值keycode设置,但是由于不同浏览器keycode不同所以首选内置别名书写。
<div id="app">
<!-- <input type="text" @keyup="fn"> -->
<!-- <input type="text" @keyup.49="fn"> -->
<!-- <input type="text" @keyup.a="fn"> -->
<!-- <input type="text" @keyup.esc="fn"> -->
<input type="text" @keyup.a.b.c="fn"> //可以设置连续多个按键
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: { },
methods: {
fn (event) {
console.log(event);
console.log('输入了对应内容');
}
}
});
</script>
系统修饰符
触发组合按键时使用。作为系统修饰符的包括ctrl、shift、table、mate(window键)、alt键盘。设置组合键之后想使用特定组合键时添加.exact即可
<div id="app">
<!-- <input type="text" @keyup.17.q="fn"> -->
<input type="text" @keyup.ctrl.q.a="fn" > //只要同时包含ctrl和q或a按下就会触发如ctrl+alt+q会触发
<input type="text" @keyup.ctrl.exact.a="fn" > //只有按下ctrl+a会触发
<input type="text" @keyup.exact="fn" > //必须是没有任何系统键按下才触发
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
inputValue: ''
},
methods: {
fn (event) {
console.log(event);
// this.inputValue = '';
}
}
});
鼠标按键修饰符
使用left、right、middle控制左右中键
v-model修饰符
.trim修饰符
用于过滤用户首尾输入的空格。书写在v-model之后
<input type="text" v-model.trim="inputValue">
<p>{{ inputValue }}<p>
.lazy修饰符
数据和euitu双向绑定之后失去焦点时才改变数据
<input type="text" v-model.lazy="inputvalue">
<p>{{ inputvalue }}</p>
.number修饰符
将用户输入的值转化为数值型,无法转化的保留原来值内容
<input type="text" v-model.number="inputvalue"> //用户输入123abc只会展示123
<p>{{ inputvalue }}</p>
自定义指令
自定义全局指令
通过Vue的directive方法设置全局自定义指令,设置全局指令时,directive写在创建实例的外部。el是钩子绑定的元素
<div id="app">
<input type="text" v-focus> //调用时必须写v-
<input type="text" v-focusa.b="1000+1"> //可以再自定义指令之后添加值
</div>
new Vue({
el:'#app',
data:{}
})
Vue.directive('focus', {
inserted (el, binding) { //binding 记录添加钩子的信息,包括用到的修饰符等值
// console.log(el); //el记录了绑定的DOM元素
console.log(binding);
el.focus();
}
});
自定义局部指令
只能在当前vue实例或者组件内部使用,directives写在创建实例内部
<div id="app">
<input type="text" v-focus>
</div>
<script>
// 自定义局部指令
new Vue({
el: '#app',
data: {},
directives: {
focus: {
inserted (el) {
el.focus();
}
}
}
});
</script>
过滤器
用于进行文本内容格式化处理。在插值表达式和v-bind中使用
语法:Vue.filter('过滤器名称',function(value){return '处理结果'})
,调用时将修改的值和使用过滤器的名称之间用 | 连接。允许同时使用多个过滤器,也可以传入多个参数。第一个参数必须是content
全局过滤器
<div id = "app">
<p v-bind:title="value | filter">这是标签</p>
<p>{{ value2 | filterA | filterB | filterC('www.')}}</p> //第一个参数默认为value2
</div>
<script>
new Vue({
el:'#app',
data:{
value:'a-b-c',
vallue2:'c--y-z'
}
});
Vue.filter('filterA',function(value){
return value.split('-').join('');
});
Vue.filter('filterB',function(value){
return value[0].toUpperCase() + value.slice(1);
})
Vue.filter('filterC',function(par1,par2){ //第一个参数指定为过滤前的字符串
return par2 + par1;
})
</script>
局部过滤器
filters属性内容书写在实例内部
<div id='app'>
<p :title='value | filterA'>文本内容</p>
<p>{{ value | filterA }}</p>
</div>
<script>
new Vue({
el:'#app',
data:{
value:'a-b-c'
}
filters:{
filterA:fuctionA(value){
return value.split('-').join('');
}
}
})
</script>
计算属性
仅可适用于计算操作,减少函数执行次数。书写在computed属性中,计算属性只在首次触发时执行一次,以后如果数据不发生变化时不会再执行直接调用最后结果。
<div id="app">
<p>{{ getResult }}</p>
<p>{{ getResult }}</p>
<p>{{ getResult }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
arr: [1, 2, 3, 4, 5]
},
computed: {
getResult () {
console.log('执行了计算属性');
var arr = this.arr;
var sum = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
</script>
计算属性的setter方法
<div id="app">
<p>{{ fullName }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
firstName: '张',
lastName: '三'
},
computed: {
// 默认书写方式:
/* fullName () {
return this.firstName + this.lastName;
} */
// 分开书写 getter 与 setter
fullName: {
get () {
return this.firstName + this.lastName;
},
set (newValue) {
var nameArr = newValue.split(' ');
this.firstName = nameArr[0];
this.lastName = nameArr[1];
}
}
}
});
</script>
侦听器
将要监听的属性值设置成方法,监听数据变化并且执行指定操作,利用watch属性实现。监听变量修改时直接会发生变化。监听对象内收的属性和方法需要设置deep为true,可以传参给handler方法设置处理函数。对数组利用方法修改才可以触发监听。根据索引和长度无法监听。
设置immediate: true
可以立即执行定义的函数。watch分为计算属性watcher、用户watcher和渲染watcher
<div id="app">
<input type="text" v-model="value">
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
value: '这是内容',
obj:{
content1: '内容1',
content2: '内容2'
},
arr: [1,2,3,4]
},
watch: {
value (val , oldVal) { //给value添加侦听器以后每次变化都会被执行一次,参数val和oldVal可不写
console.log('侦听器触发value被修改', val , oldVal)
},
obj:{
deep:true, //给对象中的值添加监听需要设置deep和handler属性,否则不会监听对象内部属性变化
immediate: true, //无需监听的值变化,首次渲染立即执行该函数
handler(val,oldval){ //更改数组或者对象时,回调函数新旧值相同,无法同时获取新旧值。所以对象中只需输入一个参数
console.log('obj 被修改了', val, oldVal);
console.log(val === oldVal); //返回结果为true说明监听对象过程中的val和oldval相同
}
}
arr(val, oldVal){
console.log('数组被修改',val,oldVal) //数组监听无需使用deep,通过索引和length修改数组内容无法监听
}
}
})
</script>
nextTick
vm.$nextTick
可以在dom渲染之后获取到最新的dom数据。
Vue DevTools插件
- 网页必须应用vue.js功能才能看到Vue DevTools,必须使用Vue.js而不是Vue.min.js;网页必须在HTTP协议下打开而不是file协议本地打开
Vue生命周期
生命周期函数:
创建阶段(每个实例只能执行一次):
beforeCreate:实例初始化之前调用
created:实力创建后调用
beroreMount:实力挂在之前调用
mounted:实例挂在完毕
运行阶段(按需调用)
beforeUpdate:数据更新之后,视图更新前调用
updated:试图更新后调用
销毁阶段
beforeDestory:实例销毁之前调用
destoryed:实例销毁之后调用
混入
用来分发组件中的可复用功能。组件和混入对象有同名选项时,组件中的选项会覆盖混入对象的属性。同名的钩子函数则会合并,并且混入钩子先调用。
// 定义一个混入对象
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('hello from mixin!')
}
}
}
// 定义一个使用混入对象的组件
var Component = Vue.extend({
mixins: [myMixin]
})
var component = new Component() // => "hello from mixin!"
provide / inject
允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。
- provide 选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的 property
- inject 选项