2020-10-19

Vue基础(2)

上次说到了vue的一些基本语法,包括数据的单向/双向绑定,这次针对样式的绑定、内置指令、事件相关问题已经自动收集表单数据做一些总结;

1. 样式绑定

我们在搭建页面时,一个常见的需求就是给页面元素添加样式,常用的两种方式就是使用类的绑定style内联样式绑定。在vue中,我们也将针对这两种绑定方式来聊聊在vue项目中如何给元素添加样式。

  • 类的绑定
<style>
	.classA{
		background-color:skyblue
	}
	.classB{
		font-size:50px
	}
	.classC{
		font-weight:700
	}
</style>

<div id="root">
<!-- 1. 由传入的数据决定,你也不知道是哪个类生效 -->
	<p :class="myClass">我是一个p标签</p>
<!-- 2. 知道有哪几个类,但是不知道哪个生效-->
<!-- 以对象的形式出现,属性名后的属性值是布尔值,为true就生效 -->
	<p :class="{classA:isA, classB:isB}">我是一个p标签</p>
<!-- 3. 多个类都生效,以数组的形式将几个类展示出来 -->
	<p :class="['classA','classB','classC']">我是一个p标签</p>	
</div>

<script>
	let vm = new Vue({
		el:"#root",
		data:{
			myClass:"classA",
			isA:false,
			isB:true
		}
	})
</script>
  • style的绑定
<div id="root"> 
    <!-- style的绑定,引号中间使用对象写法,属性名改成小驼峰-->
    <p :style="{fontSize:mySize,color:myColor}">我是一个p标签</p>
</div>

<script>
	let vm = new Vue({
        el:"#root",
        data:{
            myColor:"red",
            mySize:"80px"
        }
    })
</script>

注意:
由上面两个示例可以看出,当模板中的数据一旦使用动态数据绑定的,那么属性后面的" "就不再是字符串标识了,而是js的代码区域。

2. 内置指令

之前在介绍数据绑定时,有使用过三个内置指令v-bind、v-model和v-on
这里再介绍几个有关条件渲染和列表渲染的指令

1)条件渲染

v-if / v-else & v-show 指令

<div id="root">
    <p v-if="isOk">成功</p>
    <p v-else>失败</p>
    <br />
    <p v-show="isOk">success</p>
    <p v-show="!isOk">fail</p>
</div>
<script>
	let vm = new Vue({
        el:"#root",
        data:{
            isOk:true
        }
    })
</script>

上面的例子输出之后,可以看到,两个指令都可以根据data中的数据,渲染出符合条件的内容。但是,这两种方式还是有一定区别的。
在控制台中,我们发现:
在这里插入图片描述
使用v-if的元素会将符合条件的元素添加到DOM树中,并将其渲染到页面上;而使用v-show的元素,不管是否符合条件,在DOM树上都可以看到,只不过对于不符合条件的元素,将其隐藏掉了。

那么问题来了,在这两种指令的选择上,究竟该如何选择呢?
小结:
这两种都可以完成条件渲染的功能,但是场合不同,使用这两种的效率不一样,

当我们切换的频率很高,就选择使用v-show;切换不频繁的情况,就使用v-if/v-else;

  1. 使用v-if时,符合条件的才渲染,不符合条件的DOM节点就直接删除掉,内存中也不存在。(节省内存)

  2. 但是使用v-show,所有DOM节点都存在在DOM树上,只有符合条件的才显示,不符合条件的仅仅是使用样式隐藏起来,也就是说内存当中还有。

  3. 使用v-if的时候,DOM节点不一定能获取到;但是使用v-show时,DOM节点一定能获取到,只不过获取到的节点可能样式是display:none罢了。

2)列表渲染

v-for指令

<div id="root">
	<ul>
	<!-- 使用v-for指令时,必须要添加一个key属性,用来唯一指定每个渲染出来的li -->
		<li v-for="(item,index) in persons" :key="item.id">
			{{item.name}} --- {{item.age}}
		</li>
	</ul>
	<!-- 添加一个修改li内容的click方法 -->
	<button @click="changeLi">修改第一个li中的name值</button>
</div>

<script>
	let vm = new Vue({
		el:"#root",
		data:{
			persons:[
				{id:1,name:"tony",age:25},
				{id:2,name:"tom",age:15},
				{id:3,name:"jenna",age:29},
				{id:4,name:"lucas",age:32},
			]
		},
		methods:{
			changeLi(){
				// 第一种方法:
				this.persons[0].name = "Andy";

				// 第二种方法:
				this.persons.splice(0,1,{id:1,name:"Andy",age:25})

				// 第三种方法:不可行
				this.persons[0] = {id:1,name:"Andy",age:25}
			}
		}
		
	})
