Vue

116 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

Vue 模板语法

  • 差值表达式
  • 指令
  • 事件绑定
  • 属性绑定
  • 样式绑定
  • 分支循环结构

指令

1.什么是指令?

  • 指令的本质就是自定义属性
  • 指令的格式:以v-开始(例如:v-clock)

2. v-cloak指令用法

  • 差值表达式存在的问题:“闪动“-连续刷新页面会出现先弹出{{msg}之后在替换成值的情况。
  • 如何解决该问题:使用v-cloak指令
  • 原理:先隐藏,替换好值之后在显示最终的值
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>02 v-cloak</title>
    <style>
        [v-cloak] {
            display: none;
        }
    </style>
</head>

<body>
    <div id="app">
        <div v-cloak>{{msg}}</div>
    </div>
    <script src="js/vue.min.js"></script>
    <script>
        /* 
        v-cloak指令的用法
            1. 提供样式:
             [v-cloak] {
             display: none;
             }
            2. 在差值表达式所在的标签中添加v-cloak指令
        */
        var vm = new Vue({
            el: '#app',
            data: {
                msg: 'Hello Vue'
            }
        });
    </script>
</body>
</html>

3. 数据绑定指令

  • v-text 填充纯文本
    • 相比插值表达式更加简洁
  • v-html 填充HTML片段
    • 存在安全问题
    • 本网站内部数据可以使用,来自第三方的数据不可使用
  • v-pre 填充原始信息
    • 显示原始信息,跳过编译过程
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>02 v-cloak</title>
    <style>
        [v-cloak] {
            display: none;
        }
    </style>
</head>
<body>
    <div id="app">
        <div v-cloak>{{msg}}</div>
        <div v-text=msg></div>
        <div v-html=msg1></div>
        <div v-pre>{{跳过编译过程输出内容}}</div>
    </div>
    <script src="js/vue.min.js"></script>
    <script>
        
        var vm = new Vue({
            el: '#app',
            data: {
                msg: 'Hello Vue',
                msg1:'<h1>HTML</h1>'
            }
        });
    </script>
</body>
</html>

4.数据响应式

  • 如何理解响应式
    • html5中的响应式(屏幕尺寸的变化导致样式的变化)
    • 数据的响应式(数据的变化导致页面内容的变化)
  • 什么是数据绑定
    • 数据绑定:将数据团填充到标签中
  • v-once 只编译一次
    • 显示内容之后不再具有响应式功能
<body>
    <div id="app">
        <div v-cloak>{{msg}}</div>
        <div v-once>{{msg1}}</div>
    </div>
    <script src="js/vue.min.js"></script>
    <script>
        /* 
           v-once的应用场景:如果显示的信息后续不需要修改,可以使用v-once,提高性能
        */
        var vm = new Vue({
            el: '#app',
            data: {
                msg: 'Hello Vue',
                msg1:'nihao'
            }
        });
    </script>
</body>

双向数据绑定

  • v-model指令用法:在表单控件或者组件上创建双向绑定

    示例代码如下:

    <body>
        <div id="app">
            <div>{{msg}}</div>
            <div>
                <input type="text" v-model="msg">
            </div>
        </div>
        <script src="js/vue.min.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    msg: 'Hello Vue'
                }
            });
        </script>
    </body>
    

MVVM设计思想

  • M(model)
  • V (View)
  • VM(View-Model)

事件绑定

Vue如何处理事件与实践函数的调用方式:

  • v-on指令用法 简写模式:@

    <input type='button' v-on:click='num++'>
    //如下为简写样式,把v-on改成了@
    <input type='button' @click='num++'>
    
  • 事件函数的调用方式

    • 直接绑定函数名称
    <button v-on:click='say'>Hello</button>
    
    • 事件绑定调用函数
    <button v-on:click='say()'>Hello</button>
    

v-on 指令与实践函数的调用方式示例代码如下:

<body>
    <div id="app">
        <div>{{num}}</div>
        <button v-on:click='num++'>点击1</button>
        <button @click='num++'>点击2</button>
        <button @click='handle'>点击3</button>
        <button @click='handle()'>点击4</button>
    </div>
    <script src="js/vue.min.js"></script>
    <script>
        // 事件绑定
        var vm = new Vue({
            el: '#app',
            data: {
                num: 0
            },
            methods:{
                handle:function(){
                    // this是Vue的实例对象
                    this.num++;
                }
            }
        });
    </script>
