Vue学习笔记二

Vue常用特性

表单操作

1. 基于Vue的表单操作

  • input单行文本
  • textarea 多行文本
  • select 下拉框
  • redio 单选框
  • checkbox 多选框

html代码如下:

<div id="app">
	<form action="">
		<div>
			<span>名字:</span>
			<span>
				<input type="text" v-model="uname">
			</span>
		</div>
		<div>
			<span>性别:</span>
			<span>
				<input type="radio" id="male" v-model="gender" value="1">
				<label for="male"></label>
				<input type="radio" id="female" v-model="gender" value="2">
				<label for="female"></label>
			</span>
		</div>
		<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>
		<div>
			<span>职业:</span>
			<select v-model="occupation" name="" id="">
				<option value="0">请选择职业</option>
				<option value="1">教师</option>
				<option value="2">软件工程</option>
				<option value="3">律师</option>
			</select>
		</div>
		<div>
			<span>个人简历:</span>
			<textarea v-model="desc"></textarea>
		</div>
		<div>
			<input type="submit" value="提交" @click.prevent="handle">
		</div>
	</form>
</div>

js代码如下:

const vm = new Vue({
	el: '#app',
	data: {
		uname: '神里の凌华',
		gender: '2',
		hobby: ['2'],
		occupation: '0',
		desc: '神里凌华大小姐!'
	},
	methods: {
		handle: function () {
			console.log(this.uname);
			console.log(this.gender);
			console.log(this.hobby);
			console.log(this.occupation);
			console.log(this.desc);
		}
	}
});

2. 表单域修饰符

  • number: 转化为数值
  • trim: 去掉开始和结尾的空格
  • lazy: 将input事件切换为change事件

html代码如下:

<div id="app">
    测试number:<input type="text" v-model.number="age"><br>
    测试trim:<input type="text" v-model.trim="info"><br>
    测试lazy:<input type="text" v-model.lazy="msg">{{msg}}<br>
    <button @click="handle">点击</button>
</div>

js代码如下:

const vm = new Vue({
	el: '#app',
	data: {
		age: '',
		info: '',
		msg: ''
	},
	methods: {
		handle: function () {
			console.log(this.age + 2);
			console.log(this.info);
			console.log(this.msg);
		}
	}
});

自定义指令

1. 自定义指令的语法规则(获取元素焦点)

js代码如下:

Vue.directive('focus', {
	inserted: function (el) {
		el.focus();
	}
})
const vm = new Vue({
	el: '#app',
	data: {
		name: ''
	},
	methods: {
		handle: function () {
		}
	}
})

2. 自定义指令用法

html代码如下:

<div id="app">
    <input type="text" v-focus>
</div>

3. 带参数的自定义指令(改变元素背景色)

js代码如下:

Vue.directive('color', {
	inserted: function (el, binding) {
		el.style.backgroundColor = binding.value.color;
	}
})
const vm = new Vue({
	el: '#app',
	data: {
		name: ''
	},
	methods: {
		handle: function () {
		}
	}
})

html代码如下:

<div id="app">
    <input type="text" v-color="{color: 'orange'}">
</div>

4. 局部指令

js代码如下:

const vm = new Vue({
	el: '#app',
	data: {
		name: ''
	},
    methods: {
		handle: function () {
		}
	},
	directives: {
		focus: {
			inserted: function focus(el) {
				el.focus();
			}
		}
	}
})

html代码如下:

<div id="app">
    <input type="text" v-focus>
</div>

计算属性

1. 为什么需要计算属性

表达式的计算逻辑可能会比较复杂,使用计算属性可以使模板内容更加简洁

html代码如下:

<div id="app">
    <div>{{msg}}</div>
    <div>{{msg.split('').reverse().join('')}}</div>
</div>

js代码如下:

const vm = new Vue({
	el: '#app',
		data: {
		msg: 'Hello'
	}
})

2. 计算属性的用法

html代码如下:

<div id="app">
    <div>{{msg}}</div>
    <div>{{reverseMessage}}</div>
</div>

js代码如下:

const vm = new Vue({
	el: '#app',
		data: {
		msg: 'Hello'
	},
    computed: {
		reverseMessage: function () {
			return this.msg.split('').reverse().join('');
		}
	}
})

3. 计算属性与方法的区别

  • 计算属性是基于它们的依赖(计算的是已有的数据属性)进行缓存的
  • 方法不存在缓存

html代码如下:

<div id="app">
    <div>{{msg}}</div>
    <div>{{msg}}</div>
    <div>{{reverseMessage}}</div>
    <div>{{reverseMessage}}</div>
    <div>{{reverseString()}}</div>
    <div>{{reverseString()}}</div>
</div>

js代码如下:

const vm = new Vue({
	el: '#app',
		data: {
		msg: 'Hello'
	},
    computed: {
		reverseMessage: function () {
			return this.msg.split('').reverse().join('');
		}
	},
    methods: {
		reverseString: function () {
			console.log('methods');
			return this.msg.split('').reverse().join('');
		}
    }
})

