Vue.js 核心特性
数据驱动视图
-
数据变化会自动更新到对应元素中,无需手动操作DOM,这种行为称作单向数据绑定
-
对于输入框等可输入元素,可设置双向数据绑定
双向数据绑定是在数据绑定基础上,可自动将元素输入内容更新给数据,实现数据与元素内容的双向绑定 -
Vue.js 的数据驱动视图是基于MVVM模型实现的
-
MVVM(Model-View-ViewModel)是一种软件开发思想
Model 层,代表数据
View 层,代表视图模版
ViewModel 层,代表业务逻辑处理代码
优点
- 基于MVVM模型实现的数据驱动视图解放了DOM操作
- View 与 Model 处理分离,降低代码耦合度
缺点 - 但双向绑定时的Bug调试难度增大
- 大型项目的 View 与 Model 过多,维护成本高
组件化开发
- 组件化开发,允许我们将网页功能封装为自定义 HTML 标签,复用时书写自定义标签名即可
- 组件不仅可以封装结构,还可以封装样式与逻辑代码,大大提高了开发效率与可维护性
基础语法
Vue实例
- Vue实例是通过Vue函数创建的对象,是使用Vue功能的基础
var vm = new Vue({
// 选项对象
})
el选项
- 用来选取一个DOM元素作为Vue实例的挂载目标(不能是html或者body元素)
- 只有挂载元素内部才会被Vue进行处理,外部为普通 HTML 元素
- 代表MVVM中的View
- 未设置 el 的 vue 实例,也可以通过 vm.$mount()进行挂载,参数形式与el规则相同
var vm = new Vue({});
vm.$mount('#app');
插值表达式
-
挂载元素可以使用Vue.js的模版语法,模版中可以通过插值表达式为元素进行动态内容设置,写法为{{}}
-
注意点:
- 插值表达式只能书写在标签内容区域,可以与其他内容混合
- 内部只能书写 JavaScript 表达式,不能书写语句
data选项
- 用于储存 Vue 实例需要使用的数据,值为对象类型
- data中的数据可以通过vm.$data.数据 或 vm.数据 访问
console.log(vm.$data.title)
console.log(vm.title)
-
data中的数据可以直接在视图中通过插值表达式访问
-
data 中的数据为响应式数据,在发生改变时没视图会自动更新
-
data 中存在数组时,索引操作与 length 操作无法自动更新视图,这时可以借助 Vue.set()方法替代操作
Vue.set(vm.contentArr, 0, '生效的新内容')
methods 选项
- 用于存储需要在 Vue 实例中使用的函数
var vm = new Vue({
el: '#app',
data: {
title: 'a-a-a-a'
},
methods: {
fn (value) {
return value.split('-').join('');
}
}
})
- methodes 中的方法可以通过 vm.方法名 访问
- 方法中的this为vm实例,可以便捷访问 vm 数据等功能
Vue.js 指令
Vue.js 的指令就是以v-开头的自定义属性
v-once 指令
- 使元素内部的插值表达式只生效一次
<p v-once>{{title}}</p>
v-text 指令
- 元素内容整体替换为指定纯文本数据
<body>
<p v-text="100">aaa</p>
<p v-text="content">aaa</p>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
content: '内容文本'
},
})
</script>
v-html指令
- 元素内容整体替换为指定的 HTML 文本
<body>
<p v-html="content">aaa</p>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
content: '<span>111</span>'
},
})
</script>
属性绑定 v-bind 指令
- v-bind 指令用于动态绑定 HTML 属性
<p v-bind:titlt="title">标签内容</p>
<!-- 简写 -->
<p :title="title">标签内容</p>
- 如果需要一次绑定多个属性,还可以绑定对象
<body>
<p v-bind="attrObj">p标签的内容</p>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
attrObj: {
id: 'box',
title: '实例内容',
'data-title': 'data-title'
}
}
});
</script>
属性绑定 class绑定
- class 是 HTML属性,可以通过 v-bind 进行绑定,并且可以与 class 属性共存
<body>
<p v-bind:class="cls">标签内容</p>
<p class="a" :class="cls">标签内容</p>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
cls: 'x',
}
});
</script>
- 对于class绑定,Vue.js中还提供了特殊处理方式
<body>
<p :class="{ b:isB, c: isC, 'class-d': true }"></p>
<p :class="['a', {b: isB} ,'c']"></p>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
isB: true,
isC: false
}
});
属性绑定 style绑定
- style 是 HTML 属性,可以通过 v-bind 进行绑定,并且可以与 style 属性共存
<body>
<div id="app">
<p :style="styleObj">标签内容</p>
<p style="width: 100px;" :style="styleObj">标签内容</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
styleObj: {
width: '200px',
height: '100px',
border: '1px solid #ccc',
'font-size': '30px'
}
}
});
</script>
- 当我们希望给元素绑定多个样式对象时,可以设置为数组
<p style="width: 100px;" :style="[styleObj, styleObj2]">标签内容</p>
v-for 指令
- 用于遍历数据渲染结构,常用的数组与对象均可遍历
<body>
<div id="app">
<ul>
<li v-for="item in arr">{{item}}</li>
</ul>
<ul>
<li v-for="value in obj">{{value}}</li>
</ul>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
arr: ['1', '2', '3'],
obj: {
content1: '1',
content2: '2',
content3: '3'
}
}
});
</script>
- 使用 v-for 的同时,应始终指定唯一的 key 属性,可以提高渲染性能避免问题
<body>
<div id="app">
<li v-for="(item, id) in itemList" :key="item.id">
输入框{{ item.value }}: <input type="text">
</li>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
arr: [1, 2, 3],
itemList: [
{
id: 1,
value: 2
},
{
id: 2,
value: 3
},
{
id: 3,
value: 4
}
]
}
})
</script>
- 通过<template>标签设置模版占位符,可以将部分元素或内容作为整体进行操作
v-show指令
- 用于控制元素显示与隐藏,适用于显示隐藏频繁切换时使用。
<div id="app">
<p v-show="true">这个元素会显示</p>
<p v-show="false">这个元素会隐藏</p>
</div>
- 注意
<template>无法使用v-show指令
v-if 指令
- 用于根据条件控制元素的创建与移除
<body>
<div id="app">
<p v-if="false">这是标签内容</p>
<p v-else-if="true">1111</p>
<p v-else-if="true">1111</p>
<p v-else>最后一个p标签</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
bool: true
}
})
</script>
-
给使用 v-if 的同类型元素绑定不同的 key
-
出于性能考虑,应避免将 v-if 与 v-for 应用与同一标签
事件与表单处理
事件处理
v-on 指令
- 用于进行元素的事件绑定
<body>
<div id="app">
<p>{{content}}</p>
<button v-on:click="content='新内容'">按钮</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
content: '默认内容'
}
})
</script>
- Vue.js 还为 v-on 指令提供了简写方式
<div id="app">
<p>{{ content }}</p>
<button @click="content='新内容'">按钮</button>
</div>
- 事件程序代码较多时,可以在methods中设置函数,并设置为事件处理程序
<body>
<div id="app">
<p>{{ content }}</p>
<button v-on:click="fn">点击修改内容</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
content: 'aaa'
},
methods: {
fn() {
this.content = '新内容';
}
}
})
</script>
- 在视图中可以通过 $event 访问事件对象
<body>
<div id="app">
<p>{{ content }}</p>
<button @click="fn(content, $event)">点击修改内容</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
content: 'aaa'
},
methods: {
fn( content, event ) {
console.log(content);
console.log(event);
}
}
})
</script>
表单输入绑定 v-model 指令
- 用于给<input>、<textarea>、<select>元素设置双向数据绑定
<body>
<div id="app">
<p>元素内容为:{{value}}</p>
<input type="text" v-model="value">
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
value: ''
}
})
</script>
输入框绑定
- 输入框分为单行输入框 input 与多行输入框 textarea
<body>
<div id="app">
<p>input 内容为:{{value1}}</p>
<input type="text" v-model="value1">
<p>textarea 内容为:{{value2}}</p>
<textarea v-model="value2"></textarea>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
value1: '',
value2: ''
}
});
</script>
单选按钮绑定
- 单选按钮的双向数据绑定方式如下
<body>
<div id="app">
<p>radio数据为:{{ value3 }}</p>
<input type="radio" id="one" value="1" v-model="value3">
<label for="one">选项一</label>
<input type="radio" id="one" value="2" v-model="value3">
<label for="two">选项一</label>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
value3: ''
}
});
</script>
复选框绑定
- 复选框绑定分为单个选项与多个选项两种情况,书写方式不同
<body>
<div id="app">
<p>单个checkbox选中的数据为: {{ value4 }}</p>
<input type="checkbox" id="item" value="选项内容" v-model="value4">
<label for="item">选项</label>
<p>多个checkbox选中的数据为: {{ value5 }}</p>
<input type="checkbox" id="one" value="选项一内容" v-model="value5">
<label for="one">选项一</label>
<input type="checkbox" id="two" value="选项二内容" v-model="value5">
<label for="two">选项二</label>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
value4: '',
value5: []
}
});
</script>
选择框绑定
- 选择框绑定分为单选绑定与多选绑定两种情况,书写方式不同
<body>
<div id="app">
<p>单选select数据为: {{ value6 }}</p>
<select v-model="value6">
<option value="">请选择</option>
<option value="1">选项一</option>
<option value="2">选项二</option>
<option value="3">选项三</option>
</select>
<p>多选select数据为: {{ value7 }}</p>
<select v-model="value7" multiple>
<option value="1">选项一</option>
<option value="2">选项二</option>
<option value="3">选项三</option>
</select>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
value6: '',
value7: []
}
});
</script>
小结
- input 输入框:绑定字符串值。
- textarea 输入框:绑定字符串值
- radio:绑定字符串值
- checkbox:单个绑定布尔值,多个绑定数组
- select:单选绑定字符串,多选绑定数组
修饰符
修饰符是以点开头的指令后缀,用于给当前指令设置特殊操作
pervent 修饰符
- 用于阻止默认事件行为,相当于 event.preventDefault()
<body>
<div id="app">
<a @click.prevent="fn" href="https://www.baidu.com">baidu</a>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
fn(){
console.log("这是 a 标签的点击事件")
}
}
});
</script>
stop 修饰符
- 用于阻止事件传播,相当于 event.stopPropagation()
<body>
<div id="app">
<div @click="fn1">
<button @click.stop="fn2">按钮</button>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
},
methods: {
fn1() {
console.log('div 的点击事件')
},
fn2() {
console.log('button 的点击事件')
}
}
})
</script>
once 修饰符
<body>
<div id="app">
<button @click="fn">按钮1</button>
<button @click.once="fn">按钮2</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
},
methods:{
fn() {
console.log('按钮被点击了')
}
}
})
</script>
按键修饰符
按键码
- 按键码指的是将按键的按键码作为修饰符使用以标识按键的操作方式
特殊按键
- 特殊按键指的是键盘中类似esc、enter、delete等功能按键,为了更好的兼容性,应首选内置别名。
<body>
<div id="app">
<input type="text" @keyup.49="fn">
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
},
methods: {
fn() {
console.log('输入了对应内容')
}
}
})
</script>
系统修饰符
.ctrl
.alt
.shift
<body>
<div id="app">
<input type="text" @keyup.ctrl.q="fn" v-model="inoutValue">
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
inputValue:''
},
methods: {
fn(event){
this.inputValue = '';
}
}
})
</script>
鼠标按键修饰符
- 用来设置点击事件由鼠标哪个按键来完成
.left
.right
.middle
<button @click.left="fn"></button>
<button @click.right="fn"></button>
<button @click.middle="fn"></button>
v-model 修饰符
.trim 修饰符
- 用于过滤用户输入内容首尾两端的空格
<body>
<div id="app">
<input type="text" v-model.trim = "inputValue">
<p>{{ inputValue }}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
inputValue: ''
}
})
</script>
lazy 修饰符
- 用于将 v-model 的触发方式由 input 事件更改为 change 事件触发
<body>
<div id="app">
<input type="text" v-model.lazy="inputValue">
<p>{{ inputValue }}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
inputValue: ''
}
})
</script>
number 修饰符
- 用于自动将用户输入的值转换为数值类型,如无法被 parseFloat() 转换,则返回原始内容
<body>
<div id="app">
<input type="text" v-model.number="inputValue">
<p>{{ inputValue }}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
inputValue: ''
}
})
</script>
自定义指令
指令用于简化 DOM 操作,相当于对基础 DOM 操作的一种封装
当我们希望使用一些内置指令不具备的DOM功能时,可以进行自定义指令设置
自定义全局指令
- 指的时可以被任意Vue实例或组件使用的指令
<body>
<div id="app">
<input type="text" v-focus>
</div>
</body>
<script>
// 自定义全局指令
Vue.directive('focus', {
inserted (el){
el.focus
}
})
var vm = new Vue({
el: '#app',
data: {
}
})
</script>
自定义局部指令
- 指的是可以在当前 Vue 实例或组件内使用的指令
<body>
<div id="app">
<input type="text" v-foucs>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
},
directives: {
focus: {
inserted (el) {
el.focus();
}
}
}
})
</script>
过滤器
用于进行文本内容格式化处理
过滤器可以在插值表达式和 v-bind 中使用
全局过滤器
- 全局过滤器可以在任意 Vue 实例使用
- 过滤器能在插值表达式和 v-bind 中使用,通过管道符 | 连接数据
<body>
<div id="app">
<p v-bind:title="value | filterA">这是标签</p>
</div>
</body>
<script>
// 设置全局过滤器
Vue.filter('filterA', function (value) {
console.log(value);
return value.split('-').join('')
});
var vm = new Vue({
el: '#app',
data: {
value: 'a-b-c'
}
})
</script>
- 可以将一个数据传入到多个过滤器中进行处理
<body>
<div id="app">
<p v-bind:title="value | filterA | filterB">这是标签</p>
</div>
</body>
<script>
// 设置全局过滤器
Vue.filter('filterA', function (value) {
console.log(value);
return value.split('-').join('')
});
Vue.filter('filterB', function (value) {
console.log(value);
return value[0].toUpperCase() + value.slice(1);
});
var vm = new Vue({
el: '#app',
data: {
value: 'a-b-c'
}
})
</script>
- 一个过滤器可以传入多个参数
<body>
<div id="app">
<p v-bind:title="value | filterA | filterB">这是标签</p>
<p>{{ value | filterC(100, 200) }}</p>
</div>
</body>
<script>
// 设置全局过滤器
Vue.filterC('filterC', function (par1, par2, par3) {
return par2 + par1.spilt('-').join('');
})
var vm = new Vue({
el: '#app',
data: {
value: 'a-b-c'
}
})
</script>
局部过滤器
- 只能在当前 Vue 实例中使用
<body>
<div id="app">
<p>{{ content | filterA }}</p>
</div>
</body>
<script>
// 设置局部过滤器
var vm = new Vue({
el: '#app',
data: {
content: 'a-b-c'
},
filters: {
filterA: function (value) {
value.split('-').join();
}
}
})
</script>
计算属性
- Vue.js 的视图不建议书写复杂逻辑,这样不利于维护
- 计算属性使用时为属性形式,访问时会自动执行对应函数
<body>
<div id="app">
<p>{{ getResult }}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
arr: [1, 2, 3, 4, 5]
},
methods: {
getSum () {
var arr = this.arr;
var sum = 0;
for( var i = 0; i < arr.length; i++){
sum += arr[i];
}
return sum;
}
},
computed: {
getResult () {
var arr = this.arr;
var sum = 0;
for( var i = 0; i < arr.length; i++){
sum += arr[i];
}
return sum;
}
}
})
</script>
methods 与 computed 区别
- computed 具有缓存型,methods 没有
- computed 通过属性名访问,methods 需要调用
- computed 仅适用与计算操作
计算属性的 setter
- 计算属性默认只有 getter,Vue.js也允许给计算属性设置 setter
<body>
<div id="app">
<p>
{{ fullName }}
</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
firstName: '张',
lastName: '三'
},
methods: {
},
computed: {
// 默认书写方式
// fullName () {
// return this.firstName + this.lastName
// }
// 分开书写 getter 与 setter
fullName: {
get () {
return this.firstName + this.lastName;
},
set (nemValue) {
var nameArr = newValue.split(' ');
this.firstName = nameArr[0];
this.lastName = nameArr[1]
}
}
}
})
</script>
侦听器
-
用于监听数据变化并执行指定操作
-
为了监听对象内部值的变化,需要将 watch 书写为对象,并设置选项 deep: true,这时通过handler 设置处理函数
<body>
<div id="app">
<input type="text" v-model="value">
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
title: '这是内容',
obj: {
content1: '内容1',
content2: '内容2'
}
},
watch: {
title (val, oldVal) {
console.log('title');
},
obj: {
deep: true,
handler() {
console.log('obj 被修改了')
}
}
}
});
</script>
注意
当更改数组或对象时,回调函数中的新值与旧值相同,因为它们的引用都指向同一个数组、对象
数组操作不要使用索引与length,无法触发侦听器函数
Vue DevTools
-
是官方提供的用来调试 Vue 应用的工具
image.png
网友评论