</body>
  • 事件函数参数传递
    • 普通参数和事件参数

示例代码如下:

<body>
    <div id="app">
        <div>{{num}}</div>
        <!-- 方式一:直接绑定函数名称 -->
        <button @click='handle1'>点击1</button>
        <!-- 方式二:事件绑定调用函数 -->
        <button @click='handle2(123,456,$event)'>点击2</button>
        <!-- $event为事件对象是固定的 -->
    </div>
    <script src="js/vue.min.js"></script>
    <script>
        /* 事件绑定 - 参数传递
        1.如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数
        2.如果事件绑定函数调用,那么事件对象必须作为最后一个参数显示传递
        */
        var vm = new Vue({
            el: '#app',
            data: {
                num: 0
            },
            methods: {
                /* 按钮2 */
                handle2: function (event) {
                    console.log(p1, p2);
                    console.log(event.target.innerHTML)
                    this.num++; // this是Vue的实例对象
                },
                /* 按钮1 */
                handle1: function (event) {
                    console.log(event.target.innerHTML)
                    this.num++; // this是Vue的实例对象
                }
            }
        });
    </script>
</body>
  • 事件修饰符
    • .stop 阻止冒泡

    • .prevent 阻止默认事件

    示例代码如下:

    <body>
        <div id="app">
            <div>{{num}}</div>
            <!-- 事件绑定调用函数 -->
            <div @click='handle1($event)'>
                <!-- .stop 阻止冒泡 -->
                <button @click.stop='handle2($event)'>点击</button>
            </div>
            <div>
                <!-- .prevent阻止默认事件 -->
                <a @click.prevent='handle3($event)' href="www.baidu.com">百度</a>
            </div>
        </div>
        <script src="js/vue.min.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    num: 0
                },
                methods: {
                    handle1: function (event) {
                        this.num++; // this是Vue的实例对象
                    },
                    /* 按钮 */
                    handle2: function (event) {},
                    handle3: function (event) {}
                }
            });
        </script>
    </body>
    
  • 按键修饰符
    • .enter 回车键
    • .delete 删除键

示例代码如下:

<body>
    <div id="app">
        <form action="">
            用户名:<input type="text" v-model='uname' v-on:keyup.delete='clearContent'><br>
            密码:<input type="text" v-model='pwd' v-on:keyup.delete='clearContent'><br>
            <!-- v-on:.click.keyup.enter='handleSubmit'的意思是点击按钮或者敲击回车键都可提交 -->
            <input type="button" value="提交" v-on:.click.keyup.enter='handleSubmit'>
        </form>
    </div>
    <script src="js/vue.min.js"></script>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                uname: '',
                pwd: ''
            },
            methods: {
                clearContent: function () {
                    this.uname = '',
                        this.pwd = '';
                },
                handleSubmit: function () {
                    console.log(this.uname, this.pwd)
                },
            }
        });
    </script>
</body>
  • 自定义按键修饰符
    • 全局 config.keyCodes对象

示例代码如下:

<body>
    <div id="app">
        <form action="">
            用户名:<input type="text" v-model='info' v-on:keyup.a='handle1'><br>
        </form>
    </div>
    <script src="js/vue.min.js"></script>
    <script>
        /* 
            事件绑定 - 自定义按键修饰符
            规则:自定义按键修饰符名字是自定义的,但是对应的值必须是按键对应的event.keyCode值
        */
        Vue.config.keyCodes.a = 65
        var vm = new Vue({
            el: '#app',
            data: {
                info: ''
            },
            methods: {
                handle1: function (event) {
                    console.log(event.keyCode)
                }
            }
        });
    </script>
</body>

属性绑定

1. Vue如何动态处理属性?

  • v-bind指令用法

    <body>
        <div id="app">
            <!-- 标准写法如下:v-bind:-->
            <!-- <a v-bind:href="url" id="a">{{msg1}}</a> -->
            <!-- 简写方法如下:':'-->
            <a :href="url" id="a">{{msg1}}</a>
            <button v-on:click='handle'>切换</button>
        </div>
        <script src="js/vue.min.js"></script>
        <script>
            /* 属性绑定 */
            var a = document.getElementById("a")
    
            var vm = new Vue({
                el: '#app',
                data: {
                    url: 'http://www.baidu.com',
                    msg1: '百度',
                },
                methods: {
                    handle: function () {
                        this.url = 'http://www.change.tm';
                        this.msg1 = '启嘉网'
                    }
                }
            })
        </script>
    </body>
    

