Vue.js -- 指令部分01

Vue.js

1. 指令

表达式的值除了可以出现内容中,也可以使用在其它位置,比如:属性。但是不能使用 {{}} 语法,而是需要 指令

v-指令名称 = 表达式 (加“ ”,但不是普通字符串)

v- 前缀代表vue ~ ~ ~

vue 中,指令是一个带有 v- 前缀的属性,与普通属性不一样的地方在于,指令的值是引号括起来的 表达式,不同的指令有不同的作用,vue 内置了一些常用的指令,后期我们还可以自定义属于自己的指令

  • 内容输出
  • 循环
  • 逻辑
  • 属性绑定
  • 事件
  • 其它

2. 内容输出

通过 {{}} 我们可以很方便的从模板中输出数据,但是这种方式会有一个问题,当页面加载渲染比较慢的时候,页面中会出现 {{}}vue 提供了几个指令来解决这个问题

指令中表达式 不需要使用 {{}}

2.1 v-text

v-text:更新元素的文本内容textContent。

<p v-text="title"></p>
<!-- 和下面的一样 -->
<p>{{title}}</p>

<!-- {{}}与v-text区别示例  {{}}可以更新部分内容  -->
<h1>hello,{{title}}</h1>
<!-- v-text会填充整个innerHTML -->
<h1 v-text="title"></h1>

v-text 与 {{}} 区别:

  1. v-text 会填充整个 innerHTML ,也是一个弊端
  2. 如果要更新部分的 textContent,需要使用{{ }}插值。

2.2 v-cloak

v-cloak:保持在元素上 直到 关联实例结束编译。

  1. 不需要表达式
  2. 这个指令 保持在元素上 直到 关联实例结束编译
  3. 和 CSS 规则 如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 {{ }} (Mustache 标签) 直到实例准备完毕。

    白话理解编译结束时,[v-cloak] 指令失效
    在示例准备完毕结束 之前 实施[v-cloak] 的指令,这里的例子也就是隐藏元素,编译结束后,则不再实行[v-cloak] 的指令

需要配合 css 进行处理

<style>
[v-cloak] {
 display: none;
}
</style>
<p v-cloak>{{title}}</p>

2.3 v-html

v-html:更新元素的 innerHTML,可以让内容作为 html 进行解析

注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译。
如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代。

为了防止 xss 攻击,默认情况下输出是不会作为 html 解析的,通过 v-html 可以让内容作为 html 进行解析

<div id="app">
<!-- 内容按普通 HTML插入  不会作为html来解析的  输出的是文本-->
        <p>{{content}}</p>
        
<!-- 使用v-html 可作为html来解析的 -->
        <p v-html="content" ></p>
</div>

<script>
        let app = new Vue({
            el:"#app",
            data:{
                content:"<style> body{background:pink} </style>",
            }
        });
</script>

页面输出对比:
在这里插入图片描述

2.4 v-once

v-once:只渲染元素和组件一次,后期的更新不再渲染

	<div id="app">
		<div v-once>
			<p>{{msg}}</p>
		</div>
	</div>
	
	<script>
	        let app = new Vue({
	            el:"#app",
	            data:{
	                msg:"我是1"
	            }
	        });
	</script>

2.5 v-pre

v-pre:忽略这个元素和它子元素内容的编译

	<div id="app">
		<span v-pre>{{msg}}</span>
	</div>
	
	<script>
	        let app = new Vue({
	            el:"#app",
	            data:{
	                msg:"我是1"
	            }
			});
    </script>

页面显示:
在这里插入图片描述
在这里插入图片描述

3. 逻辑处理

3.1 v-show

v-show:根据表达式的值(布尔值),切换元素显示与隐藏(display 属性)

改变的只有 该元素的display样式

适用于 状态切换比较频繁 的情况(例如table选项卡、轮播图……)

   <div id="app">
       <div v-show="islogin">这是隐私</div>
   </div>
   <script>
       let app = new Vue({
           el:"#app",
           data:{
               islogin:true
           }
       })
   </script>

islogin:true 时的页面:在这里插入图片描述
islogin:false 时的页面:在这里插入图片描述

3.2 v-if

v-if:根据表达式的值(布尔值),创建或销毁元素

改变的是元素的结构(渲染或者删除)

适用于 状态切换 不频繁 的情况 (例如删除购物车……)

v-if与 v-show 的区别

  v-show:改变的只有 该元素的display样式
      适用于:状态切换 比较 频繁 的情况(例如table选项卡、轮播图……)

  v-if: 改变的是元素的结构(渲染或者删除)
      适用于:状态切换 不频繁 的情况(例如删除购物车……)

   <div id="app">
       <div v-show="islogin">这是隐私</div>
       <br>
       <div v-if="islogin">欢迎</div>
   </div>
   <script>
       let app = new Vue({
           el:"#app",
           data:{
               islogin:true
           }
       })
   </script>

