Vue2---(方法和事件绑定,样式绑定,条件渲染,循环渲染)

68 阅读3分钟

方法和事件绑定

方法

方法的写法: 在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>

image.png

image.png

对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>

image.png

条件渲染

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>

image.png

image.png

循环渲染

写法: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>

image.png

循环渲染中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)
					}
				}
			})

image.png 解析:当在数组头部添加元素时,如果不加:key标记,则勾选的内容会被挤下去而勾选的位置不变,因此加入key后,会将数据跟真实的dom一一关联 使之不发生渲染混乱的情况

不加:key的情况:

image.png