</script>

这里引出一个很重要的问题:vue是如何处理响应式数据的?
vue在处理对象和数组时是不同的:

  1. 对于对象来说,data当中所有的属性,都被添加了getter和setter方法,因此data中的数据都是响应式的,修改数据,页面也会跟着改变。
  2. 但是,对于数组来说,数组的下标不属于属性,因此没有添加getter和setter方法,它们不是响应式的。通过数组下标(示例中的第三种方法)去修改数据,数据会改变,但是页面不会跟着改变。
  3. vue在对数组进行响应式的时候,不像对象一样,直接给属性添加getter和setter方法,而是重写了数组部分的方法,在原来原生方法的基础上添加了修改页面的功能。

3. 事件相关

  • 事件对象event的问题

当我们给某个元素添加了事件是,不传参数时,事件处理函数内部自动传入一个event事件对象。

<div id="root">
	<button @click="test">test按钮</button>
</div>

<script>
	let vm = new Vue({
        methods:{
            test(event){
                console.log(event)
            }
        }
    })
</script>

一旦你传递了参数,那么这个参数就会将event事件对象覆盖,我们就没办法打印得到事件对象了。这时,就要用到$event来获取事件对象

<div id="root">
<!-- 如果还想要事件对象,那么参数就使用$event,就可以接收到event对象了,顺序无所谓 -->
	<button @click="test("zs",$event)">test按钮</button>
</div>

<script>
	let vm = new Vue({
        methods:{
            test(name,event){
                console.log(name,event)
            }
        }
    })
</script>
  • 阻止事件冒泡 & 取消浏览器的默认行为
    在原生的js中,我们通常使用event.stopPropagation()event.preventDefault()来实现阻止事件冒泡和取消浏览器的默认行为。但是,vue使用了一种更为简单的方式实现这一需要。
<div @click="outer">
    <!-- 使用事件描述符 -->
    <div @click.stop = "inner"></div>
    
    <!-- 阻止浏览器的默认行为,使用事件描述符 -->
    <a href="www.baidu.com" @click.prevent="cancelDef">点我跳转</a>
</div>

<script>
	methods:{
        outer(){
            console.log("这是outer")
        },
        inner(event){
        //    event.stopPropagation()
        	console.log("这是inner")
        },
        cancelDef(event){
        //    event.preventDefault();
        }
    }
</script>
  • 键盘事件
    不再需要查找按键的keyCode值了
<!-- 键盘事件一般都用在表单类元素或者document身上 -->
<input type="text" @keyup.enter="keyEnter" />

<script>
	methods:{
        keyEnter(event){
           // if(event.keyCode === 13){}
        }
    }
</script>

4. 自动收集表单数据

<div id="root">
 <!-- 收集数据的时候默认收集的都是表单类元素的value值 -->
	<form>
		<label>
        	用户名:<input v-model="userName" type="text" />
        </label>
        <br>
        <label>
        	密码:<input v-model="password" type="text" />
        </label>
        <br>
 <!-- 当input是单选输入框的时候,value值要自己指定,收集到的是选中的单选框的value值 -->
 <!-- 如果没有给value属性,那么获取的value值就是null -->
        <label>
            性别:男<input type="radio" name="sex" v-model="gender" value="male"><input type="radio" name="sex" v-model="gender" value="female">
         </label>
         <br>
         <label>
             爱好:
             篮球<input type="checkbox" name="hobby" value="basketball" v-model="hobbys">
             乒乓球<input type="checkbox" name="hobby" value="ping-pang" v-model="hobbys">
             足球<input type="checkbox" name="hobby" value="football" v-model="hobbys">
         </label>
         <br><br><br>
         <label>
             城市:
  <!-- select身上的v-model收集的是选中的option的value值 -->
             <select v-model="cityId">
             	<option value="0">Peking</option>
                <option value="1">Shanghai</option>
                <option value="2">Guangdong</option>
             </select>
          </label>
	</form>
</div>

<script>
	let vm = new Vue({
		el:"#root",
		data(){
			return{
				userName: "",
                password: "",
                gender: "male",
                hobbys: ['ping-pang'],
                cityId: 1
			}
		}
	})
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值