2. v-model的底层实现原理分析

<body>
  <div id="app">
      <div>{{msg}}</div>
      <input type="text" v-bind:value='msg' v-on:input='handle'>
      <!-- 这一句就省略了下面的handle方法 -->
      <input type="text" v-bind:value='msg' v-on:input='msg=$event.target.value'>
      <!-- v-model 方法最简便 -->
      <input type="text" v-model='msg'>
  </div>
  <script src="js/vue.min.js"></script>
  <script>
      /* v-model的本质 */
      var vm = new Vue({
          el: '#app',
          data: {
              msg: 'hello'
          },
          methods: {
              handle: function (event) {
                  // 使用输入域中的最新的数据覆盖原来的数据
                  this.msg = event.target.value
              }
          }
      })
  </script>
</body>

样式绑定

1. class样式处理

  • 对象语法

    <div v-bind:class="{active:isActive}"></div>
    

    示例代码如下:

    <style>
            .active {
                border: 2px black solid;
                width: 100px;
                height: 100px;
            }
            .error {
                background-color: darkmagenta;
            }
    </style>
    
    <body>
        <div id="app">
            <div v-bind:class="{active:isActive,error:isError}">测试内容</div>
            <button v-on:click='handle'>切换</button>
        </div>
        <script src="js/vue.min.js"></script>
        <script>
            /* 样式绑定 */
            var vm = new Vue({
                el: '#app',
                data: {
                    isActive: true,
                    isError: true
                },
                methods: {
                    handle: function (event) {
                        // 控制isActive的值在true和false之间进行切换
                        this.isActive = !this.isActive;
                        this.isError = !this.isError;
                    }
                }
            })
        </script>
    </body>
    
  • 数组语法

    <div  v-bind:class="[activeClass,errorClass]"></div>
    

    数组语法修改样式示例代码如下:

    	<style>
            .active {
                border: 2px black solid;
                width: 100px;
                height: 100px;
            }
            .error {
                background-color: darkmagenta;
            }
        </style>
    <body>
        <div id="app">
            <div v-bind:class="[activeClass,errorClass]">测试内容</div>
            <button v-on:click='handle'>切换</button>
        </div>
        <script src="js/vue.min.js"></script>
        <script>
            /* 样式绑定 */
            var vm = new Vue({
                el: '#app',
                data: {
                    activeClass: 'active',
                    errorClass: 'error'
                },
                methods: {
                    handle: function (event) {
                        //直接置空修改样式
                        this.errorClass = '';
                    }
                }
            })
        </script>
    </body>
    
  • 样式绑定 - 细节处理:

    • (1)对象绑定和数字绑定可以结合使用
    • (2)class绑定的值可以简化操作
    • (3)默认的class如何处理?答案是:默认的class会保留

