小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
Vue常用特性
1. 常用的特性概念
- 表单操作
- 自定义指令
- 计算属性
- 过滤器
- 侦听器
- 生命周期
2. 表单操作
2.1 基于Vue的表单操作
- Input 单行文本
- textarea 多行文本
- select 下拉多选
- radio 单选框
- CheckBox 多选框
示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
form div {
height: 40px;
line-height: 40px;
}
form div:nth-child(4) {
height: auto;
}
form div span:first-child {
display: inline-block;
width: 70px;
}
</style>
</head>
<body>
<div id="app">
<form action="http://www.baidu.com">
<div>
<span>姓名:</span>
<span>
<input type="text" v-model='uname'>
</span>
</div>
<div>
<span>性别:</span>
<span>
<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>
</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' multiple>
<!-- multiple 表示可多选 -->
<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>
<script src="js/vue.min.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
uname: '李四',
gender: 1,
hobby: [1, 2],
occupation: ['2'],
desc: '你好李四'
},
methods: {
handle: function () {
// console.log(this.uname)
// console.log(this.gender)
// console.log(this.hobby.toString())
// console.log(this.occupation.toString())
// console.log(this.desc)
}
}
})
</script>
</body>
</html>
2.2 表单域修饰符
- number : 转化为数值
- trim:去掉开始和结尾的空格
- lazy:将input事件切换为change事件
示例代码如下:
<body>
<div id="app">
<input type="text" v-model.number='age'>
<input type="text" v-model.trim='test'>
<!--azy:将input事件切换为change事件,失去焦点时,立即发生变化 -->
<input type="text" v-model.lazy ='msg' >
<div>{{msg}}</div>
<button @click='handle'>点击</button>
</div>
<script src="js/vue.min.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
age:'',
test:'',
msg:''
},
methods: {
handle: function () {
// console.log(this.age + 2);
// console.log(this.test.length)
}
}
});
</script>
</body>
2.3 自定义指令
Vue也可以自定义指令,如下示例代码展示了不带参数的自定义指令实现元素聚焦的功能:
<body>
<div id="app">
<!-- 自定义指令的使用方法如下:v-focus -->
<input type="text" v-focus>
<input type="text">
</div>
<script src="js/vue.min.js"></script>
<script>
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
});
var vm = new Vue({
el: '#app',
data: {},
methods: {}
});
</script>
</body>
如下展示了一个带参数的自定义指令,实现改变元素背景颜色的功能:
<body>
<div id="app">
<!-- 自定义指令的使用方法如下:v-focus -->
<input type="text" v-color='msg'>
</div>
<script src="js/vue.min.js"></script>
<script>
// 注册一个全局自定义指令 `v-color`
Vue.directive('color', {
// bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
bind: function (el,binding) {
// 改变元素的背景颜色样式
el.style.backgroundColor = binding.value.color
}
});
var vm = new Vue({
el: '#app',
data: {
msg:{
color:'red'
}
},
methods: {}
});
</script>
</body>
效果图如下:
上述展示的两个都是自定义全局指令,如下代码展示了自定义指令的局部指令:
<body>
<div id="app">
<!-- 自定义指令的使用方法如下:v-focus -->
<input type="text" v-color='msg'>
<input type="text" v-focus>
</div>
<script src="js/vue.min.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: {
color: 'red'
}
},
methods: {},
//局部指令,组件中也接受一个 directives 的选项
directives: {
color: {
bind: function (el, binding) {
// 改变元素的背景颜色样式
el.style.backgroundColor = binding.value.color
}
},
// 自定义聚焦指令
focus: {
inserted: function (el) {
// 聚焦元素
el.focus()
}
}
}
});
</script>
</body>
效果与上述代码相同,只是换了个样式。
局部指令,组件中接受一个
directives的选项.
2.4 计算属性
表达式的计算逻辑可能会比较复杂,使用计算属性可以是模板内容更加简洁。
用法如下:
<body>
<div id="app">
<div>{{msg}}</div>
<div>{{reverseString}}</div>
</div>
<script src="js/vue.min.js"></script>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:"NiHao"
},
computed:{
reverseString:function(){
return this.msg.split('').reverse().join('');
}
}
})
</script>
</body>
上述示例代码展示了一个字符串翻转的效果。最终的打印结果为 oaHiN 。
注意:如果msg数据发生变化,计算属性的结果也会跟着变化。
2.4.1 计算属性与方法的区别
- 计算属性是基于他们的依赖进行缓存的
- 方法不存在缓存
计算属性与方法对比的示例代码如下:
<body>
<div id="app">
<div>{{reverseString}}</div>
<div>{{reverseString}}</div>
<div>{{reverseMessage()}}</div>
<div>{{reverseMessage()}}</div>
</div>
<script src="js/vue.min.js"></script>
<script>
/* 计算属性与方法的区别 */
var vm = new Vue({
el: '#app',
data: {
msg: "NiHao"
},
methods: {
reverseMessage: function () {
console.log("methods");
return this.msg.split('').reverse().join('');
}
//该方法打印了两遍methods
},
computed: {
reverseString: function () {
console.log("computed")
return this.msg.split('').reverse().join('');
}
// 计算属性打印了一遍computed
}
})
</script>
</body>
2.5 侦听器
1. 侦听器的应用场景
数据变化是执行异步或开销较大的操作。
2. 侦听器的用法
如下示例代码展示了侦听器的用法:
<body>
<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 src="js/vue.min.js"></script>
<script>
/* 侦听器 */
var 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;
}
}
})
</script>
</body
上述代码实现了修改输入框中的值,下面的fullName也会跟着改变。使用watch进行监听。
2.6 过滤器
2.6.1. 作用:
格式化数据,比如将字符串格式化为首字母大写,将日期格式化为指定日期等。
2.6.2. 自定义过滤器:
Vue.filter('过滤器名称',function(value){
//过滤器业务逻辑
})
2.6.3. 过滤器的使用和创建局部过滤器
示例代码如下:
<body>
<div id="app">
<input type="text" v-model='msg'>
<div>{{msg | upper}}</div>
<div>{{msg | upper | lower}}</div>
<!-- 添加一个经过过滤器修改后首字母为大写的class属性 -->
<div v-bind:class='msg | upper'>测试过滤器</div>
</div>
<script src="js/vue.min.js"></script>
<script>
//过滤器
Vue.filter('upper', function (val) {
return val.charAt(0).toUpperCase() + val.slice(1);
});
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>
</body
2.6.4 带参数的过滤器及其使用方法
Vue.filter('过滤器名称',function(value,arg1){
//value就是过滤器传递过来的参数
})
- 参数一:arg1
注意function中的第二个参数才是使用过滤器是接收的参数,也就是从第二个参数开始。
2.6.4.1 过滤器格式化日期案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>过滤器</title>
</head>
<body>
<div id="app">
<div>{{date | format('yyyy-MM-dd-hh-mm-ss')}}</div>
</div>
<script src="js/vue.min.js"></script>
<script>
//过滤器
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;
}
// 调用dateFormat方法
return dateFormat(value, arg);
})
Vue.filter('upper', function (val) {
return val.charAt(0).toUpperCase() + val.slice(1);
});
var vm = new Vue({
el: '#app',
data: {
date: new Date()
},
})
</script>
</body>
</html>
2.7 生命周期
2.7.1 主要阶段
-
挂载(初始化相关属性)
- beforeCreate
- created
- beforeMount
- mounted( 重要的)
-
更新(元素或组件的变更操作)
- beforeUpdate
- updated
-
销毁(销毁相关属性)
- beforeDestroy
- destroyed
示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生命周期</title>
</head>
<body>
<div id="app">
<div>{{msg}}</div>
<button @click='update'>更新</button>
<button @click='destroy'>销毁</button>
</div>
<script src="js/vue.min.js"></script>
<script>
var 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')
}
})
</script>
</body>
</html>