02vue指令-1

vue内部指令

指令 说明 简写
mustache 大括号语法 {
v-if 条件判断,根据ture/false渲染元素
v-else 同上
v-else-if 同上
v-show 样式显示
v-for 遍历
v-text 插入覆盖文字内容
v-html 转义超链接
v-on 事件监听 @
v-model 双向绑定;复杂
v-bind 动态绑定;复杂
v-pre 显示原始字符串,不转义
v-once 执行一次
v-cloak 披风,用于遮盖

1、Mustache语法

<div id="app">
    <h2>{{message}}</h2>
    <h2>{{message}},啧啧啧</h2>

    <!-- Mustache的语法不仅可以直接写变量,还可以写简单表达式 -->
    <h2>{{firstName + lastName}}</h2>
    <h2>{{firstName + " " + lastName}}</h2>
    <h2>{{firstName}}{{lastName}}</h2>
    <h2>{{count * 2}}</h2>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        message:"你好啊",
        firstName:"skt t1",
        lastName:"faker",
        count:100
      }
    })

  </script>

2、v-once

​ v-once表示该dom元素只渲染一次,之后数据改变,不会再次渲染。

 <div id="app">
    <h2>{{message}}</h2>
    <!-- 只会渲染一次,数据改变不会再次渲染 -->
    <h2 v-once>{{message}}</h2>

  </div>

3. v-html

在某些时候我们不希望直接输出[百度一下](http://www.baidu.com)这样的字符串,而输出被html自己转化的超链接。此时可以使用v-html。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="app">
		    <h2>不使用v-html</h2>
		    <h2>{{ url }}</h2>
		    <h2>使用v-html,直接插入html</h2>
		    <h2 v-html="url"></h2>
		  </div>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<script>
			const app = new Vue({
				el:"#app",
				data:{
					url:"<a href='http://www.baidu.com'>百度一下</a>"
				}
			})
		</script>
	</body>
</html>

页面如下

4. v-text

v-text会覆盖dom元素中的数据,相当于js的innerHTML方法。

<body>
  <div id="app">
    <h2>不使用v-text</h2>
    <h2>{{message}},啧啧啧</h2>
    <h2>使用v-text,以文本形式显示,会覆盖</h2>
    <h2 v-text="message">,啧啧啧</h2>

  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        message:"你好啊"
      }
    })
  </script>
</body>

结果

5. v-pre

有时候我们期望直接输出{{message}}这样的字符串,而不是被{{}}语法转化的message的变量值,此时我们可以使用v-pre标签。

<body>
  <div id="app">
    <h2>不使用v-pre</h2>
    <h2>{{message}}</h2>
    <h2>使用v-pre,不会解析</h2>
    <h2 v-pre>{{message}}</h2>

  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        message:"你好啊"
      }
    })
  </script>
</body>

​ 结果如图,使用v-pre修饰的dom会直接输出字符串。

6、v-cloak 披风

有时候因为加载延时问题,例如卡掉了,数据没有及时刷新,就造成了页面显示从{{message}}到message变量“你好啊”的变化,这样闪动的变化,会造成用户体验不好。此时需要使用到v-cloak的这个标签。在vue解析之前,div属性中有v-cloak这个标签,在vue解析完成之后,v-cloak标签被移除。简单,类似div开始有一个css属性display:none;,加载完成之后,css属性变成display:block,元素显示出来。

<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <title>v-cloak指令的使用</title>
  <style>
   [v-cloak]{
      display: none;
    }
  </style>
</head>

<body>
  <div id="app" v-cloak>
    <h2>{{message}}</h2>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    //在vue解析前,div中有一个属性cloak
    //在vue解析之后,div中没有一个属性v-cloak
    setTimeout(() => {
      const app = new Vue({
        el: "#app",
        data: {
          message: "你好啊"
        }
      })
    }, 1000);
  </script>
</body>

</html>

这里通过延时1秒模拟加载卡住的状态,结果一开始不显示message的值,div元素中有v-cloak的属性,1秒后显示message变量的值,div中的v-cloak元素被移除。

7、v-for