上述三点的测试代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>16 样式绑定-细节处理</title>
    <style>
        .active {
            border: 2px black solid;
            width: 100px;
            height: 100px;
        }

        .error {
            background-color: darkmagenta;
        }

        .test {
            color: darkorange;
        }
        .base{
            font-size: 24px;
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- 细节一:对象绑定和数组绑定可以结合使用 -->
        <div v-bind:class="[activeClass,errorClass,{test:isTest}]">测试内容</div>
        <!-- 细节二:class绑定的值的简化操作--数组和对象都可简化 -->
        <div v-bind:class="arrClasses"></div>
        <div v-bind:class="objClasses">对象样式简化操作</div>
       <!-- 细节三:默认的class如何处理?答案是:默认的class会保留 -->
        <div class="base" v-bind:class="objClasses">默认的class</div>

        <button v-on:click='handle'>切换</button>
    </div>
    <script src="js/vue.min.js"></script>
    <script>
        /* 样式绑定 */
        var vm = new Vue({
            el: '#app',
            data: {
                activeClass: 'active',
                errorClass: 'error',
                isTest: true,
                arrClasses: ['active', 'error'],
                objClasses: {
                    active: true,
                    test: true
                }
            },
            methods: {
                handle: function (event) {
                    this.errorClass = '';
                }
            }
        })
    </script>
</body>

</html>

2. style(内联)样式处理

  • 对象语法

    <div v-bind:style="{color:activecolor,fontsize:fontsize}"></div>
    
  • 数组语法

    <div v-bind:style="[basestyle,overridingStyles]"></div>
    

style(内联)样式处理的对象语法和数组语法如下所示:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>16 样式绑定-细节处理</title>
</head>

<body>
    <div id="app">
        <!-- 对象语法 -->
        <div v-bind:style='{border:borderStyle,width:widthStyle,height:heightStyle}'></div>
        <div v-bind:style='objStyle'></div>
        <!-- 数组语法: -->
        <div v-bind:style='[objStyle,overridingStyles]'></div>
        <button v-on:click='handle'>切换</button>
    </div>
    <script src="js/vue.min.js"></script>
    <script>
        /* 样式绑定 */
        var vm = new Vue({
            el: '#app',
            data: {
                borderStyle: '2px solid black',
                widthStyle: '100px',
                heightStyle: '100px',
                objStyle: {
                    border: '5px solid green',
                    width: '200px',
                    height: '200px'
                },
                overridingStyles: {
                    /* overridingStyles会覆盖之前原有的样式 */
                    border: '3px solid red',
                    backgroundColor: 'pink'
                }

            },
            methods: {
                handle: function (event) {
                    this.widthStyle = '200px';
                    this.objStyle.width = '100px'
                }
            }
        })
    </script>
</body>

</html>

分支循环结构

1. 分支结构
  • v-if
  • v-else
  • v-else-if
  • v-show
2. v-if与v-show的区别
  • v-if控制元素是否渲染到页面
  • v-show控制元素是否显示(已经渲染到了页面)

示例代码如下:

<body>
    <div id="app">
        <div v-if='score>=90'>优秀</div>
        <div v-else-if='score<90&&score>=80'>良好</div>
        <div v-else-if='score<80&&score>=60'>及格</div>
        <div v-else></div>
        <div v-show='flag'>测试v-show</div>
        <button v-on:click='handle'>点击切换</button>
    </div>
    <script src="js/vue.min.js"></script>
    <script>
        /* 
            分支结构
            v-show的原理:控制元素样式是否显示 display:none
        */
        var vm = new Vue({
            el: '#app',
            data: {
                score:20,
                flag:false
            },
            methods: {
                handle:function(){
                    this.flag=!this.flag
                }
            }
        });
    </script>
</body>
3. 循环结构
  • v-for遍历数组

  • key的作用:帮助Vue区分不同的元素,从而提高性能

<body>
    <div id="app">
        <div>水果列表</div>
        <ul>
            <li v-for='item in fruits'>{{item}}</li>
            <!-- 可以加上索引 -->
            <li v-for='(item,index) in fruits'>{{item + '---' + index}}</li>
            <!-- key 的作用:帮助Vue区分不同的元素,从而提高性能 -->
            <li :key='item.id' v-for='item in myFruits'>
                <span>{{item.ename}}</span>
                <span>------</span>
                <span>{{item.cname}}</span>
            </li>
        </ul>
    </div>
    <script src="js/vue.min.js"></script>
    <script>
        /* 循环结构 */
        
        var vm = new Vue({
            el: '#app',
            data: {
                fruits: ['apple', 'banana', 'orange'],
                myFruits: [{
                    id: 1,
                    ename: 'apple',
                    cname: '苹果'
                }, {
                    id: 2,
                    ename: 'banana',
                    cname: '香蕉'
                }, {
                    id: 3,
                    ename: 'orange',
                    cname: '橘子'
                }]
            },
        });
    </script>
</body>
4. v-if和v-for结合使用
  • v-for遍历对象

    <div v-for='(value,key,index) in object'></div>
    
  • v-if和v-for结合使用

    语法如下:

    <div v-if='value == 12' v-for='(value,key,index) in object'></div>
    

    示例代码如下:

    <body>
        <div id="app">
            <div v-if='value== "张三"' v-for='(value,key,index) in object'>{{value + '---' + key + '---' + index}}</div>
        </div>
        <script src="js/vue.min.js"></script>
        <script>
            /* 
                v-if和v-for结合使用
            */
            var vm = new Vue({
                el: '#app',
                data: {
                    object : {
                        name: '张三',
                        age: 19,
                        hobby: 'eat'
                    }
                }
            });
        </script>
    </body>