Vue常用特性
表单基本操作
获取单选框中的值
通过v-model
<input type="radio" id="male" value="1" v-model='gender'>
<label for="male">男
</label>
<input type="radio" id="female" value="2" v-model='gender'>
<label for="female">女
</label>
<script>
new Vue({
data: {
gender: 2,
},
})
</script>
获取复选框中的值
通过v-model和获取单选框中的值一样复选框 checkbox 这种的组合时 data 中的 hobby 我们要定义成数组 否则无法实现多选
<div>
<span>爱好:
</span>
<input type="checkbox" id="ball" value="1" v-model='hobby'>
<label for="ball">篮球
</label>
<input type="checkbox" id="sing" value="2" v-model='hobby'>
<label for="sing">唱歌
</label>
<input type="checkbox" id="code" value="3" v-model='hobby'>
<label for="code">写代码
</label>
</div>
<script>
new Vue({
data: {
hobby: ['2', '3'],
},
})
</script>
获取下拉框和文本框中的值
通过v-model
<div>
<span>职业:
</span>
<select v-model='occupation' multiple>
<option value="0">请选择职业...
</option>
<option value="1">教师
</option>
<option value="2">软件工程师
</option>
<option value="3">律师
</option>
</select>
<textarea v-model='desc'></textarea>
</div>
<script>
new Vue({
data: {
occupation: ['2', '3'],
desc: 'nihao'
},
})
</script>
表单修饰符
.number 转换为数值
注意点:当开始输入非数字的字符串时,因为Vue无法将字符串转换成数值所以属性值将实时更新成相同的字符串。即使后面输入数字,也将被视作字符串。
.trim 自动过滤用户输入的首尾空白字符
只能去掉首尾的 不能去除中间的空格
.lazy 将input事件切换成change事件
.lazy 修饰符延迟了同步更新属性值的时机。即将原本绑定在 input 事件的同步逻辑转变为绑定在 change 事件上
在失去焦点 或者 按下回车键时才更新
<input v-model.number="age" type="number">
<input v-model.trim="msg">
<input v-model.lazy="msg" >
自定义指令
内置指令不能满足我们特殊的需求Vue允许我们自定义指令
Vue.directive 注册全局指令
<input type="text" v-focus>
<script>
Vue.directive('focus', {
inserted: function (el) {
el.focus();
}
});
new Vue({
el:'#app'
});
</script>
Vue.directive 注册全局指令 带参数
<input type="text" v-color='msg'>
<script type="text/javascript">
Vue.directive('color', {
bind: function(el, binding){
el.style.backgroundColor = binding.value.color;
}
});
var vm = new Vue({
el: '#app',
data: {
msg: {
color: 'blue'
}
}
});
</script>
自定义指令局部指令
局部指令,需要定义在 directives 的选项 用法和全局用法一样局部指令只能在当前组件里面使用当全局指令和局部指令同名时以局部指令为准
<input type="text" v-color='msg'>
<input type="text" v-focus>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
msg: {
color: 'red'
}
},
directives: {
color: {
bind: function(el, binding){
el.style.backgroundColor = binding.value.color;
}
},
focus: {
inserted: function(el) {
el.focus();
}
}
}
});
</script>
计算属性 computed
模板中放入太多的逻辑会让模板过重且难以维护 使用计算属性可以让模板更加的简洁计算属性是基于它们的响应式依赖进行缓存的computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化
<div id="app">
<div>{{reverseString}}
</div>
<div>{{reverseString}}
</div>
<div>{{reverseMessage()}}
</div>
<div>{{reverseMessage()}}
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
msg: 'Nihao',
num: 100
},
methods: {
reverseMessage: function(){
console.log('methods')
return this.msg.split('').reverse().join('');
}
},
computed: {
reverseString: function(){
console.log('computed')
var total = 0;
for(var i=0;i<=this.num;i++){
total += i;
}
return total;
}
}
});
</script>
侦听器 watch
使用watch来响应数据的变化一般用于异步或者开销较大的操作watch 中的属性 一定是data 中 已经存在的数据当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听
<div id="app">
<div>
<span>名:
</span>
<span>
<input type="text" v-model='firstName'>
</span>
</div>
<div>
<span>姓:
</span>
<span>
<input type="text" v-model='lastName'>
</span>
</div>
<div>{{fullName}}
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
firstName: 'Jim',
lastName: 'Green',
},
watch: {
firstName: function(val) {
this.fullName = val + ' ' + this.lastName;
},
lastName: function(val) {
this.fullName = this.firstName + ' ' + val;
}
}
});
</script>
过滤器
Vue.js允许自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和v-bind表达式。过滤器应该被添加在JavaScript表达式的尾部,由“管道”符号指示支持级联操作过滤器不改变真正的data,而只是改变渲染的结果,并返回过滤后的版本全局注册时是filter,没有s的。而局部过滤器是filters,是有s的
<div id="app">
<input type="text" v-model='msg'>
<div>{{msg | upper}}
</div>
<div>{{msg | upper | lower}}
</div>
<div :abc='msg | upper'>测试数据
</div>
</div>
<script type="text/javascript">
Vue.filter('lower', function(val) {
return val.charAt(0).toLowerCase() + val.slice(1);
});
var vm = new Vue({
el: '#app',
data: {
msg: ''
},
filters: {
upper: function(val) {
return val.charAt(0).toUpperCase() + val.slice(1);
}
}
});
</script>
过滤器中传递参数
<div id="box">
{{ message | filterA('arg1', 'arg2') }}
</div>
<script>
Vue.filter('filterA',function(n,a,b){
if(n<10){
return n+a;
}else{
return n+b;
}
});
new Vue({
el:"#box",
data:{
message: "哈哈哈"
}
})
</script>
生命周期
事物从出生到死亡的过程Vue实例从创建 到销毁的过程 ,这些过程中会伴随着一些函数的自调用。我们称这些函数为钩子函数
####常用的 钩子函数
beforeCreate在实例初始化之后,数据观测和事件配置之前被调用 此时data 和 methods 以及页面的DOM结构都没有初始化 什么都做不了
created在实例创建完成后被立即调用此时data 和 methods已经可以使用 但是页面还没有渲染出来beforeMount在挂载开始之前被调用 此时页面上还看不到真实数据 只是一个模板页面而已mountedel被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。 数据已经真实渲染到页面上 在这个钩子函数里面我们可以使用一些第三方的插件beforeUpdate数据更新时调用,发生在虚拟DOM打补丁之前。 页面上数据还是旧的updated由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。 页面上数据已经替换成最新的beforeDestroy实例销毁之前调用destroyed实例销毁后调用
数组变异方法
在 Vue 中,直接修改对象属性的值无法触发响应式。当你直接修改了对象属性的值,你会发现,只有数据改了,但是页面内容并没有改变变异数组方法即保持数组方法原有功能不变的前提下对其进行功能拓展
push()往数组最后面添加一个元素,成功返回当前数组的长度
pop()删除数组的最后一个元素,成功返回删除元素的值shift()删除数组的第一个元素,成功返回删除元素的值unshift()往数组最前面添加一个元素,成功返回当前数组的长度splice()有三个参数,第一个是想要删除的元素的下标(必选),第二个是想要删除的个数(必选),第三个是删除 后想要在原位置替换的值sort()sort() 使数组按照字符编码默认从小到大排序,成功返回排序后的数组reverse()reverse() 将数组倒序,成功返回倒序后的数组
替换数组
不会改变原始数组,但总是返回一个新数组
filterfilter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
concatconcat() 方法用于连接两个或多个数组。该方法不会改变现有的数组sliceslice() 方法可从已有的数组中返回选定的元素。该方法并不会修改数组,而是返回一个子数组
动态数组响应式数据
Vue.set(a,b,c) 让 触发视图重新更新一遍,数据动态起来a是要更改的数据 、 b是数据的第几项、 c是更改后的数据
图书列表案例
静态列表效果基于数据实现模板效果处理每行的操作按钮
1、 提供的静态数据
数据存放在vue 中 data 属性中
var vm
= new Vue({
el
: '#app',
data
: {
books
: [{
id
: 1,
name
: '三国演义',
date
: ''
},{
id
: 2,
name
: '水浒传',
date
: ''
},{
id
: 3,
name
: '红楼梦',
date
: ''
},{
id
: 4,
name
: '西游记',
date
: ''
}]
}
}); var vm
= new Vue({
el
: '#app',
data
: {
books
: [{
id
: 1,
name
: '三国演义',
date
: ''
},{
id
: 2,
name
: '水浒传',
date
: ''
},{
id
: 3,
name
: '红楼梦',
date
: ''
},{
id
: 4,
name
: '西游记',
date
: ''
}]
}
});
2、 把提供好的数据渲染到页面上
利用 v-for循环 遍历 books 将每一项数据渲染到对应的数据中
<tbody>
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}
</td>
<td>{{item.name}}
</td>
<td>{{item.date}}
</td>
<td>
<a href="" @click.prevent>修改
</a>
<span>|
</span>
<a href="" @click.prevent>删除
</a>
</td>
</tr>
</tbody>
3、 添加图书
通过双向绑定获取到输入框中的输入内容给按钮添加点击事件把输入框中的数据存储到 data 中的 books 里面
<div>
<h1>图书管理
</h1>
<div class="book">
<div>
<label for="id">
编号:
</label>
<input type="text" id="id" v-model='id'>
<label for="name">
名称:
</label>
<input type="text" id="name" v-model='name'>
<button @click='handle'>提交
</button>
</div>
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
books: [{
id: 1,
name: '三国演义',
date: ''
},{
id: 2,
name: '水浒传',
date: ''
},{
id: 3,
name: '红楼梦',
date: ''
},{
id: 4,
name: '西游记',
date: ''
}]
},
methods: {
handle: function(){
var book = {};
book.id = this.id;
book.name = this.name;
book.date = '';
this.books.push(book);
this.id = '';
this.name = '';
}
}
});
</script>
4 修改图书-上
点击修改按钮的时候 获取到要修改的书籍名单
4.1 给修改按钮添加点击事件, 需要把当前的图书的id 传递过去 这样才知道需要修改的是哪一本书籍 把需要修改的书籍名单填充到表单里面
4.2 根据传递过来的id 查出books 中 对应书籍的详细信息4.3 把获取到的信息填充到表单
<div id="app">
<div class="grid">
<div>
<h1>图书管理
</h1>
<div class="book">
<div>
<label for="id">
编号:
</label>
<input type="text" id="id" v-model='id' :disabled="flag">
<label for="name">
名称:
</label>
<input type="text" id="name" v-model='name'>
<button @click='handle'>提交
</button>
</div>
</div>
</div>
<table>
<thead>
<tr>
<th>编号
</th>
<th>名称
</th>
<th>时间
</th>
<th>操作
</th>
</tr>
</thead>
<tbody>
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}
</td>
<td>{{item.name}}
</td>
<td>{{item.date}}
</td>
<td>
<a href="" @click.prevent='toEdit(item.id)'>修改
</a>
<span>|
</span>
<a href="" @click.prevent>删除
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
flag: false,
id: '',
name: '',
books: [{
id: 1,
name: '三国演义',
date: ''
},{
id: 2,
name: '水浒传',
date: ''
},{
id: 3,
name: '红楼梦',
date: ''
},{
id: 4,
name: '西游记',
date: ''
}]
},
methods: {
handle: function(){
var book = {};
book.id = this.id;
book.name = this.name;
book.date = '';
this.books.push(book);
this.id = '';
this.name = '';
},
toEdit: function(id){
console.log(id)
var book = this.books.filter(function(item){
return item.id == id;
});
console.log(book)
this.id = book[0].id;
this.name = book[0].name;
}
}
});
</script>
5 修改图书-下
5.1 定义一个标识符, 主要是控制 编辑状态下当前编辑书籍的id 不能被修改 即 处于编辑状态下 当前控制书籍编号的输入框禁用5.2 通过属性绑定给书籍编号的 绑定 disabled 的属性 flag 为 true 即为禁用5.3 flag 默认值为false 处于编辑状态 要把 flag 改为true 即当前表单为禁用5.4 复用添加方法 用户点击提交的时候依然执行 handle 中的逻辑如果 flag为true 即 表单处于不可输入状态 此时执行的用户编辑数据数据
<div id="app">
<div class="grid">
<div>
<h1>图书管理
</h1>
<div class="book">
<div>
<label for="id">
编号:
</label>
<input type="text" id="id" v-model='id' :disabled="flag">
<label for="name">
名称:
</label>
<input type="text" id="name" v-model='name'>
<button @click='handle'>提交
</button>
</div>
</div>
</div>
<table>
<thead>
<tr>
<th>编号
</th>
<th>名称
</th>
<th>时间
</th>
<th>操作
</th>
</tr>
</thead>
<tbody>
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}
</td>
<td>{{item.name}}
</td>
<td>{{item.date}}
</td>
<td>
<a href="" @click.prevent='toEdit(item.id)'>修改
</a>
<span>|
</span>
<a href="" @click.prevent>删除
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
flag: false,
id: '',
name: '',
},
methods: {
handle: function() {
if (this.flag) {
this.books.some((item) => {
if (item.id == this.id) {
item.name = this.name;
return true;
}
});
this.flag = false;
} else {
var book = {};
book.id = this.id;
book.name = this.name;
book.date = '';
this.books.push(book);
this.id = '';
this.name = '';
}
this.id = '';
this.name = '';
},
toEdit: function(id) {
this.flag = true;
console.log(id)
var book = this.books.filter(function(item) {
return item.id == id;
});
console.log(book)
this.id = book[0].id;
this.name = book[0].name;
}
}
});
</script>
6 删除图书
6.1 给删除按钮添加事件 把当前需要删除的书籍id 传递过来6.2 根据id从数组中查找元素的索引6.3 根据索引删除数组元素
<tbody>
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}
</td>
<td>{{item.name}}
</td>
<td>{{item.date}}
</td>
<td>
<a href="" @click.prevent='toEdit(item.id)'>修改
</a>
<span>|
</span>
<a href="" @click.prevent='deleteBook(item.id)'>删除
</a>
</td>
</tr>
</tbody>
<script type="text/javascript">
var vm = new Vue({
methods: {
deleteBook: function(id){
#
#
#
# 6.4 根据filter 方法 过滤出来id 不是要删除书籍的id
# 因为 filter 是替换数组不会修改原始数据 所以需要 把 不是要删除书籍的id 赋值给 books
this.books = this.books.filter(function(item){
return item.id != id;
});
}
}
});
</script>
常用特性应用场景
1 过滤器
Vue.filter 定义一个全局过滤器
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}
</td>
<td>{{item.name}}
</td>
<td>{{item.date | format('yyyy-MM-dd hh:mm:ss')}}
</td>
<td>
<a href="" @click.prevent='toEdit(item.id)'>修改
</a>
<span>|
</span>
<a href="" @click.prevent='deleteBook(item.id)'>删除
</a>
</td>
</tr>
<script>
#1.1 Vue.filter 定义一个全局过滤器
Vue.filter('format', function(value, arg) {
function dateFormat(date, format) {
if (typeof date === "string") {
var mts = date.match(/(\/Date\((\d+)\)\/)/);
if (mts && mts.length >= 3) {
date = parseInt(mts[2]);
}
}
date = new Date(date);
if (!date || date.toUTCString() == "Invalid Date") {
return "";
}
var map = {
"M": date.getMonth() + 1,
"d": date.getDate(),
"h": date.getHours(),
"m": date.getMinutes(),
"s": date.getSeconds(),
"q": Math.floor((date.getMonth() + 3) / 3),
"S": date.getMilliseconds()
};
format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
var v = map[t];
if (v !== undefined) {
if (all.length > 1) {
v = '0' + v;
v = v.substr(v.length - 2);
}
return v;
} else if (t === 'y') {
return (date.getFullYear() + '').substr(4 - all.length);
}
return all;
});
return format;
}
return dateFormat(value, arg);
})
#1.2 提供的数据 包含一个时间戳 为毫秒数
[{
id: 1,
name: '三国演义',
date: 2525609975000
},{
id: 2,
name: '水浒传',
date: 2525609975000
},{
id: 3,
name: '红楼梦',
date: 2525609975000
},{
id: 4,
name: '西游记',
date: 2525609975000
}];
</script>
2 自定义指令
让表单自动获取焦点通过Vue.directive 自定义指定
<input type="text" id="id" v-model='id' :disabled="flag" v-focus>
<script>
# 2.1 通过Vue.directive 自定义指定
Vue.directive('focus', {
inserted: function (el) {
el.focus();
}
});
</script>
3 计算属性
通过计算属性计算图书的总数
图书的总数就是计算数组的长度
<div class="total">
<span>图书总数:
</span>
<span>{{total}}
</span>
</div>
<script type="text/javascript">
var vm = new Vue({
data: {
flag: false,
submitFlag: false,
id: '',
name: '',
books: []
},
computed: {
total: function(){
return this.books.length;
}
},
});
</script>
生命周期