对于一个数组或者字典元素可以用v-for遍历元素

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="app">
			<h3>直接显示值</h3>
			<ul>
				<li v-for="item in items">
					{{item}}
				</li>
			</ul>
			<h3>显示index和值</h3>
			<ul>
				<li v-for="(index,item) in items">
					{{item}} => {{index}}
				</li>
			</ul>
			<h3>显示index、键、值</h3>
			<ul>
				<li v-for="(value, key, index) in object">
					{{ index }} => {{ key }} => {{ value }}
				</li>
			</ul>
		</div>

		<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
		<script>
			const app = new Vue({
				el: "#app",
				data: {
					items: ['葫', '芦', '娃', '救', '爷爷'],
					object: {
						firstName: '葫芦娃',
						lastName: '爷爷',
					}
				}
			})
		</script>
		</script>
	</body>
</html>

结果:

8、v-if、 v-else-if、v-else、v-show

v-if用于条件判断,判断Dom元素是否显示。

<div v-if="isLogin">你好</div>

<div v-else>请登录后操作</div>

<div v-show="isLogin">你好</div>

<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else-if="type === 'C'">C</div>
<div v-else>Not A/B/C</div>

v-if与v-show的区别

v-show = false 相对于 display : none

  • v-if: 在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建,开销较高,在运行时条件很少改变时使用。
  • v-show:调整css dispaly属性,开销较小,在常频繁地切换时使用。

8.1、v-if的demo

在登录网站是经常可以选择使用账户名或者邮箱登录的切换按钮。要求点击按钮切换登录方式。

实现输入框的复用

<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <span v-if="isUser">
      <label for="username">用户账号</label>
      <input type="text" id="username" placeholder="请输入用户名" >
    </span>
    <span v-else="isUser">
        <label for="email">用户邮箱</label>
        <input type="text" id="email" placeholder="请输入用户邮箱" >
    </span>
    <button @click="isUser=!isUser">切换类型</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        isUser:true
      }
    })
  </script>
</body>
</html>

这里需要了解一下vue底层操作,此时input输入框值被复用了。

  1. vue在进行DOM渲染是,处于性能考虑,会复用已经存在的元素,而不是每次都创建新的DOM元素。

  2. 在上面demo中,Vue内部发现原来的input元素不再使用,所以直接将其映射对应虚拟DOM,用来复用。

  3. 如果不希望出现类似复用问题,可以给对应的dom元素加上key值,并保证key不同。

    <input type="text" id="username" placeholder="请输入用户名" key="username">
    <input type="text" id="email" placeholder="请输入用户邮箱" key="email">
    
v-if 在首次渲染的时候,如果条件为假,什么也不操作,页面当作没有这些元素。当条件为真的时候,开始局部编译,动态的向DOM元素里面添加元素。当条件从真变为假的时候,开始局部编译,卸载这些元素,也就是删除。
v-show 不管条件是真还是假,第一次渲染的时候都会编译出来,也就是标签都会添加到DOM中。之后切换的时候,通过display: none;样式来显示隐藏元素。可以说只是改变css的样式,几乎不会影响什么性能。

9、v-bind (:)简写(语法糖)【动态绑定属性】https://cn.vuejs.org/v2/api/#v-bind

用于处理html标签的动态属性,即动态赋值。

常规写法

// html
<img v-bind:src="imgSrc"  width="200px">

// js
data: {    
    imgSrc:'http://liangxinghua.com/uploads/image/20180709/1531106987.png'
}
说明
某些时候我们并不想将变量放在标签内容中,像这样<h2>{{message}}</h2>是将变量h2标签括起来,类似js的innerHTML。但是我们期望将变量imgURL写在如下位置,想这样<img src="imgURL" alt="">导入图片是希望动态获取图片的链接,此时的imgURL并非变量而是字符串imgURL,如果要将其生效为变量,需要使用到一个标签v-bind:,像这样<img v-bind:src="imgURL" alt="">,而且这里也不能使用Mustache语法,类似<img v-bind:src="{{imgURL}}" alt="">,这也是错误的。
<!-- 正确的做法使用v-bind指令 -->
    <img v-bind:src="imgURL" alt="">
    <a v-bind:href="aHerf"></a>
    <!-- 语法糖写法 -->
    <img :src="imgURL" alt="">
    <a :href="aHerf"></a>

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        imgURL:"https://cn.bing.com/th?id=OIP.NaSKiHPRcquisK2EehUI3gHaE8&pid=Api&rs=1",
        aHerf:"http://www.baidu.com"
      }
    })
  </script>

