代码下载
表单操作
基于Vue的表单操作
- input 单行文本
- textarea 多行文本
- select 下拉多选,multiple属性实现多选,多选时对应的 data 中的数据也要定义成数组
- radio 单选框
- checkbox 多选框,data 中的数据要定义成数组,否则无法实现多选
<div class="main">
<h2>表单基础使用</h2>
<div id="app">
<form action="https://www.baidu.com">
<div>
姓名:
<input type="text" v-model="uname">
</div>
<div>
性别:
<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>
</div>
<div>
爱好:
<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>
职业:
<select v-model="occupation">
<option value="0">请选择职业……</option>
<option value="1">程序员</option>
<option value="2">公务员</option>
<option value="3">医生</option>
</select>
</div>
<div>
特长:
<select v-model="strongPoint" multiple>
<option value="0">请选择特长……</option>
<option value="1">篮球</option>
<option value="2">羽毛球</option>
<option value="3">乒乓球</option>
</select>
</div>
<div>
简介:
<textarea v-model="desc"></textarea>
</div>
<input type="submit" value="提交" @click.prevent="handle">
</form>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
uname: '张三',
gender: '1',
hobby: ['2'],
occupation: '0',
strongPoint: ['1', '2'],
desc: ''
},
methods: {
handle: function() {
console.log('--------------');
console.log('uname: ', this.uname);
console.log('gender: ', this.gender);
console.log('hobby: ', this.hobby);
console.log('hobby: ', this.hobby.toString());
console.log('occupation: ', this.occupation);
console.log('strongPoint: ', this.strongPoint);
console.log('desc: ', this.desc);
}
}
});
</script>
表单修饰符
- .number 转换为数值,当开始输入非数字的字符串时,因为Vue无法将字符串转换成数值,所以属性值将实时更新成相同的字符串。即使后面输入数字,也将被视作字符串。
- .trim 自动过滤用户输入的首尾空白字符,只能去掉首尾的 不能去除中间的空格 .lazy 将input事件切换成change事件。
- .lazy 修饰符延迟了同步更新属性值的时机。即将原本绑定在 input 事件的同步逻辑转变为绑定在 change 事件上,在失去焦点 或者 按下回车键时才更新。
<h3>表单域修饰符</h3>
<div>
number:
<input type="text" v-model="age"> <span v-text="age + 10"></span>
<input type="text" v-model.number="age1"> <span v-text="age1 + 10"></span>
</div>
<div>
trim:
<input type="text" v-model="info"> <span v-text="'长度' + info.length"></span>
<input type="text" v-model.trim="info1"> <span v-text="'长度' + info1.length"></span>
</div>
<div>
lazy:
<input type="text" v-model="msg"> <span v-text="msg"></span>
<input type="text" v-model.lazy="msg1"> <span v-text="msg1"></span>
</div>
<script src="../js/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
age: '',
age1: '',
info: '',
info1: '',
msg: '',
msg1: ''
}
});
</script>
自定义指令
当内置指令不能满足特殊的需求时,Vue允许我们自定义指令。
自定义全局指令
binding 为自定义的函数形参,通过自定义属性传递过来的值存在 binding.value 里面。
自定义局部指令
局部指令,需要定义在 directives 的选项,用法和全局用法一样;局部指令只能在当前组件里面使用;当全局指令和局部指令同名时以局部指令为准。
<div class="main" id="app">
<h2>自定义指令</h2>
<h3>自定义全局指令</h3>
<input type="text" v-focus v-color="color">
<h3>自定义局部指令</h3>
<input type="text" v-focus1 v-color1="color">
</div>
<script src="../js/vue.js"></script>
<script>
Vue.directive('focus', {
inserted: function(el) {
el.focus();
}
});
Vue.directive('color', {
bind: function(el, banding) {
console.log('color: ', banding);
el.style.backgroundColor = banding.value;
}
});
let vm = new Vue({
el: '#app',
data: {
color: 'orange'
},
directives: {
focus1: {
inserted: function(el) {
el.focus();
}
},
color1: {
bind: function(el, banding) {
console.log('color1: ', banding);
el.style.backgroundColor = banding.value;
}
}
}
});
</script>
计算属性 computed
模板中放入太多的逻辑会让模板过重且难以维护,使用计算属性可以让模板更加的简洁。
- 计算属性是基于它们的响应式依赖进行缓存的
- computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是多个变量中的某一个值发生了变化则监控的这个值也就会发生变化
<body>
<div class="main" id="app">
<h2>计算属性</h2>
<h3>计算属性使用</h3>
<div>{{ msg }}</div>
<div>{{ msg.split('').reverse().join('') }}</div>
<div>{{ reverseString }}</div>
<h3>计算属性与方法的区别</h3>
计算属性是基于依赖进行缓存的,而方法不缓存。
<div>{{ sqrM() }}</div>
<div>{{ sqrM() }}</div>
<div>{{ sqrA }}</div>
<div>{{ sqrA }}</div>
</div>
<script src="../js/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
msg: 'hello',
num: 100
},
computed: {
reverseString: function() {
return this.msg.split('').reverse().join('');
},
sqrA: function() {
console.log('sqrA');
return this.num * this.num;
}
},
methods: {
sqrM: function() {
console.log('sqrM');
return this.num * this.num;
}
}
});
</script>
</body>
侦听器 watch
使用watch来响应数据的变化,一般用于异步或者开销较大的操作
- watch 中的属性 一定是data 中 已经存在的数据
- 当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听
<body>
<div class="main" id="app">
<h2>监听器 watch</h2>
<h3>基本使用</h3>
<div>
姓:<input type="text" v-model="firstName">
</div>
<div>
名:<input type="text" v-model="lastName">
</div>
<div>{{ fullName }}</div>
<h3>用户名校验案例</h3>
<div>
<input type="text" placeholder="请输入用户名" v-model.lazy="userName">
<span>{{ message }}</span>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
firstName: '',
lastName: '',
fullName: '',
userName: '',
message: ''
},
watch: {
firstName: function(v) {
// v表示变化之后的值
this.fullName = v + this.lastName;
},
lastName: function(v) {
// v表示变化之后的值
this.fullName = this.firstName + v;
},
userName: function(v) {
setTimeout(() => {
if (v === 'zs' || v === 'ls' || v == 'ww') {
this.message = '该用户名已经存在,请更换';
} else if (v.length > 0) {
this.message = '该用户名可以使用';
} else {
this.message = '';
}
}, 1000);
}
}
});
</script>
</body>
过滤器
Vue.js允许自定义过滤器,可被用于一些常见的文本格式化:
- 过滤器可以用在两个地方:双花括号插值和v-bind表达式
- 过滤器应该被添加在JavaScript表达式的尾部,由“管道”符号指示 支持级联操作
- 过滤器不改变真正的 data,而只是改变渲染的结果,并返回过滤后的版本
- 全局注册时是filter,没有s的。而局部过滤器是filters,是有s的
<body>
<div class="main" id="app">
<h2>过滤器</h2>
<h3>基本用法</h3>
<input type="text" placeholder="请输入英文字母" v-model="msg">
<div>
全局过滤器:<span :id="msg | upper">{{ msg | upper }}</span>
</div>
<div>
局部过滤器:<span :id="msg | lower">{{ msg | lower }}</span>
</div>
<div>
过滤器级联操作:<span :id="msg | lower | upper">{{ msg | upper | lower }}</span>
</div>
<h3>带参数的过滤器</h3>
<div>{{ date }}</div>
<div>{{ date | fomat('yyyy-MM-dd') }}</div>
</div>
<script src="../js/vue.js"></script>
<script>
// 全局过滤器
Vue.filter('upper', function(v){
return v.charAt(0).toUpperCase() + v.slice(1);
});
Vue.filter('fomat', function(v, ag) {
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(v, ag);
});
let app = new Vue({
el: '#app',
data: {
msg: '',
date: new Date()
},
// 局部过滤器
filters: {
lower: function(v) {
return v.charAt(0).toLowerCase() + v.slice(1);
}
}
});
</script>
</body>
生命周期
主要阶段:
- 挂载(初始化相关属性),beforeCreate、created、beforeMount、mounted
- 更新(元素或组件的变更操作),beforeUpdate、updated
- 销毁(销毁相关属性),beforeDestroy、destroyed
Vue实例的产生过程 | 说明 |
---|---|
beforeCreate | 在实例初始化之后,数据观测和事件配置之前被调用 此时data 和 methods 以及页面的 DOM结构都没有初始化 什么都做不了 |
created | 在实例创建完成后被立即调用此时data 和 methods已经可以使用 但是页面还没有渲染出来 |
beforeMount | 在挂载开始之前被调用 此时页面上还看不到真实数据 只是一个模板页面而已 |
mounted | el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。 数据已经真实渲染到页面上 在这个钩子函数里面我们可以使用一些第三方的插件 |
beforeUpdate | 数据更新时调用,发生在虚拟DOM打补丁之前。 页面上数据还是旧的 |
updated | 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。 页面上数据已经替换成最新的 |
beforeDestroy | 实例销毁之前调用 |
destroyed | 实例销毁后调用 |
<body>
<div class="main" id="app">
<h2>生命周期</h2>
<div>{{ msg }}</div>
<button @click="update">更新</button>
<button @click="destroy">销毁</button>
</div>
<script src="../js/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
msg: '我是初始数据'
},
methods: {
update: function() {
this.msg = '我更新了'
},
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>
补充
数组:
- 变异方法(修改原有数据),push()、pop()、shift()、unshift()、splice()、sort()、reverse()
- 替换方法(生成新的数组),filter()、concat()、slice()
动态数组或对象响应式数据,第一个参数是要更改的数据 、 第二个参数是数据的数组中的第几项或对象中的key、 第三个参数更改后的数据:
- Vue.set(vm.items, indexOfItem, newValue)
- vm.$set(vm.items, indexOfItem, newValue)
<body>
<div class="main" id="app">
<h2>常用特性补充</h2>
<h3>数组</h3>
<input type="text" placeholder="请输入水果名" v-model="fname">
<button @click="addHandle">添加</button>
<ul>
<li :key="index" v-for="(model, index) in list">{{ model }} <button @click="deleteHandle(model)">删除</button></li>
</ul>
<h3>对象</h3>
<div>
<div>{{ info.name }}</div>
<div>{{ info.age }}</div>
<div>{{ info.gender }}</div>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
list: [
'苹果',
'梨子',
'桔子'
],
fname: '',
info: {
name: '张三',
age: 18
}
},
methods: {
addHandle: function() {
this.list.unshift(this.fname);
this.fname = '';
},
deleteHandle: function(n) {
// let i = this.list.indexOf(n);
// this.list.splice(i, 1);
this.list = this.list.filter((v) => {
return n !== v;
});
}
}
});
// vm.list[0] = '榴莲';
// vm.list[3] = '菠萝';
Vue.set(vm.list, 0, '香蕉');
vm.$set(vm.list, 3, '荔枝');
// vm.info.age = 20;
// vm.info.gender = '女';
Vue.set(vm.info, 'age', 8);
vm.$set(vm.info, 'gender', '男');
</script>
</body>