执行的控制台结果如下:
在这里插入图片描述

计算属性调用了两次,如果依赖的数据属性没有变化,只会执行一次,因为有缓存

方法调用了两次,即使依赖的数据属性不变化也会执行了两次,因为没有缓存

侦听器

在这里插入图片描述

1. 侦听器的应用场景

数据变化时执行异步或开销较大的操作

2. 侦听器的用法

html代码如下:

<div id="app">
    名:<input type="text" v-model="firstName"><br>
    姓:<input type="text" v-model="lastName"><br>
    全名:<span>{{fullName}}</span>
</div>

js代码如下:

const vm = new Vue({
	el: '#app',
	data: {
		firstName: 'Jim',
		lastName: 'Green',
		fullName: 'Jim Green'
	},
	watch: {
		firstName: function (val) {
			this.fullName = val + ' ' + this.lastName;
		},
		lastName: function (val) {
			this.fullName = this.firstName + ' ' + val;
		}
	}
})

3. 侦听器案例:验证用户名是否可用

需求:输入框中输入姓名,失去焦点时验证是否存在,如果已存在,提示重新输入,如果不存在,提示可以使用。

实现步骤:

① 通过v-model实现数据绑定

② 需要提供提示信息

③ 需要侦听器监听输入信息的变化

④ 需要修改触发的事件

html代码如下:

<div id="app">
    用户名:<input type="text" v-model.lazy="uname">
    <span>{{tip}}</span>
</div>

js代码如下:

const vm = new Vue({
	el: '#app',
	data: {
		uname: '',
		tip: ''
	},
	methods: {
		checkName: function (uname) {
			let that = this;
			setTimeout(function () {
				if (uname == 'admin') {
					that.tip = '用户已存在,请更换一个';
				} else {
					that.tip = '可以使用';
				}
			}, 2000);
		}
	},
	watch: {
		uname: function (val) {
			this.checkName(val);
			this.tip = '正在校验...';
		}
	}
})

计算属性与侦听器的区别

计算属性:是computed中定义的属性,这个属性的值 随着依赖的数据属性的变化而调用getter方法返回的,计算属性的方法中,因为使用return立即返回结果,计算属性的结束就是返回的结果,即使计算属性的方法中有异步操作,修改了数据属性也不会影响计算属性的结果,因为结果已经返回了。

侦听器: 是watch中当监听的数据属性发生变化时,会调用相应的方法处理监听器的方法是一直监听者数据属性的变化,并没有计算属性方法结果的这种返回值,不无论是同步或异步,只要修改了数据属性的值,侦听器都会侦听到并调用对应的方法。

过滤器

1. 过滤器的作用是什么?

格式化数据,比如将字符串格式化为首字母大写,将日期格式化为指定的格式等…

2. 自定义过滤器

js代码如下:

Vue.filter('my-filter', function (value) {
	//过滤器业务逻辑
	return value.toUpperCase();
})
Vue.filter('upper', function (value) {
	//过滤器业务逻辑
	return value.toUpperCase();
})
Vue.filter('lower', function (value) {
	//过滤器业务逻辑
	return value.toLowerCase();
})
Vue.filter('formatId', function (value) {
	//过滤器业务逻辑
	return '00' + value;
})
const vm = new Vue({
	el: '#app',
	data: {
        id: 1,
		msg: 'hello W'
	}
})

3. 过滤器的使用

html代码如下:

<div id="app">
    <div>{{msg}}</div>
    <div>{{msg | my-filter}}</div>
    <div>{{msg | upper}}</div>
    <div>{{msg | upper | lower}}</div>
    <div v-bind:id="id | formatId"></div>
</div>

4. 局部过滤器

html代码如下:

<div id="app">
    <div>{{msg | upper}}</div>
</div>

js代码如下:

const vm = new Vue({
    el: '#app',
    data: {
        id: 1,
        msg: 'hello W'
    },
    filters: {
    upper: function (val) {
    	return val.charAt(0).toUpperCase() + val.slice(1);
    	}
    }
})

5. 带参数的过滤器

html代码如下:

<div id="app">
    <div>{{date | format('yyyy-MM-dd')}}</div>
</div>

6. 过滤器的使用

js代码如下:

Vue.filter('format', function (value, arg1) {
	//过滤器业务逻辑
	let arr = arg1.split('-');
	// console.log(arr);
	let str = '';
	for (let i = 0; i < arr.length; i++) {
		let temp = arr[i];
		switch (temp) {
			case 'yyyy':
				str += value.getFullYear() + '年';
				break;
			case 'MM':
				str += value.getMonth() + 1 + '月';
				break;
			case 'dd':
				str += value.getDate() + '日';
				break;
		}
	}
	return str;
})

生命周期