此时vue对象中定义的imgURL变量和aHerf变量可以动态的绑定到img标签的src属性和a标签的href属性。v-bind:由于用的很多,vue对他有一个语法糖的优化写法也就是:

9.1 v-bind动态绑定class(对象语法)

有时候我们期望对Dom元素的节点的class进行动态绑定,选择此Dom是否有指定class属性。例如,给h2标签加上class="active",当Dom元素有此class时候,变红<style>.active{color:red;}</style>,在写一个按钮绑定事件,点击变黑色,再次点击变红色。
<body>
  <div id="app">
    <!-- <h2 class="active">{{message}}</h2>
    <h2 :class="active">{{message}}</h2> -->

    <!-- 动态绑定class对象用法  -->
    <!-- <h2 :class="{key1:value1,key2:value2}">{{message}}</h2>
    <h2 :class="{类名1:true,类名2:boolean}">{{message}}</h2> -->
    <h2 class="title" :class="{active:isActive}">{{message}}</h2>
    <h2 class="title" :class="getClasses()">{{message}}</h2>
    <button @click="change">点击变色</button>

  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        message:"你好啊",
        active:"active",
        isActive:true
      },
      methods: {
        change(){
          this.isActive = !this.isActive
        },
        getClasses(){
          return {active:this.isActive}
        }
      },
    })
  </script>
</body>

定义两个变量activeisActive,在Dom元素中使用:class={active:isActive},此时绑定的class='active',isActive为true,active显示,定义方法change()绑定在按钮上,点击按钮this.isActive = !this.isActive,控制Dom元素是否有class='active'的属性。

9.2 v-bind动态绑定class(数组语法)

<body>
  <div id="app">
    <!-- 加上单引号当成字符串 -->
    <h2 class="title" :class="['active','line']">{{message}}</h2>
    <!-- 不加会被当成变量 -->
    <h2 class="title" :class="[active,line]">{{message}}</h2>
    <h2 class="title" :class="getClasses()">{{message}}</h2>

  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        message:"你好啊",
        active:"aaaa",
        line:'bbbb'
      },
      methods: {

        getClasses(){
          return [this.active,this.line]
        }
      },
    })
  </script>
</body>
  1. 加上单引号的表示字符串
  2. 不加的会当成变量
  3. 可以直接使用方法返回数组对象
例子
<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <title>作业(v-for和v-bind的结合)</title>
  <style>
    .active{
      color:red;
    }
  </style>
</head>
<body>
  <div id="app">

    <ul>
      <li v-for="(item, index) in movies" :key="index" :class="{active:index===currentIndex}" @click="changeColor(index)" >{{index+"---"+item}}</li>
    </ul>

  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        currentIndex:0,
        movies:["海王","海贼王","火影忍者","复仇者联盟"]
      },
      methods: {
        changeColor(index){
          this.currentIndex = index
        }
      },
    })
  </script>
</body>
</html>

v-for时候的index索引,给每行绑定事件点击事件,点击当行是获取此行索引index并赋值给currentIndex,使用v-bind:绑定class,当index===currentIndexDom元素有active的class,颜色变红。

9.4 v-bind动态绑定style(对象语法)

<!-- <h2 :style="{key(属性名):value(属性值)}">{{message}}</h2> -->
<!-- 加单引号,当成字符串解析 -->
<h2 :style="{fontSize:'50px'}">{{message}}</h2>
<!-- 不加单引号,变量解析 -->
<h2 :style="{fontSize:fontSize}">{{message}}</h2>
<h2 :style="getStyle()">{{message}}</h2>

9.5 v-bind动态绑定style(数组语法)

<div id="app">
    <h2 :style="[baseStyle]">{{message}}</h2>
    <h2 :style="getStyle()">{{message}}</h2>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        message:"你好啊",
        baseStyle:{backgroundColor:'red'}
      },
      methods: {
        getStyle(){
          return [this.baseStyle]
        }
      },
    })
  </script>

