直接显示的用法-不太好
插值语法实现姓名案例--直接在{{}}里面,需求也写在里面--会导致内容变长,一眼不明了,按照Vue风格讲,应该在使用简单表达式在模板里面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js引入/测试版本/vue.js"></script>
</head>
<body>
<!-- 准备容器 -->
<div id='root'>
姓:<input type="text" v-model:value=firstName>
<br>
名:<input type="text" v-model:value=secondName>
<br>
<span>姓名:</span>
<!-- <span>{{firstName+'-'+secondName}}</span> -->
<!-- slice直接写会让其变的长 太麻烦 不报错 -->
<!-- 截取前3位 -->
<span>{{firstName.slice(0,3)}}-{{secondName}}</span>
</div>
<script>
Vue.config.keyCodes.a = 13;
new Vue({
el: '#root',
data:{
firstName: '张',
secondName:'三',
},
methods: {
showInfo(e) {
console.log(e.target.value)
}
},
});
</script>
</body>
</html>
使用methods方法实现同步显示
解决办法:showFullName展示插值语法显示的是函数{{showFullName}}
在绑定事件的时候methods里面的方法作为事件回调使用
但是如果需要直接使用可以使用插值语法,只是需要加上函数执行的小括号,就是调用函数的返回值插入,不加会直接插入函数
<!-- 准备容器 -->
<div id='root'>
姓:<input type="text" v-model:value=firstName>
<br>
名:<input type="text" v-model:value=secondName>
<br>
<span>姓名:</span>
<!-- <span>{{firstName+'-'+secondName}}</span> -->
<!-- slice直接写会让其变的长 太麻烦 不报错 -->
<!-- 截取前3位 -->
<span>{{showFullName()}}</span>
</div>
<script>
Vue.config.keyCodes.a = 13;
new Vue({
el: '#root',
data:{
firstName: '张',
secondName:'三',
},
methods: {
showFullName() {//作为方法使用 可以作为事件回调使用
//但是不想让其作为事件的回调-自己调用
console.log('实例对象this',this)
return this.firstName+'-'+this.secondName
}
},
});
</script>
关于这部分双向绑定其依据来源于数据代理,实例上的data数据等于_data里面的数据,之后数据代理将vue实例上的对象和_date上的对象进行绑定,操作实例上的对象等于操作_data等于操作date中的数据。对于页面进行变换。
当我们改变data中的数据的时候,模板上的数据不是该数据,但是是数据的组合。数据改变,就会重新解析,方法也会重新调用。拿到最新的值。
只要vue里面的data数据发生改变vue会重新解析模板。才会知道模板里面的哪些数据进行了改变,然后对页面进行更新。
计算属性
对于vue:认为data里面的数据就是属性。左边属性名 右边属性值
data:{
firstName: '张',
secondName:'三',
},
你使用插值语法:就会出现你设置的属性方法出错
计算属性:就是使用已经存在的属性,重新计算输出新的属性 所放的配置项在computed
//当有人读取fullName时,get就会被调用,返回值就是fullName的值
测试get函数 --当鼠标点击的时候就被调用
computed:{
fullName:{//计算过程可能比较复杂需要配置成对象
get(){//当有人读取fullName时。get就会被调用,返回值就是fullName的值
console.log('被调用了')
return '788788s'
}
}
}
那么如何读取fullname ,也就是fullname在哪------在vue实例对象上
_date中的数据是来自vue中的date中属性,但是没有计算属性中的值
多次读取计算属性的值是从缓存中读取
get什么时候调用:
1、初次读取fullName会被调用---存在缓存
2、所依赖的数据发生变化时(也就是用到的数据firstName+secondName)也就是姓,名发生改变重新调用
但是对于methods而言,没有任何缓存而言。调用了就执行--执行多次
但是计算属性,存在缓存
计算属性下面的fullname是对象,但是get函数不是对象,读取的是返回值,而不是函数
实例对象上面date里面的属性、还有methods上的函数,但是计算属性中的get不是函数
自动找到get函数得到返回值,放置在vm上,属性的名称是该函数名称
相对的有get就有set。fullname是我们计算出来的新属性,只写get就只是考虑
了fullname被读取的时候的情形,但是没有考虑到fullname被修改
vm.fullName="被修改"
当计算属性被修改的时候,set被调用,收到的值是被修改的值
computed:{
fullName:{//计算过程可能比较复杂需要配置成对象
get(){//当有人读取fullName时。get就会被调用,返回值就是fullName的值
//console.log(this)//this时=是vm
// console.log('a')
return this.firstName+'-'+this.secondName
},
set(value){//fullName被修改 然后执行 value修改后的值
console.log('set',value)
}
}
执行:vm.fullName="dsd" 其中fullName被修改 对应的set函数得调用做了一个输出,但是没有修改姓,和名 所以data中的数据没有变
所以需要依靠set中的value修改data中的数据。传入的是姓-名。进行拆分传入
方法:将字符串按照-拆分成数组。数组的第0项是姓,第1项是名.
computed:{//计算属性--从属性中添加继续添加
fullName:{//计算过程可能比较复杂需要配置成对象
get(){//当有人读取fullName时
//get就会被调用,返回值就是fullName的值
console.log('被调用了');
console.log(this);//指向实例
return this.firstName+'-'+this.secondName;
},
set(value){//当该函数名称被修改的时候,就会调用set函数。也就是写的时候
console.log(value);
const arr=value.split('-');//按照指定字符将字符串拆分成数组
//最终修改实例对象中的date数据
this.firstName=arr[0];
this.secondName=arr[1];
}
},
所以fullname没有真正的值,都是计算出来的,需要改变-改变其组成参数.但是不能将fullname里面的set get写成箭头函数,就会变成this指向window。set和get是vue管理的函数,被vue管理的函数不可以写成箭头函数
计算属性的定义:要用的属性不存在,需要通过已有的属性计算出来
原理:底层借助了还是Object.defineproperty方法提供的getter和setter
get函数什么时候执行:
初次读取的时候执行一次
当所依赖的数据发生改变的时候会被再次调用
优点:当与methods实现相比,内部有缓存机制(复用),效率更高,调试更便捷
应用:
计算属性在vm实例上,直接读取使用就可以(就是使用{{fullname}})
如果计算属性需要被修改,必须写set函数去相应修改,且set中要引起计算时依赖的数据发生变化.就是将属性也要改变形成联动效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="js/vue.js"></script>
</head>
<body>
<!-- 准备容器 -->
<div id='root'>
姓:<input type="text" v-model:value=firstName>
<br>
名:<input type="text" v-model:value=secondName>
<br>
<span>姓名:</span>
<!-- <span>{{firstName+'-'+secondName}}</span> -->
<!-- slice直接写会让其变的长 太麻烦 不报错 -->
<!-- 截取前3位 -->
<h3>插值语法</h3>
<span>{{firstName.slice(0,3)}}-{{secondName}}</span>
<h3>methods方法</h3>
<span>{{showFullName()}}</span>
<h3>计算属性-有缓存</h3>
<span>{{fullName}}</span>
<span>{{fullName}}</span>
</div>
<script>
const vm=new Vue({
el: '#root',
data:{//属性
firstName: '张',
secondName:'三',
},
methods: {
showInfo(e) {
console.log('s')
console.log(e.target.value)
},
showFullName() {//作为方法使用 可以作为事件回调使用
//但是不想让其作为事件的回调-自己调用
// console.log('实例对象this',this)
return this.firstName+'-'+this.secondName
}
},
computed:{//计算属性--从属性中添加继续添加
fullName:{//计算过程可能比较复杂需要配置成对象
get(){//当有人读取fullName时
//get就会被调用,返回值就是fullName的值
console.log('被调用了');
console.log(this);//指向实例
return this.firstName+'-'+this.secondName;
},
set(value){//当该函数名称被修改的时候,就会调用set函数。也就是写的时候
console.log(value);
const arr=value.split('-');//按照指定字符将字符串拆分成数组
//最终修改实例对象中的date数据
this.firstName=arr[0];
this.secondName=arr[1];
}
},
}
});
</script>
</body>
</html>