目录
一、事件绑定
1、单向绑定(响应式)
改变数据源中的数据,页面中也会改变,但页面中改变却不能改变数据源中的数据。如果要做到后半句的功能,就要自己绑一个input事件,获取到页面中改变后的数据,然后在方法中去改变数据源的数据。
2、双向绑定
v-model:一般绑在input上,但也可以绑在其他标签上。属性值改变,交互控件的value改变,反之用户交互改变了value,然后也会让属性值改变(监听用户交互)
<div id="app">
<p>{{val}}</p>
<input type="text" :value="val" @input="change"><br>
<p>{{msg}}</p>
<input type="text" v-model="msg">
</div>
<script>
const VueApp = {
data(){
return {
val:'123456',
msg:'nireu'
}
},
methods:{
change(e){
console.log(e.target.value)
this.val=e.target.value
}
}
}
Vue.createApp(VueApp).mount('#app')
</script>
二、条件渲染
v-if = '变量',变量值为true则元素显示,false隐藏。v-show也能实现同样的功能,使用方法:v-show = '变量',变量值为true则元素显示,false隐藏。
两者区别:v-if隐藏是直接将节点在dom树中移除,show是标签元素display:none,依旧占据内存。两者没有好坏之分,有各自的使用场景,需要经常切换的用show,很少切换的用if。
v-if、v-else:两者间不能有其他语句。v-if等号后面是表达式(表达式要进行布尔判定),v-else后面不需要写什么。
<div id="app">
<!-- 隐藏,取值false -->
<!-- <div v-if="flag">盒子1</div> -->
<!-- 隐藏,判定为false -->
<!-- <div v-if='age>30'>盒子1</div> -->
<div v-if="false">盒子1</div>
<div v-show="true">盒子2</div>
<p v-if="age>=18">成年人</p>
<p v-else>未成年</p>
</div>
<script>
const VueApp = {
data(){
return {
flag:false,
age:21
}
}
}
Vue.createApp(VueApp).mount('#app')
</script>
三、循环渲染
v-for指令:遍历数组数组,将数组中的每一个元素渲染在页面上。
<div id="app">
<p v-for="el in arr">{{el}}</p>
<!--
<p>{{arr[0]}}</p>
<p>{{arr[1]}}</p>
<p>{{arr[2]}}</p>
<p>{{arr[3]}}</p>
-->
<div v-for="el in arr2">
<!-- v-if先运行,此时还没有el2 -->
<!-- <p v-for="(el2,i) in el" v-if="typeof el2 === 'number'">{{el2}}</p> -->
<p v-for="(el2,i) in el">{{el2}}</p>
</div>
</div>
<script>
const VueApp = {
data(){
return {
arr:['hello','java','typescript','vue'],
arr2:[['red','green','blue'],['Tom','Peter','Amy'],[1,2,3]]
}
}
}
Vue.createApp(VueApp).mount('#app')
</script>
v-for和v-if写在一个标签中时,在vue2.0和vue3.0中都有各自的优先级,3.0版本运行时,v-if先运行,v-for后运行,2.0时反过来的。并且官方不建议这样写,可以分开写嵌套。
<div id="app">
<button @click="fn">加载更多</button>
<div v-for="el in arr2" :key="el.id">
<input type="checkbox" name="hu">{{el.text}}
</div>
</div>
<script>
const VueApp = {
data(){
return {
arr2:[
{
id:101,
text:'九曲湖'
},
{
id:102,
text:'西湖'
},
{
id:103,
text:'百丈漈'
}
]
}
},
methods:{
fn(){
this.arr2.unshift({
id:103,
text:'百丈漈'+parseInt(Math.random()*100)
})
}
}
}
Vue.createApp(VueApp).mount('#app')
</script>
运行上述示例代码,会发现当我们勾选了九曲湖后去点击加载更多,勾选的就变成百丈漈87了。这是因为vue框架在循环渲染时,如果新添加了数据,它不会重新创建对应数据数量的节点,而是把之前的节点复用,再在后面添加新的节点,然后再把数组中的元素一一对到节点中。当我们在前面添加节点时,原本被勾选的这个节点复用过来,依旧是勾选状态,但对应数据不一样了。
key的意义:为解决上述问题,在v-for所在的元素中添加一个':key=“”',里面写唯一标识的数据,后面渲染时就会认准这个标识数据。
四、计算样式
computed:会把函数调用的结果缓存起来 当计算属性的函数中使用到的数据源改变了 就会重新执行计算属性。
<div id="app">
<p>方法-----{{fm()}}</p>
<p>计算样式-{{age}}</p>
<p>{{count}}</p>
<button @click="add">增加</button>
</div>
<script>
const VueApp = {
data(){
return {
birth:'2000-07-21',
count:10
}
},
methods:{
fm(){
console.log('运行了methods中的函数')
return new Date().getFullYear()-new Date(this.birth).getFullYear()
},
add(){
this.count++
}
},
computed:{
age(){
console.log('运行了computed中的函数')
return new Date().getFullYear()-new Date(this.birth).getFullYear()
}
}
}
Vue.createApp(VueApp).mount('#app')
</script>
从上述示例的运行结果可以看出,第一次页面加载后methods中的方法和computed中的函数都运行了,不一样的在于当我们在页面中手动改变了其他使用到的数据源中的数据时,整个模板是重新加载了一遍的,然后方法就又执行了一次,但计算样式中的函数却没有执行。这就是两者的区别,计算样式会在缓存中查看,如果计算属性的函数中使用到的数据源改变了 就会重新执行,没有改变就直接使用缓存中的数据。