类似绑定class,绑定style也是一样的。

10、v-on 简写@

详情:https://cn.vuejs.org/v2/api/#v-on

绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。

用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件

在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 $event property:v-on:click="handle('ok', $event)"

2.4.0 开始,v-on 同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的。

10.1、修饰符

  • .stop - 调用 event.stopPropagation()
  • .prevent - 调用 event.preventDefault()
  • .capture - 添加事件侦听器时使用 capture 模式。
  • .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
  • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
  • .native - 监听组件根元素的原生事件。
  • .once - 只触发一次回调。
  • .left - (2.2.0) 只当点击鼠标左键时触发。
  • .right - (2.2.0) 只当点击鼠标右键时触发。
  • .middle - (2.2.0) 只当点击鼠标中键时触发。
  • .passive - (2.3.0) 以 { passive: true } 模式添加侦听器
<body>
  <div id="app">
    <!--1. .stop的使用,btn的click事件不会传播,不会冒泡到上层,调用event.stopPropagation() -->
    <div @click="divClick">
        <button @click.stop="btnClick">按钮1</button>
    </div>
    <!-- 2. .prevent 调用event.preeventDefault阻止默认行为  -->
    <form action="www.baidu.com">
      <button type="submit" @click.prevent="submitClick">提交</button>
    </form>
    <!--3. 监听键盘的事件 -->
    <input type="text" @click.enter="keyup">

  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      methods:{
        btnClick(){
          console.log("点击button");
        },
        divClick(){
          console.log("点击div");
        },
        submitClcik(){
          console.log("提交被阻止了")
        },
        keyup(){
          console.log("keyup点击")
        }
      }
    })
  </script>
</body>

说明:

1 .stop的使用,btn的click事件不会传播,不会冒泡到上层,调用event.stopPropagation()。
2 .prevent 调用event.preeventDefault阻止默认行为。
3 .enter监听键盘事件

10.2 实例

一个简单的鼠标点击事件

<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <title>Document</title>
</head>
<body>
  <div id="app">
      <h2>{{count}}</h2>
      <!-- <button v-on:click="count++">加</button>
      <button v-on:click="count--">减</button> -->
      <button @click="increment">加</button>
      <button @click="decrement()">减</button>
  </div>
  <script>
    const app = new Vue({
      el:"#app",
      data:{
        count:0
      },
      methods: {
        increment(){
          this.count++
        },
        decrement(){
          this.count--
        }
      }
    })

  </script>
</body>
</html>

使用v-on:click给button绑定监听事件以及回调函数,@是v-on:的语法糖,也就是简写也可以使用@click。方法一般是需要写方法名加上(),在@click中可以省掉,如上面的<button @click="increment">加</button>

10.2、 v-on的参数传递

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <!-- 事件没传参 -->
    <button @click="btnClick">按钮1</button>
    <button @click="btnClick()">按钮2</button>
    <!-- 事件调用方法传参,写函数时候省略小括号,但是函数本身需要传递一个参数 -->
    <button @click="btnClick2(123)">按钮3</button>
    <button @click="btnClick2()">按钮4</button>
    <button @click="btnClick2">按钮5</button>
    <!-- 事件调用时候需要传入event还需要传入其他参数 -->
    <button @click="btnClick3($event,123)">按钮6</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el:"#app",
      methods:{
        btnClick(){
          console.log("点击XXX");
        },
        btnClick2(value){
          console.log(value+"----------");
        },
        btnClick3(event,value){
          console.log(event+"----------"+value);
        }
      }
    })
  </script>
</body>
</html>	

说明

  1. 事件没传参,可以省略()
  2. 事件调用方法传参了,写函数时候省略了小括号,但是函数本身是需要传递一个参数的,这个参数就是原生事件event参数传递进去
  3. 如果同时需要传入某个参数,同时需要event是,可以通过$event传入事件。

按钮4调用btnClick2(value){},此时undefined。按钮5调用时省略了(),会自动传入原生event事件,如果我们需要event对象还需要传入其他参数,可以使用$event对象。

posted @ 2020-07-09 01:51  slzhao  阅读(150)  评论(0编辑  收藏  举报