计算属性和监视
计算属性:
- 1)在 computed 属性对象中定义计算属性的方法
- 2)在页面中使用{{方法名}}来显示计算的结果
监视属性
- 1)通过通过 vm 对象的$watch()或 watch 配置来监视指定的属性
- 2)当属性变化时, 回调函数自动调用, 在函数内部进行计算
计算属性高级
- 1)通过 getter/setter 实现对属性数据的显示和监视
- 2)计算属性存在缓存, 多次读取只执行一次 getter 计算
class 与 style 绑定
理解
- 1)在应用界面中, 某个(些)元素的样式是变化的
- 2)class/style 绑定就是专门用来实现动态样式效果的技术
<div id="demo">
姓: <input type="text" placeholder="First Name" v-model="firstName"><br>
名: <input type="text" placeholder="Last Name" v-model="lastName"><br>
<!--fullName1是根据fistName和lastName计算产生-->
姓名1(单向): <input type="text" placeholder="Full Name1" v-model="fullName1"><br>
姓名2(单向): <input type="text" placeholder="Full Name2" v-model="fullName2"><br>
姓名3(双向): <input type="text" placeholder="Full Name3" v-model="fullName3"><br>
<p>{{fullName1}}</p>
<p>{{fullName1}}</p>
<p>{{fullName1}}</p>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
const vm = new Vue({
el: '#demo',
data: {
firstName: 'A',
lastName: 'B',
// fullName1: 'A B'
fullName2: 'A B'
},
computed: {
// 什么时候执行:初始化显示/相关的data属性数据发生改变
// 计算并返回当前属性的值
fullName1(){//计算属性的一个方法,方法的返回值作为属性值
console.log('fullName1()');
return this.firstName + ' ' + this.lastName;
},
fullName3: {
/*
回调函数要满足3个条件:
1、你定义的;
2、你没有调用;
3、但最终它执行了
什么时候调用?
用来做什么?
*/
// 回调函数,当需要读取当前属性值时回调,根据相关的数据计算并返回当前属性的值
get(){
return this.firstName + ' ' + this.lastName;
},
// 回调函数,监视当前属性值的变化,当属性值发生改变时回调,更新相关的属性数据
set(value){// value就是fullName3的最新属性值
const names = value.split(' ');
this.firstName = names[0];
this.lastName = names[1];
}
}
},
watch: {//配置监视
firstName: function(value){//firstName发生了变化
console.log(this);//就是VM对象
this.fullName2 = value + ' ' + this.lastName;
}
}
})
vm.$watch('lastName', function(value){
// 更新fullName2
this.fullName2 = this.firstName + ' ' + value;
});
</script>
class 绑定
- 1):class='xxx'
- 2)表达式是字符串: 'classA'
- 3)表达式是对象: {classA:isA, classB: isB}
- 4)表达式是数组: ['classA', 'classB']
style 绑定
- 1):style="{ color: activeColor, fontSize: fontSize + 'px' }"
- 2)其中 activeColor/fontSize 是 data 属性
<style type="text/css">
.aClass{
color: red;
}
.bClass{
color: blue;
}
.cClass{
font-size: 30px;
}
</style>
</head>
<body>
<div id="demo">
<h2>1. class绑定: :class='xxx'</h2>
<p class="cClass" :class="a">xxx是字符串</p>
<p :class="{aClass: isA, bClass: isB}">xxx是对象</p>
<p :class="['aClass', 'cClass']">xxx是数组</p>
<h2>2. style绑定</h2>
<p :style="{color: activeColor, fontSize: fontSize + 'px'}">style绑定</p>
<button @click="update">更新</button>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#demo',
data: {
a: 'aClass',
isA: true,
isB: false,
activeColor: 'red',
fontSize: 20
},
methods: {
update(){
this.a = 'bClass';
this.isA = false;
this.isB = true;
this.activeColor = 'green';
this.fontSize = 30;
}
}
})
</script>
条件渲染
条件渲染指令
- 1)v-if 与 v-else
- 2)v-show
比较 v-if 与 v-show
- 3)如果需要频繁切换 v-show 较好
- 4)当条件不成立时, v-if 的所有子节点不会解析
<div id="demo">
<p v-if="ok">成功了</p>
<p v-else="true">失败了</p>
<p v-show="ok">表白成功</p>
<p v-show="!ok">表白失败</p>
<button @click="ok=!ok">切换</button>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#demo',
data: {
ok: false
}
})
</script>
列表渲染
列表显示指令
- 数组: v-for / index
- 对象: v-for / key
<div id="demo">
<h2>测试: v-for 遍历数组</h2>
<ul>
<li v-for="(p, index) in persons" :key="index">
{{index}}---{{p.name}}---{{p.age}}
---<button @click="deleteP(index)">删除</button>
---<button @click="updateP(index, {name: 'Lucy', age: 20})">更新</button>
</li>
</ul>
<h2>测试: v-for 遍历对象</h2>
<ul>
<li v-for="(value, key) in persons[1]" :key="key">
{{value}}---{{key}}
</li>
</ul>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
vue本身只是监视了persons的改变,没有监视数组内部数据的改变
vue重写了数组中的一系列改变数组内部数据的方法(先调用原生,再更新界面)-->数组内部改变,界面自动变化
*/
new Vue({
el: '#demo',
data: {
persons: [
{name: 'Tom', age:18},
{name: 'Jack', age:16},
{name: 'Bob', age:19},
{name: 'Rose', age:17}
]
},
methods: {
deleteP(index){
// 删除persons中指定index的p
this.persons.splice(index, 1);
},
updateP(index, newP){
// 并没有改变persons本身,数组内部发生变化,但并没调用变异方法,Vue不会更新界面
// this.persons[index] = newP;
// this.persons = [];
this.persons.splice(index, 1, newP);
}
}
})
</script>
列表的更新显示
- 删除 item
- 替换 item
列表的高级处理
- 列表过滤
- 列表排序
<div id="demo">
<input type="text" v-model="searchName">
<ul>
<li v-for="(p, index) in filterPersons" :key="index">
{{index}}---{{p.name}}---{{p.age}}
</li>
</ul>
<div>
<button @click="setOrderType(1)">年龄升序</button>
<button @click="setOrderType(2)">年龄降序</button>
<button @click="setOrderType(0)">原本顺序</button>
</div>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#demo',
data: {
searchName: '',
orderType: 0,// 0代表原本、1代表升序、2代表降序
persons: [
{name: 'Tom', age:18},
{name: 'Jack', age:16},
{name: 'Bob', age:19},
{name: 'Rose', age:17}
]
},
computed: {
filterPersons(){
// 取出相关的数据
const {searchName, persons, orderType} = this;
// 最终需要显示的数组
let fPersons;
// 对persons进行过滤
fPersons = persons.filter(p => p.name.indexOf(searchName)!==-1);
// 排序
if(orderType!==0){
fPersons.sort(function(p1, p2){
// 1代表升序、2代表降序
if(orderType===2){
// 如果返回负数则p1在前,返回正数则p2在前
return p2.age - p1.age;
}else{
return p1.age - p2.age;
}
})
}
return fPersons;
}
},
methods: {
setOrderType(orderType){
this.orderType = orderType;
}
}
})
</script>
事件处理
绑定监听:
- 1)v-on:xxx="fun"
- 2)@xxx="fun"
- 3)@xxx="fun(参数)"
- 4)默认事件形参: event
- 5)隐含属性对象: $event
事件修饰符
- 1).prevent : 阻止事件的默认行为 event.preventDefault()
- 2).stop : 停止事件冒泡 event.stopPropagation()
按键修饰符
- 1).keycode : 操作的是某个 keycode 值的键
- 2).keyName : 操作的某个按键名的键(少部分)
<div id="example">
<h2>1. 绑定监听</h2>
<button @click="test1">test1</button>
<button @click="test2('hello')">test2</button>
<!-- <button @click="test3($event)">test3</button> -->
<button @click="test3">test3</button>
<button @click="test4(123, $event)">test4</button>
<h2>2. 事件修饰符</h2>
<div style="width: 200px;height: 200px;background: red" @click="test5">
<div style="width: 100px;height: 100px;background: blue" @click.stop="test6"></div>
</div>
<a href="http://www.baidu.com" @click.prevent="test7">去百度</a>
<h2>3. 按键修饰符</h2>
<input type="text" @keyup.13="test8">
<input type="text" @keyup.enter="test8">
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#example',
data: {
test1(){
alert('test1');
},
test2(msg){
alert(msg);
},
test3(event){
alert(event.target.innerHTML);
},
test4(number, event){
alert(number + '---' + event.target.innerHTML);
},
test5(){
alert('out');
},
test6(){
alert('inner');
},
test7(){
alert('点击了');
},
test8(event){
// if(event.keyCode === 13){
alert(event.target.value + ',' + event.keyCode);
// }
}
}
})
</script>
表单输入绑定
使用 v-model 对表单数据自动收集
- 1)text/textarea
- 2)checkbox
- 3)radio
- 4)select
<div id="demo">
<form action="/xxx" @submit.prevent="handleSubmit">
<span>用户名: </span>
<input type="text" v-model="username"><br>
<span>密码: </span>
<input type="password" v-model="pwd"><br>
<span>性别: </span>
<input type="radio" id="female" value="女" v-model="gender">
<label for="female">女</label>
<input type="radio" id="male" value="男" v-model="gender">
<label for="male">男</label><br>
<span>爱好: </span>
<input type="checkbox" id="basket" value="basket" v-model="hobby">
<label for="basket">篮球</label>
<input type="checkbox" id="foot" value="foot" v-model="hobby">
<label for="foot">足球</label>
<input type="checkbox" id="pingpang" value="pingpang" v-model="hobby">
<label for="pingpang">乒乓</label><br>
<span>城市: </span>
<select v-model="cityId">
<option value="">未选择</option>
<option :value="city.id" v-for="(city, index) in allCitys" :key="index">{{city.name}}</option>
</select><br>
<span>介绍: </span>
<textarea rows="10" v-model="desc"></textarea><br><br>
<input type="submit" value="注册">
</form>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#demo',
data: {
username: '',
pwd: '',
gender: '女',
hobby: ['foot'],
allCitys: [{id: 1, name: 'BJ'}, {id: 2, name: 'SH'}, {id: 3, name: 'GD'}],
cityId: '1',
desc: ''
},
methods:{
handleSubmit(){
console.log(this.username, this.pwd);
}
}
})
</script>
Vue 实例生命周期
生命周期流程图
生命周期流程图
vue 生命周期分析
1)初始化显示
*beforeCreate()
*created()
*beforeMount()
*mounted()
2)更新状态: this.xxx = value
*beforeUpdate()
*updated()
3)销毁 vue 实例: vm.$destory()
*beforeDestory()
*destoryed()
常用的生命周期方法
- 1)created()/mounted(): 发送 ajax 请求, 启动定时器等异步任务
- 2)beforeDestory(): 做收尾工作, 如: 清除定时器
<!--
1. vue对象的生命周期
1). 初始化显示
* beforeCreate()
* created()
* beforeMount()
* mounted()
2). 更新显示:this.xxx = value
* beforeUpdate()
* updated()
3). 销毁vue实例: vm.$destory()
* beforeDestory()
* destoryed()
2. 常用的生命周期方法
mounted(): 发送ajax请求, 启动定时器等异步任务
beforeDestory(): 做收尾工作, 如: 清除定时器
-->
<div id="test">
<button @click="destroyVM">destroy vm</button>
<p v-show="isShow">Vue实例的生命周期</p>
<p>{{isShow}}</p>
<p>{{isShow}}</p>
<p>{{isShow}}</p>
<p>{{isShow}}</p>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#test',
data: {
isShow: true
},
// 1、初始化阶段
beforeCreate(){
console.log('beforeCreate()');
},
created(){
console.log('created()');
},
beforeMount(){
console.log('beforeMount()');
},
mounted(){// 初始化显示之后立即调用(1次)
console.log('mounted()');
this.intervalId = setInterval(() => {
console.log('-------->');
this.isShow = !this.isShow;// 更新数据
}, 1000);
},
// 2、更新阶段
beforeUpdate(){
console.log('beforeUpdate()');
},
updated(){
console.log('updated()');
},
// 3、死亡阶段
beforeDestroy(){// 死亡之前调用(1次)
console.log('beforeDestroy()');
// 清除定时器
clearInterval(this.intervalId);
},
destroyed(){
console.log('destroyed()');
},
methods: {
destroyVM(){
// 干掉VM
this.$destroy();
}
}
})
</script>
网友评论