方法和事件绑定
方法
方法的写法: 在methodszhong写方法,供事件或者别的方法内部调用
不建议用箭头函数
function fn4 () {console.log("fn4")}
var fn5=()=>{console.log("fn5")}
var fn6=function(){console.log("fn6")}
new Vue({
el:"#app",
data:{},
methods:{
fn1(){console.log("fn1")},
fn2:function(){console.log("fn2")},
fn3:()=>{console.log("fn3")},
fn4,
fn5,
fn6
}
})
事件绑定
标准写法:<标签 v-on:click="fn1()">点击事件1</标签>
语法糖:<button @click="fn2">点击事件2
事件修饰符
- .stop 阻止冒泡,阻止从当前元素经过的所有冒泡行为
- .prevent 阻止默认事件
- .capture 添加事件侦听器时让事件在捕获阶段触发
- .self 其他元素的事件触发时 事件链经过它,无论是捕获还是冒泡阶段都不会触发它的事件,只有它自己是精准对象才会触发事件, 虽然它自己不会被别人影响,但是它自己的事件触发的时候还是会生成事件链经过其他元素,并不阻止继续冒泡到其他元素
- .once 事件只触发一次,触发完之后,事件就解绑
- 多修饰符一起使用:连点
列:
<style>
.s1 {
width: 200px;
height: 200px;
background-color: aqua;
}
.s2 {
width: 150px;
height: 150px;
background-color: antiquewhite;
}
.s3 {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
<body>
<div id="box">
<div @click="fn1" class="s1">1
<div @click="fn2" class="s2">2
<!-- 阻止冒泡 .stop -->
<div @click.stop="fn3" class="s3">3</div>
</div>
</div>
<!-- 阻止默认事件 -->
<a @click.prevent="fn4" href="https://www.baidu.com/">{{msg}}</a>
<!-- 绑定多个事件 -->
<span @click="fn5">1111</span>
</div>
<script>
new Vue({
el: "#box",
data: {
msg: "hello"
},
methods: {
fn1() {
console.log(1111);
},
fn2() {
console.log(2222);
},
fn3() {
console.log(33333);
},
fn4() {
this.msg = "6666666"
},
fn5() {
this.fn51();
this.fn52();
},
fn51() {
},
fn52() {
}
},
})
</script>
</body>
样式绑定
对class进行绑定
对象语法,v-bind:class 指令也可以与普通的 class 属性共存
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
<div v-bind:class="classObject"></div>
对应js 中的data:
data: {
isActive: true,
hasError: false,
classObject: {
active: true,
'text-danger': false
}
}
数组语法,这样写将始终添加 errorClass,但是只有在 isActive 是真值时才添加 activeClass
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
列:
<style>
.rijianmoshi {
width: 400px;
height: 400px;
background-color: skyblue;
}
.yejianmoshi {
width: 400px;
height: 400px;
background-color: black;
}
</style>
<body>
<div id="box">
<button @click="fn">{{msg}}</button>
<div :class="module">
</div>
</div>
<script>
new Vue({
el: "#box",
data: {
msg: "日间模式",
flage: true,
module: "rijianmoshi"
},
methods: {
fn() {
this.flage = !this.flage
if (this.flage) {
this.msg = "日间模式",
this.module = "rijianmoshi"
} else {
this.msg = "夜间模式",
this.module = "yejianmoshi"
}
}
},
})
</script>
</body>
对style进行绑定
对象语法
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
<div v-bind:style="styleObject"></div>
对应js 中的data:
data: {
activeColor: 'red',
fontSize: 30,
red1:"red",
styleObject: {
color: 'red',
fontSize: '13px'
}
}
数组语法,可以将多个样式对象应用到同一个元素上
<div v-bind:style="[baseStyles, overridingStyles,{color:red1}]"></div>
列:
<style>
.a {
width: 300px;
height: 300px;
background-color: aqua;
}
.b {
width: 250px;
height: 250px;
background-color: aliceblue;
}
.c {
width: 200px;
height: 200px;
background-color: aquamarine;
}
</style>
<body>
<div id="box">
<div :class="a">
<div :class="{b:isb}">
<div :class="['a',c ]">
</div>
</div>
</div>
<div :style="{color:r}">
{{msg}}
</div>
<div :style="stylebox">
</div>
</div>
<script>
new Vue({
el: "#box",
data: {
a: "a",
isb: true,
c: "c",
r: "red",
msg: "hello",
stylebox: {
width: "200px",
height: "150px",
background: "blue"
}
}
})
</script>
</body>
条件渲染
v-if:移除元素来切换模块 具有更高的渲染消耗 因此常常用在不常切换的业务,使用的变量为true就显示,false就隐藏
v-show:通过css的display:none来隐藏元素,具有更高的内存消耗,用于经常切换的业务,使用的变量为true就显示,false就隐藏
<body>
<div id="app">
<button @click="change1">开关</button>
<div v-if="flag">hello</div>
<div v-show="flag">hello2</div>
<div v-show="'flag'+100">hello2</div>
</div>
<script>
new Vue({
el:"#app",
data:{
n:0,
n2:true,
flag:true
},
methods:{
change1(){
this.flag=!this.flag
}
}
})
//v-if -移除元素来切换模块 具有更高的渲染消耗 因为常常用在不常切换的业务
//v-show -css的隐藏元素(display:none)切换模块 -具有更高的内存消耗 经常切换的业务
</script>
</body>
循环渲染
写法:v-for="(item,index) in arr2",item是数组中的元素,index是元素下标
注:
1.v-for和v-if放在了同一个标签中 没有先后顺序的要求,但是先执行for
渲染过程为:对arr每一项先做map循环判断v-if给出的条件,再做一遍for 循环渲染
这样引起的问题是:arr 数组新增一项数据时,会对每一项再做一遍v-if 循环,然后for 循环渲染
2.解决方案把for弄到最外层(面试)
如果if和for套在一层,数据容器发生变化时,if会重新判断一遍 嵌套的写法 数据容器变化时 if只判断新增的数据 这样当arr 数组某一项数据发生变化时,只对新增的数据进行v-if 判断,节约渲染效率
这样又会产生新的问题:外层for的div会也创建一个挂载到DOM中 解决方案:wx采用的是block元素 vue呢? template 其实就是dom操作中的fragment
"冰"元素:template
<body>
<div id="app">
<div v-for="el in arr3">
<h1>{{el.name}}</h1>
<template v-if="el.age>10">
<div v-for="el in el.titles">{{el}}</div>
</template>
<!-- <div v-for="el in el.titles" v-if="el.age>10">{{el}}</div> -->
<!-- <div id="" class=""></div> -->
</div>
</div>
<script>
var vm=new Vue({
el:"#app",
data:{
arr3: [{
name: "css",
age:37,
titles: ["宽度", "高度", "原角度","颜色"]
}, {
name: "js",
age:20,
titles: ["变量"]
},{
name: "html",
age:90,
titles: ["标签"]
}]
}
})
//vue2.0 中v-if v-for 写到一个元素 v-for的优先级更高
//解决方案:1.写成嵌套关系 2."冰"元素:template
//vue3.0 不能写到一起 不然报错
</script>
循环渲染中key的原理
意义:
1.让数据跟真实的dom一一关联 使之不发生渲染混乱的情况
2.提高绘制渲染效率
列:
<div id="app">
<h1>请选择你最喜欢的5件商品(免费赠送给你)</h1>
<div v-for="(elx) in arr" :key="el.id">
<input type="checkbox" name="goods" :value="el.id">
<b>{{el.title}}</b>
</div>
<button @click="addmore">加载更多</button>
</div>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
id:5,
arr:[{id:1,title:"包包1",price:123},
{id:2,title:"鞋子1",price:123},
{id:3,title:"衣服1",price:123},
{id:4,title:"商品1",price:123}]
},
methods:{
addmore(){
let obj={id:this.id++,title:"商品"+this.id,price:123}
// this.arr.push(obj)
this.arr.unshift(obj)
}
}
})
解析:当在数组头部添加元素时,如果不加:key标记,则勾选的内容会被挤下去而勾选的位置不变,因此加入key后,会将数据跟真实的dom一一关联 使之不发生渲染混乱的情况
不加:key的情况: