Vue成神之路之内部指令

前言

记录平时学到的知识,标题写的大气一点,也算是给自己一点鼓励,希望在技术这条路可以远走越远,路越走越宽~

文中代码地址

PS:如果对你有一点帮助,请顺手给个小星星哦,鼓励我继续写下去~

引入的文件文件说明

vue.js——开发版本:包含完整的警告和调试模式
vue.min.js——生产版本:删除了警告,进行了压缩

1、内部指令

指令 (Directives) 是带有 v- 前缀的特殊特性。指令特性的值预期是单个 JavaScript 表达式 (v-for 是例外情况)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

1.1 v-if & v-show

v-if

  • v-if:是vue的一个内部指令,必须将它添加到一个元素上。v-if根据条件判断是否加载对应元素的DOM。

  • v-else 指令来表示 v-if 的“else 块”。v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。

  • v-else-if,顾名思义,充当v-if的“else-if块”,可以连续使用。类似于v-else,v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
    <h1>v-if & v-else & v-show</h1>
    <hr>
    <div id="app">
        <div v-if="isLogin == 'A'">v-if</div>
        <div v-else-if="isLogin == 'B'">v-else-if</div>
        <div v-else>v-else</div>
        <div v-show="isLogin">v-show</div>
        <hr>
        <template v-if="isLogin == 'B'">v-if支持template元素</template>
        <template v-show="isLogin == 'B'">v-show不支持template元素</template>>
    </div>

    <script type="text/javascript">
        var app = new Vue({
            el: '#app',
            data: {
                isLogin: 'A'
            },
            components: {
                "test-child": {
                  template:"<h1>我是template</h1>"
                }
            }
        })
    </script>
</body>
</html>

v-show

  • v-show:是另一个用于根据条件展示元素的指令。

不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。

注意,v-show 不支持 <template>元素,也不支持 v-else。

v-if 和v-show的区别:

  • v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

  • v-show 就简单得多,不管初始条件是什么,元素总是会被渲染,即元素会始终渲染并保持在DOM中,并且只是简单地基于 CSS 进行切换。

  • v-show不支持template元素,作用在template元素上没有效果,v-if则支持。

一般来说,v-if 有更高的切换开销(根据条件对元素进行创建...销毁...创建...销毁),而 v-show 有更高的初始渲染开销(不管条件是否为true,,元素都会被渲染并保存在DOM中)。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

1.2 v-for指令:解决模板循环问题

用 v-for 指令根据一组数组的选项列表进行渲染。v-for 指令需要使用 item in items 形式的特殊语法,items 是源数据数组并且 item 是数组元素迭代的别名。

需要注意的是,你需要那个html标签循环,v-for就写在那个标签上面。

基本用法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <title>V-for 案例</title>
</head>
<body>
    <h1>v-for指令用法</h1>
    <hr>
    <div id="app">
       <ul>
           <li v-for="item in items">
                {{item}}
           </li>
       </ul>
    </div>
    <script type="text/javascript">
        var app=new Vue({
            el:'#app',
            data:{
                items:[20,23,18,65,32,19,54,56,41]
            }
        })
    </script>
</body>
</html>

排序:
运行上面代码,可以看到浏览器顺利的输出了定义的数组,但是如果想在输出之前对定义的数组进行一些操作,例如:给定义的数组排个序,则可以使用Vue的computed:属性。

var app = new Vue({
    ......
    computed:{
        sortItems:function(){
              return this.items.sort(sortNumber);
        }
    }
})

function sortNumber(a,b){
    return a-b
}

在computed里新声明了一个对象sortItems,如果不重新声明延用data里面定义的数组items则会报错,原因是这样会污染原来定义的数据源,这是Vue不允许的,所以要重新声明一个对象。

对象循环输出:

先定义个数组,数组里边是对象数据

students: [
    {name: 'Andy', age: 18},
    {name: 'Tony', age: 17},
    {name: 'Alen', age: 35},
    {name: 'zaishuiyixia', age: 25}
]

在模板中输出

<ul>
   <li v-for="student in students">
       {{student.name}} - {{student.age}}
   </li>
</ul>

加入索引序号:

//数组对象方法排序:
function sortByKey(array,key){
    return array.sort(function(a,b){
      var x=a[key];
      var y=b[key];
      return ((x<y)?-1:((x>y)?1:0));
   });
}

有了数组的排序方法,在computed中进行调用排序

sortStudent:function(){
     return sortByKey(this.students,'age');
}

完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-for</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
    <h1>v-for实例</h1>
    <hr>
    <div id="app">
        <ul>
            <li v-for="item in sortItems">
                {{item}}
            </li>
        </ul>
        <hr>
        <ul>
            <li v-for="(student, index) in sortStudent">
                {{index+1}}: {{student.name}}-{{student.age}}
            </li>
        </ul>
    </div>

    <script type="text/javascript">
        var app = new Vue({
            el: '#app',
            data: {
                items:[25,58,98,65,28,98,28,76],
                students: [
                    {name: 'Andy', age: 18},
                    {name: 'Tony', age: 17},
                    {name: 'Alen', age: 35},
                    {name: 'zaishuiyixia', age: 25}
                ]
            },
            computed: {
                sortItems: function() {
                    return this.items.sort(sortNumber)
                },
                sortStudent:function(){
                     return sortByKey(this.students,'age');
                }
            }
        });

        function sortNumber(a, b) {
            return a-b;
        }

        //数组对象方法排序:
        function sortByKey(array,key){
            return array.sort(function(a,b){
              var x=a[key];
              var y=b[key];
              return ((x<y)?-1:((x>y)?1:0));
           });
        }
    </script>
</body>
</html>

1.3 v-text & v-html指令

Vue中数据绑定的形式是使用“Mustache”语法 (双大括号) 的文本插值:

<span>Message: {{ msg }}</span>

使用这种语法是有弊端的,就是当速很慢或者javascript出错时,浏览器会先显示{{xxx}}。Vue提供的v-text,就是解决这个问题的。

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

如果在javascript中写有html标签,用v-text是输出不出来的,这时候我们就需要用v-html标签了。

双大括号会将数据解释为纯文本,而非HTML。为了输出真正的HTML,就需要使用v-html 指令。 需要注意的是:在生产环境中动态渲染HTML是非常危险的,因为容易导致XSS攻击。所以只能在可信的内容上使用v-html,永远不要在用户提交和可操作的网页上使用。 完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-text & v-html实例</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
    <h1>v-text & v-html实例</h1>
    <hr>
    <div id="app">
        <span>{{message}}</span> == <span v-text="message"></span>
        <br>
        <span v-html="html"></span>
    </div>

    <script type="text/javascript">
        var app = new Vue({
            el: '#app',
            data: {
                message: 'hello world!',
                html: '<h2>hello world!</h2>'
            }
        })
    </script>
</body>
</html>

1.4 v-on指令

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

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

使用绑定事件监听器,编写一个加分减分的程序:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-on实例</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
    <h1>v-on实例</h1>
    <hr>
    <div id="app">
        本场比赛得分:{{score}}
        <p>
            <button v-on:click="jiafen">加分</button>
            <button v-on:click="jianfen">减分</button>
            <br><br>
            <!-- 绑定键盘的enter键 -->
            <input type="text" v-on:keyup.enter="onEnter" v-model="score2" >
        </p>
    </div>

    <script type="text/javascript">
        var app = new Vue({
            el: '#app',
            data: {
                score: 0,
                score2: 1
            },
            methods: {
                jiafen: function() {
                    this.score++;
                },
                jianfen: function() {
                    this.score--;
                },
                onEnter: function() {
                    this.score = this.score + parseInt(this.score2)
                }
            }
        })
    </script>
</body>
</html>

v-on 还有一种简单的写法,就是用@代替。

<button @click="jianfen">减分</button>

除了绑定click之外,还可以绑定其它事件,比如键盘回车事件v-on:keyup.enter,现在增加一个输入框,然后绑定回车事件,回车后把文本框里的值加到我们的count上。 绑定事件写法:

<input type="text" v-on:keyup.enter="onEnter" v-model="score2">

javascript代码:

onEnter:function(){
     this.count=this.count+parseInt(this.secondCount);
}

因为文本框的数字会默认转变成字符串,所以我们需要用parseInt()函数进行整数转换。

1.5 v-model

v-model指令,可简单的理解为绑定数据源。就是把数据绑定在特定的表单元素上,可以很容易的在表单控件或者组件上创建双向绑定 、 。

使用限制,应该用于表单控件或者组件上:

<input>、<select>、<textarea>、components

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-model绑定数据源实例</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
    <h1>v-model绑定数据源实例</h1>
    <hr>
    <div id="app">
        <p>原始文本信息:{{message}}内部指令</p>
        <h3>文本框</h3>
        <p>v-model:<input type="text" v-model="message"></p>
        <p>v-model.lazy:<input type="text" v-model.lazy="message"></p>
        <p>v-model.number:<input type="text" v-model.number="message"></p>
        <p>v-model.trim<input type="text" v-model.trim="message"></p>
        <hr>
        <h3>文本域</h3>
        <textarea cols="30" rows="10" v-model="message"></textarea>
        <hr>
        <h3>多选框绑定一个值</h3>
        <input type="checkbox" id="isTrue" v-model="isTrue">
        <label for="isTrue">{{isTrue}}</label>
        <hr>
        <h3>多选框绑定数组</h3>
        <p>
            <input type="checkbox" id="alen" value="alen" v-model="names">
            <label for="alen">alen</label>
            <input type="checkbox" id="andy" value="andy" v-model="names">
            <label for="andy">andy</label>
            <input type="checkbox" id="tony" value="tony" v-model="names">
            <label for="tony">tony</label>
            <p>{{names}}</p>
        </p>
        <hr>
        <h3>单选框绑定</h3>
        <p>
            <input type="radio" id="man" value="男" v-model="sex">
            <label for="man">男</label>
            <input type="radio" id="woman" value="女" v-model="sex">
            <label for="woman">女</label>
            <p>你选择的性别是:{{sex}}</p>
        </p>
    </div>

    <script type="text/javascript">
        var app = new Vue({
            el: '#app',
            data: {
                message: 'hello world!',
                isTrue: true,
                names: [],
                sex: '男'
            },
            methods: {
                
            }
        })
    </script>
</body>
</html>

1.6 v-bind

动态地绑定一个或多个属性。在绑定 class 或 style 特性时,支持其它类型的值,如数组或对象。

绑定css样式,在绑定CSS样式时,绑定的值必须在vue中的data属性中进行声明:

1、直接绑定class样式

<div :class="className">1、绑定classA</div>

2、绑定classA并进行判断,在isClassA为true时显示样式,在isClassA为false时不显示样式。

<div :class="{classA:isClassA}">2、绑定class中的判断</div>

3、绑定class中的数组

<div :class="[classA,classB]">3、绑定class中的数组</div>

4、绑定class中使用三元表达式判断

<div :class="isClassA?classA:classB">4、绑定class中的三元表达式判断</div>

5、绑定style

<div :style="{color:red,fontSize:font}">5、绑定style</div>

6、用对象绑定style样式

<div :style="styleObject">6、用对象绑定style样式</div>
......
var app=new Vue({
   el:'#app',
   data:{
       styleObject:{
           fontSize:'24px',
           color:'green'
            }
        }
})

完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-bind实例</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
    <style>
        .classA {
            color: red;
        }
        .classB {
            font-size: 150%;
        }
    </style>
</head>
<body>
    <h1>v-bind实例</h1>
    <hr>
    <div id="app">
        <p><img v-bind:src="imgUrl" alt="" width="300px"></p>
        <p><a :href="blogUrl" target="_blank">我的博客地址</a></p>
        <hr>
        <div :class="className">1、绑定class属性</div>
        <div :class="{classA: isClassA}">2、绑定class中的判断</div>
        <div :class="[classA, classB]">3、绑定class中的数组</div>
        <div :class="isClassA?classA:classB">4、绑定class中的三元运算符</div>
        <hr>
        <div>
            <input type="checkbox" id="isClassA" v-model="isClassA">
            <label for="isClassA">isClassA={{isClassA}}</label>
        </div>
        <hr>
        <div :style="{color:color,fontSize:font}">5、绑定style</div>
        <div :style="styleObj">5、对象绑定style</div>
    </div>

    <script type="text/javascript">
        var app = new Vue({
            el: '#app',
            data: {
                imgUrl: 'https://upload-images.jianshu.io/upload_images/1969310-c688f5d4d3a352b1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp',
                blogUrl: 'https://www.jianshu.com/p/26010db3776c',
                className: 'classA',
                isClassA: false,
                classA: 'classA',
                classB: 'classB',
                color: 'red',
                font: '20px',
                styleObj: {
                    color: 'green',
                    fontSize: '24px'
                }
            }
        })
    </script>
</body>
</html>

1.7 其他指令

v-pre指令:

在模板中跳过vue的编译,直接输出原始值。就是在标签中加入v-pre就不会输出vue中的data值了。

<div v-pre>{{message}}</div>

v-cloak指令:

在vue渲染完指定的整个DOM后才进行显示。可以防止数据抖动。

<div v-cloak>
  {{ message }}
</div>

v-once指令:

在第一次DOM时进行渲染,渲染完成后视为静态内容,跳出以后的渲染过程。

<div v-once>第一次绑定的值:{{message}}</div>
<div><input type="text" v-model="message"></div>

完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-pre & v-cloak & v-once</title>
    <script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
    <h1>v-pre & v-cloak & v-once</h1>
    <hr>
    <div id="app">
        <div v-pre>{{message}}</div>
        <div v-cloak>渲染完成后,才显示!</div>
        <div>{{message}}</div>
        <div><input type="text" v-model="message"></div>
        <div>{{message}}</div>
    </div>

    <script type="text/javascript">
        var app = new Vue({
            el: '#app',
            data: {
                message: 'hello world!'
            }
        })
    </script>
</body>
</html>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,044评论 0 29
  • vue概述 在官方文档中,有一句话对Vue的定位说的很明确:Vue.js 的核心是一个允许采用简洁的模板语法来声明...
    li4065阅读 7,185评论 0 25
  • 1.安装 可以简单地在页面引入Vue.js作为独立版本,Vue即被注册为全局变量,可以在页面使用了。 如果希望搭建...
    Awey阅读 10,982评论 4 129
  • 主要还是自己看的,所有内容来自官方文档。 介绍 Vue.js 是什么 Vue (读音 /vjuː/,类似于 vie...
    Leonzai阅读 3,324评论 0 25
  • 苹果家族是建立小马谷的家庭。它们的名字都和苹果有关。就像苹果罗丝、苹果丽丽等。史密夫婆婆是全小马谷最老的小马,小马...