计算属性的基本使用
- 使用Mastache语法拼接
<h2>{{firstName+ " " + lastName}}</h2>
- 使用方法methods
<h2>{{getFullName()}}</h2>
- 使用计算属性computed
<h2>{{fullName}}</h2>
例子中计算属性computed看起来和方法似乎一样,只是方法调用需要使用(),而计算属性不用,方法取名字一般是动词见名知义,而计算属性是属性是名词,但这只是基本使用。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<h2>您的firstname:{{firstName}}</h2>
<h2>您的lastname:{{lastName}}</h2>
<h2>您的fullname是从计算属性中得到:{{fullName}}</h2>
<h2>您的fullname是从方法中得到:{{getFullName()}}</h2>
</div>
<script>
const vm = new Vue({
el:'#app',
data(){
return {
firstName:'zhang',
lastName:'san'
}
},
methods:{
getFullName(){
return this.firstName + this.lastName
}
},
computed:{//计算属性 一定要有一个返回值 在页面中渲染时是不需要加小括号的
fullName(){
return this.firstName + this.lastName
}
}
})
</script>
</body>
</html>
计算属性的复杂使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<h2>您的总价:{{totalPrice}}</h2>
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
books: [{
id: 110,
name: "JavaScript从入门到入土",
price: 119
},
{
id: 111,
name: "Java从入门到放弃",
price: 80
},
{
id: 112,
name: "编码艺术",
price: 99
},
{
id: 113,
name: "代码大全",
price: 150
},
]
}
},
computed: {
/* totalPrice() {
let total = 0
for (let i = 0; i < this.books.length; i++) {
total += this.books[i].price
}
return total
} */
/* totalPrice() {
let total = 0
for (let index in this.books) {
total += this.books[index].price
}
return total
} */
/* totalPrice() {
let total = 0;
for(let item of this.books){
total += item.price
}
return total
} */
/* totalPrice() {
let total = 0;
this.books.forEach(item=>{
total += item.price
})
return total
} */
/* map */
/* totalPrice() {
let total = 0;
this.books.map(item=>{
total += item.price
})
return total
} */
/* filter */
/* totalPrice() {
let total = 0;
this.books.filter(item=>{
total += item.price
})
return total
} */
/* reduce */
/* totalPrice() {
return this.books.reduce((total,item)=>{
return total + item.price
},0)
} */
/* totalPrice() {
return this.books.reduce((total,item)=>total + item.price,0)
} */
/* some */
totalPrice() {
let total = 0;
this.books.some(item=>{
total += item.price
})
return total
}
}
})
</script>
</body>
</html>
计算属性中的getter和setter
计算属性一般没有set方法,只读属性,只有get方法,但是上述中newValue就是新的值,也可以使用set方法设置值,但是一般不用
通过这种方式,我们可以在改变计算属性值的同时也改变和计算属性相关联的属性值。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="firstName"/>
<input type="text" v-model="lastName"/>
<input type="text" v-model="fullName"/>
<!-- v-model实现数据的双向绑定 -->
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
firstName: 'zhang',
lastName: 'san'
}
},
computed: { //计算属性 一定要有一个返回值 在页面中渲染时是不需要加小括号的
/* fullName(){
return this.firstName + this.lastName
} */
fullName: {
get: function() {
return this.firstName +','+ this.lastName
},
set:function(val){
var list = val.split(',')
console.log(list);
this.firstName = list[0]
this.lastName = list[1]
}
}
}
})
</script>
</body>
</html>
计算属性和methods的对比
计算属性有缓存,在this.firstName + " " + this.lastName
的属性不变的情况下,methods调用了四次,而计算属性才调用了一次,性能上计算属性明显比methods好。而且在改动firstName的情况下,计算属性只调用一次,methods依然要调用4次。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<h2>您的fullname是从计算属性中得到:{{fullName}}</h2>
<h2>您的fullname是从计算属性中得到:{{fullName}}</h2>
<h2>您的fullname是从计算属性中得到:{{fullName}}</h2>
<h2>您的fullname是从计算属性中得到:{{fullName}}</h2>
<h2>您的fullname是从方法中得到:{{getFullName()}}</h2>
<h2>您的fullname是从方法中得到:{{getFullName()}}</h2>
<h2>您的fullname是从方法中得到:{{getFullName()}}</h2>
<h2>您的fullname是从方法中得到:{{getFullName()}}</h2>
</div>
<script>
const vm = new Vue({
el:'#app',
data(){
return {
firstName:'zhang',
lastName:'san'
}
},
methods:{
getFullName(){
console.log('这里调用了方法getFullName');
return this.firstName + this.lastName
}
},
computed:{//计算属性 一定要有一个返回值 在页面中渲染时是不需要加小括号的
fullName(){
console.log('这里调用了计算属性fullName');
return this.firstName + this.lastName
}
}
})
/* 总结:计算属性的性能是优于方法的 因为计算属性是具有缓存特性的 */
</script>
</body>
</html>
侦听器watch的用法1
监听器中有两个参数 一个是newval新的值 一个是oldval是老值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<h3>{{firstName}}</h3>
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
firstName: "zhang",
lastName: "san",
watchFullName: "zhangsan",
age: 18,
}
},
watch: {
/* firstName(newval,oldval){
//监听器中有两个参数 一个是newval新的值 一个是oldval是老值
console.log(newval);
console.log(oldval);
} */
firstName: "change"
},
methods: {
change(newval, oldval) {
console.log(newval);
console.log(oldval);
}
}
})
</script>
</body>
</html>
侦听器watch的用法2
handler方法就相当于普通侦听器触发的事件,从结果可以看到,组件初始化的时候,侦听器并没有handler方法 ,所以fullName是没有值的
当修改以上代码,加上immediate: true,immediate:true代表watch里面声明了之后会立马执行handler里面的函数。执行相应的逻辑。组件初始化的时候,侦听器会立马(immediate)触发handler方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<p>FullName: {{person.fullname}}</p>
<p>FirstName: <input type="text" v-model="person.firstname"></p>
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
person: {
firstname: 'Menghui',
lastname: 'Jin',
fullname: ''
}
}
},
watch: {
/* fullname(newval,oldval){
console.log(newval);
console.log(oldval);
} */
/* person(newval,oldval){
console.log(newval);
console.log(oldval);
} */
person:{
handler(n,o){
console.log(n);
console.log(o);
this.person.fullname = n.firstname + this.person.lastname
},
immediate:true,//刷新即加载
deep:true//深度监听0
}
}
})
</script>
</body>
</html>
侦听器watch的用法3
当在输入框中输入数据时, 可以发现fullName的值并没有随之改变 这是因为vue无法检测到对象内部属性值的变化,比如person.firstname的变化
所以此时 需要用到vue的深度监听(deep)
此时加上代码 deep: true
可以发现 每次输入框数据变化 fullname随之改变
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<p>FullName: {{person.fullname}}</p>
<p>FirstName: <input type="text" v-model="person.firstname"></p>
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
person: {
firstname: 'Menghui',
lastname: 'Jin',
fullname: ''
}
}
},
computed:{
person2(){
return JSON.parse(JSON.stringify(this.person));//深拷贝
}
},
watch: {
person2:{
handler(n,o){
console.log(this.person);
console.log(n.firstname);
console.log(o.firstname);
},
deep:true//深度监听
}
}
})
</script>
</body>
</html>