1. 主要阶段

  • 挂载(初始化相关属性)

    ① beforeCreate

    ② created

    ③ beforeMount

    ④ mounted

  • 更新(元素或组件的变更操作)

    ① beforeUpate

    ② updated

  • 销毁(销毁相关属性)

    ① beforeDestroy

    ② destroy

img

html代码如下:

<div id="app">
    <div>{{msg}}</div>
    <button @click="update">更新</button>
    <button @click="destroy">销毁</button>
</div>

js代码如下:

const vm = new Vue({
	el: '#app',
	data: {
		msg: '生命周期'
	},
	methods: {
		update: function () {
			this.msg = 'hello';
		},
		destroy: function () {
			this.$destroy();
		}
	},
	beforeCreate: function () {
		console.log("beforeCreate");
	},
	created: function () {
		console.log("created");
	},
	beforeMount: function () {
		console.log("beforeMount");
	},
	mounted: function () {
		console.log("mounted");
	},
	beforeUpdate: function () {
		console.log("beforeUpdate");
	},
	updated: function () {
		console.log("updated");
	},
	beforeDestroy: function () {
		console.log("beforeDestroy");
	},
	destroyed: function () {
		console.log("destroyed");
	}
})

综合案例

图书管理
在这里插入图片描述

补充知识(数组相关API)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
css代码如下:

table {
	text-align: center;
	border: 1px dashed #F4DBA7;
}
tr, th, td {
	border: 1px dashed #F4DBA7;
}
.active {
	background-color: #F4DBA7;
}
tr.active td {
	border-bottom: 1px solid greenyellow;
}

html代码如下:

<div id="app">
	<h2 style="text-align: center;">图书管理</h2>
	<table id="booklist" cellpadding="5" cellspacing="0" width="40%" align="center">
		<tbody>
			<tr :class="{active : isActive}">
				<td colspan="4">
				编号:<input type="text" v-model="id">
				名称:<input type="text" v-model="name">
				<input type="button" value="提交" @click="add">
				</td>
			</tr>
			<tr :class="{active : isActive}">
				<th>编号</th>
				<th>名称</th>
				<th>时间</th>
				<th>操作</th>
                </tr>
			<tr v-for="item in list" :key="item.id">
				<td>{{item.id}}</td>
				<td>{{item.name}}</td>
				<td>{{item.date | format('yyyy-MM-dd-hh-mm-ss')}}</td>
				<td><a href="#" @click="modify(item)">修改</a> | <a href="#" @click="del(item.id)">删除</a></td>
			</tr>
		</tbody>
	</table>
</div>

js代码如下:

//处理日期的过滤器
Vue.filter('format', function (value, arg1) {
	//过滤器业务逻辑
	let arr = arg1.split('-');
	let str = '';
	for (let i = 0; i < arr.length; i++) {
	let temp = arr[i];
	switch (temp) {
		case 'yyyy':
			str += value.getFullYear() + '-';
			break;
		case 'MM':
			str += value.getMonth() + 1 + '-';
			break;
		case 'dd':
			str += value.getDate() + '  ';
			break;
		case 'hh':
			str += value.getHours() + ":";
			break;
		case 'mm':
			str += value.getMinutes() + ":";
			break;
		case 'ss':
			str += value.getSeconds();
			break;
		}
	}
	return str;
})
const vm = new Vue({
	el: '#app',
	data: {
		id: '',
		name: '',
		flag: false, //编辑的状态
		isActive: true,
		list: [{
			id: 1,
			name: '三国演义',
			date: new Date()
		}, {
			id: 2,
			name: '西游记',
			date: new Date()
		}, {
			id: 3,
			name: '红楼梦',
			date: new Date()
		}, {
			id: 4,
			name: '水浒传',
			date: new Date()
		}]
	},
	methods: {
		add: function () {
			// 判断是否点击了编辑按钮
			if (this.flag) {
				//先删除数据
				this.del(this.id);
				//插入数据
				this.list.splice(this.id - 1, 0, { id: this.id, name: this.name, date: new Date()});
				this.flag = false;
			} else {
				//添加记录到list中
				this.list.push({
				id: this.id,
				name: this.name,
				date: new Date()
			});
		}
		//将输入框的内容清空
		this.id = this.name = '';
		},
		modify: function (obj) {
			this.flag = true;
			this.id = obj.id;
			this.name = obj.name;
		},
		del: function (id) {
			// some方法循环数组,返回true可以终止循环
			// this.list.some((item, i) => {
			//     if (item.id == id) {
			//         // i是需要删除元素的数组下标 移除1条记录
			//         this.list.splice(i, 1);
			//         // 返回true 终止循环
			//         return true;
			//     }
			// });
			// 通过findIndex方法获取需要删除记录的数组下标
			let index = this.list.findIndex(item => {
				if (item.id == id) {
					return true;
				}
			});
			// 通过splice方法来移除记录
			this.list.splice(index, 1);
		}
	}
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值