islogin:true 时的页面:
在这里插入图片描述
islogin:false 时的页面:
在这里插入图片描述

3.3 v-else / v-else-if

  • 限制:
    前一兄弟元素必须有 v-if 或 v-else-if。
    v-if 和 v-else以及 v-else-if 之间 必须是连接的,中间不能出现其他元素,否则会报错
  • 用法:为 v-if 或者 v-else-if 添加“else 块”。
   <div id="app">
       <div v-show="islogin">这是隐私</div>
       <br>
       <div v-if="islogin">欢迎</div>
       <!-- <p>哈哈哈</p> -->
       <div v-else="islogin">请登录</div>
   </div>
   <script>
       let app = new Vue({
           el:"#app",
           data:{
               islogin:true
           }
       })
   </script>

islogin:true 时的页面:
在这里插入图片描述
islogin:false 时的页面:
在这里插入图片描述

4. 循环与列表

4.1 v-for

根据数据循环渲染 v-for 指令所在的元素及其子元素

可以循环的数据:Array | Object | number | string | Iterable (2.6 新增)

<div v-for="(item, index) in items"></div>

<div v-for="(val, key) in object"></div>
<div v-for="(val, key, index) in object"></div>
<!-- index 属性名对应的下标 -->

循环数组,循环对象实例:

    <!-- 指令中的循环 -->
    <div id="app">
        <ul>
        <!-- of  in  在这里使用没有区别 -->

        <!-- 1. 循环数组中的 -->         
            <li v-for = "user in users" :key="user.id">
                <!-- 没加 :key="user.id" 的时候 input框里选中的不跟数据变化走-->
                <input type="checkbox">
                {{user.id}} - {{user.name}}
            </li>
        </ul>

        <!-- 2. 循环对象中的 -->
        <div v-for="(val,name,index) in Object">
            <span>索引值:{{index}}</span>
            <span>属性名:{{name}},值:{{val}}</span>
        </div>
    </div>

v-for 中也可以使用 of 语法,在 vue 中两者没有什么区别

4.2 :key

默认情况下,在渲染 DOM 过程中使用 原地复用 ,这样一般情况下会比较高效,但是对于循环列表,特别是依赖某种状态的列表,会有一些问题,我们可以通过 :key 属性,来给每个循环节点添加一个标识

v-for和:key代码示例

   <!-- 指令中的循环 -->
   <div id="app">
       <ul>
       <!-- of  in  在这里使用没有区别 -->

       <!-- 1. 循环数组中的 -->         
           <li v-for = "user in users" :key="user.id">
               <!-- 没加 :key="user.id" 的时候 input框里选中的不跟数据变化走-->
               <input type="checkbox">
               {{user.id}} - {{user.name}}
           </li>
       </ul>

       <!-- 2. 循环对象中的 -->
       <div v-for="(val,name,index) in Object">
           <span>索引值:{{index}}</span>
           <span>属性名:{{name}},值:{{val}}</span>
       </div>
       
       <!-- 
       
           <div v-for="(item, index) in items"></div>

           <div v-for="(val, key) in object"></div>
           <div v-for="(val, key, index) in object"></div> 
       
       -->
       <!-- index 属性名对应的下标 -->

   </div>

   <script>
       // 虚拟dom  vdom  有一个机制:每次加载过后,会像缓存似的留一个备份,
       //                          等下一次渲染的时候,去看跟之前留的有什么不一样的地方
       //                          有变动的地方就改一下,没有变大的就原样渲染到html上
       //                          也为了尽可能少的去修改dom,为了达到优化加载速度的目的
       //所以执行数据排序sort()时,仅是id,name改变了,四个input里不变,所以选中框选中情况没有重新渲染,因为跟备份的是一致的,
       
       //想要跟随去动,使用 :key  给每个循环节点添加一个标识
       //例如   :key="user.id"  

       //模板 => vdom =>html
       // 留一备份    
       {
           li : "1"
           li : "2"
           li : "3"
           li : "4"
       }
       let app = new Vue({
           el:"#app",
           data:{
               users:[
                   {id:1,name:"小马"},
                   {id:2,name:"小陈"},
                   {id:3,name:"小冯"},
                   {id:4,name:"小金"}
               ],
               Object:{
                   x:"a",
                   y:"b",
                   z:"c"
               }
           }
       });

       app.users.sort((a,b)=>{
           return Math.random() - .5
       });

   </script>

随机排序前:在这里插入图片描述
随机排序后:
在这里插入图片描述

5. 属性绑定

5.1 v-bind

绑定数据(表达式)到指定的属性上,<div v-bind:参数="值/表达式"></div>,这里的参数就是指定的属性名称

v-指令名称:参数=“指令的值” (参数是指定的属性名称)

注意跟不加v-bind:或者 :作区分,不加的话则是原生获取属性的方式

<div id="app">
  <div v-bind:id="myId"></div>
  <div v-bind:class="myclass"></div>
  <div :id="Id"></div>
</div>

<script>
	new Vue({
    el: '#app',
    data: {
    	myclass:"box",
    	Id:"haha",
      	myId: 'kaikeba'
    }
  })
</script>
缩写

有的一些常用指令会有对应的缩写,v-bind 对应的缩写为::

<div :id="myId"></div>

5.2 样式

针对样式属性v-bind 值有一些特殊的写法

5.2.1 style
  • 原生普通写法
<div style="width: 100px; height: 100px; background: red"></div>
  • v-bind 写法
<div :style="'width: 100px; height: 100px; background: red'"></div>
  • 对象写法
<div :style="style1"></div>

...
<script>
new Vue({
	el: '#app',
	data: {
		style1: {
	      width: '100px',
	      height: '100px',
	      background: 'green'
	    }
	}
});
</script>
  • 数组写法:有重复的优先显示最后一个;数组 [] 内不能写引号
<div :style="[style1, style2]"></div>

...
<script>
new Vue({
	el: '#app',
	data: {
		style1: {
	      width: '100px',
	      height: '100px',
	      background: 'green'
	    },
	    style2: {
	      border: '1px solid black'
	  	}
	}
  
});
</script>
5.2.2 class
  • 原生普通写法
<div class="box1 box2"></div>
  • v-bind 写法
<div :class="'box1 box2'"></div>
  • 数组写法
<div :class="['box1', 'box2']"></div>
  • 对象写法布尔值
<div :class="{'box1': isActive, 'box2': isChecked}"></div>

使用对象写法,可以根据值(boolean)动态添加对应的 class
true的时候显示样式,false不显示,都是true的时候,就根据css样式优先级来显示

    <style>
        div{
            font-size: 13px;
            text-align: center;
            line-height: 50px;
        }
        .box1{
            width: 200px;
            height: 200px;
            background:pink
        }
        .box2{
            width: 300px;
            height: 100px;
            background:yellow;
            border: 2px solid black;
        }
    </style>
</head>
<body>

    <div id="app">

        <!-- 原生写法 -->
        <div style="width : 100px; height : 100px; background-color: yellowgreen;">原生style</div>
        
        <!-- v-bind -->
        <div :style="style1">:style="style1"</div>

        <!-- 数组写法 
            :style   获取的是具体的样式
            :class   获取的是类名
        -->
        <div :class="box">:class="box"</div>
        <div :style="[style1,style2]">:style="[style1,style2]"</div>

        <!-- 对象写法 -->
        <div :class="{'box1':new_box,'box2':two_box}">:class="{'box1':new_box,'box2':two_box}"</div>

    </div>
    
    <script>

        let app = new Vue({
            el:"#app",
            data:{
                style1:{
                    width:'100px',
                    height:'100px',
                    background:'blue'
                },
                style2:{
                    width:'150px',
                    height:'150px',
                    background:'green',
                    border:'2px solid black'
                },
                box:"school",
                new_box:true,
                two_box:false
            
            }
        })


    </script>

class对象写法中
new_box:true, two_box:false 时
在这里插入图片描述
new_box:true, two_box:true 时
在这里插入图片描述

6. 数据流

6.1 单向数据流

通过上面的知识点和案例,我们可以看到,当数据更新的时候,页面视图就会更新,但是页面视图中绑定的元素更新的时候,对应的数据是不会更新的

我们称为:单向数据流数据 => 视图

  • v-bind: 单向数据绑定。 数据 => 视图
<input type="text" :value="msg2" />
<div>{{msg2}}</div>

vue 中,还有一种双向数据流绑定的方式

6.2 双向数据流 v-model

<input type="text" v-model="msg" />
<div>{{msg}}</div>

数据 msg 更新,视图中 inputvalue 就会更新。同时,当 input 中的 value 更新的时候,数据 msg 也会更新,这就是我们说的 数据双向绑定 [与 React 中的受控组件类似]

v-model:  双向数据绑定数据=>视图视图=>数据 用于交互性元素

  不是所有的标签(组件)都支持 v-model
    – 默认:交互元素(input, textarea, select)

  不是所有的属性都支持 v-model
    – v-model 只能绑定一个指定好的属性
     input :   value
     textarrea : value
     select :  selected

非交互: div p img 等静态类标签(不需要统计信息的)


    <div id="app">
        <!-- 双向数据绑定  数据=>视图 ,视图=>数据 -->
        <input type="text" v-model="msg"> 双向
        <div>{{msg}}</div>

        <br><hr><br>

        <!-- 单向绑定 数据=>视图 -->
        <input type="text" :value="msg2"> 单向
        <div>{{msg2}}</div>
    </div>

    <script>
        let app = new Vue({
            el:"#app",
            data:{
                msg:"123",
                msg2:"abc"
            }
        })
    </script>  
      

页面显示:
在这里插入图片描述
数据=>视图(单向、双向都可以):
在这里插入图片描述
视图=>数据 (只有双向才可以):
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值