Vue学习笔记day2

Vue复习笔记day2

1.插值操作:mustache语法

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- mustache语法中,不仅仅可以写变量,还可以写简单表达式,下面是一些简单例子 -->
        <h2>{{message}}</h2>
        <h2>{{firstname + ' ' + lastname}}</h2>
        <h2>{{firstname}} {{lastname}}</h2>
        <div>{{counter * 3}}</div>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: 'abc',
                firstname: 'Kobe',
                lastname: 'Bryant',
                counter: 10
            }
        })
    </script>
</body>

</html>

2.插值操作:其他指令应用

本小节重点:

1.v-once指令:可以使得此信息只显示初始化,不会改变;

2.v-html指令:该指令后面往往会跟上一个String类型,会将String的html解析出来。可以理解为提示接收信息格式,使得轻松解析服务器返回的内容(html内容),例如url等等;

3.v-text指令:与mustache语法功能相同,但是有缺陷,无法完成字符串拼接;

4.v-pre指令:用于跳过这个元素和其子元素的编译过程,原封不动展示其内部内容;

5.v-cloak指令:可以看做一个标志,具体使用详见代码(用处不大)。

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        [v-cloak] {
            display: none
        } 
    </style>
</head>

<body>
    <!-- 在vue解析之前,有一个v-cloak属性 -->
    <!-- 在vue解析之后,没有一个v-cloak属性 -->
    <div id="app" v-cloak>
        <!-- v-once指令可以使得此信息只显示初始化,不会改变 -->
        <h2 v-once>{{message}}</h2>
        <h2 v-html='url'></h2>
        <!-- 注意v-text指令缺陷:无法拼接是字符串
        即:
        <h2 v-text="message"></h2>与<h2 v-text="message">多余文本信息</h2>没有区别,被v-text指定内容覆盖
        -->
        <h2 v-text="message"></h2>
        <!-- 如果想要展示的文本信息为{{message}},可以采用v-pre指令 -->
        <h2 v-pre>{{message}}</h2>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: 'abc',
                url: '<a href = "http://www.baidu.com">百度一下</a>'
            }
        })
    </script>
</body>

</html>

3.v-bind基本使用

前面说了内容的动态绑定,即mustache语法,这小节讨论属性的动态绑定。

  • 动态绑定a元素的href属性
  • 动态绑定img元素的src属性

这也就是v-bind的作用,动态绑定属性。

v-bind语法糖:v-bind: <=> :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- 原来指定src的方法 -->
        <!-- <img src="http://masteryhh.oss-cn-beijing.aliyuncs.com/blog_img/a.jpg" alt=""> -->
        <!-- 如何改进呢?当然,这里肯定不可以用mustache语法,因为该语法用于内容而不是属性 -->
        <img v-bind:src="imgURL" alt="">
        <a v-bind:href="aHref">百度一下</a>
        <!-- v-bind语法糖:v-bind: <=> : -->
        <!-- 即v-bind:src="http://masteryhh.oss-cn-beijing.aliyuncs.com/blog_img/a.jpg"
        等价于:src="http://masteryhh.oss-cn-beijing.aliyuncs.com/blog_img/a.jpg"
         -->
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: 'abc',
                imgURL: 'http://masteryhh.oss-cn-beijing.aliyuncs.com/blog_img/a.jpg',
                aHref: 'http://www.baidu.com'
            }
        })
    </script>
</body>

</html>

4.v-bind动态绑定class

很多时候,我们希望动态地来切换class,比如

当数据处于某个状态时,字体显示为红色

当数据处于另外一个状态时,字体显示为黑色

v-bind一般要么绑定对象语法,要么绑定数组语法,基本很少纯字符串

此处演示对象语法


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .active {
            color: greenyellow
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- 这里的大括号代表里面是对象,所以可以放键值对,好处是将data中的键值对作为控制器引入 -->
        <!-- <h2 :class="{active: true}">{{message}}</h2> -->
        <!-- 并且使用v-bind动态绑定类并不影响该标签对象在前面添加必须有的类 实例如下-->
        <!-- <h2 class="title" :class="{active: isActive, line: isLine}">{{message}}</h2> -->
        <!-- 如果觉得此处键值对太长了可以通过定义methods方法来获取,此处只填写定义的被调用的方法名即可 -->
        <h2 :class="{active: isActive, line: isLine}">{{message}}</h2>
        <h2 :class="getClasses()">{{message}}</h2>
        <button v-on:click="btnClick">颜色反转</button>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '这里是测试文本',
                isActive: true,
                isLine: true
            },
            methods: {
                btnClick: function () {
                    this.isActive = !this.isActive
                },
                getClasses: function () {
                    return {active: this.isActive, line: this.isLine}
                }
            }
        })
    </script>
</body>

</html>

此处演示数组语法


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .active {
            color: greenyellow
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- 这里的大括号代表里面是对象,所以可以放键值对,好处是将data中的键值对作为控制器引入 -->
        <!-- <h2 :class="{active: true}">{{message}}</h2> -->
        <!-- 并且使用v-bind动态绑定类并不影响该标签对象在前面添加必须有的类 实例如下-->
        <!-- <h2 class="title" :class="{active: isActive, line: isLine}">{{message}}</h2> -->
        <!-- 如果觉得此处键值对太长了可以通过定义methods方法来获取,此处只填写定义的被调用的方法名即可 -->
        <h2 :class="{active: isActive, line: isLine}">{{message}}</h2>
        <h2 :class="getClasses()">{{message}}</h2>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '这里是测试文本',
                isActive: true,
                isLine: true,
                array: 'aaa',
                array1: 'bbb'
            },
            methods: {
                getClasses: function () {
                    return [this.array, this.array1]
                }
            }
        })
    </script>
</body>

</html>

5.v-bind动态绑定style

和动态绑定class基本没有区别

对象语法


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- <h2 :style="{key(属性名): value(属性值)}">{{message}}</h2> -->
        <!-- 此处50px必须加上单引号,不然会被当做变量处理,然而对象里面没有这个属性,故会报错 -->
        <h2 :style="{fontSize: '50px'}">{{message}}</h2>
        <h2 :style="{fontSize: fSize}">{{message}}</h2>
        <h2 :style="{fontSize: f2Size + 'px'}">{{message}}</h2>
        <h2 :style="{fontSize: fSize, color: fColor}">{{message}}</h2>
        <!-- 同v-bind绑定class,如果觉得太长了也可以定义methods方法获取键值对 -->
        <h2 :style="getStyles()">{{message}}</h2>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '测试文本',
                fSize: '100px',
                f2Size: 100,
                fColor: 'red'
            },
            methods: {
                getStyles: function () {
                    return {fontSize: this.fSize, color: this.fColor}
                }
            }
        })
    </script>
</body>
</html>

数组语法


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- <h2 :style="{key(属性名): value(属性值)}">{{message}}</h2> -->
        <!-- 此处50px必须加上单引号,不然会被当做变量处理,然而对象里面没有这个属性,故会报错 -->
        <h2 :style="{fontSize: '50px'}">{{message}}</h2>
        <h2 :style="{fontSize: fSize}">{{message}}</h2>
        <h2 :style="{fontSize: f2Size + 'px'}">{{message}}</h2>
        <h2 :style="{fontSize: fSize, color: fColor}">{{message}}</h2>
        <!-- 同v-bind绑定class,如果觉得太长了也可以定义methods方法获取键值对 -->
        <h2 :style="getStyles()">{{message}}</h2>
        <h2 :style="[baseStyle, baseStyle1]">{{message}}</h2>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '测试文本',
                fSize: '100px',
                f2Size: 100,
                fColor: 'red',
                baseStyle: {backroundColor: 'red'},
                baseStyle1: {color: 'greenyellow'}
            },
            methods: {
                getStyles: function () {
                    return {fontSize: this.fSize, color: this.fColor}
                }
            }
        })
    </script>
</body>
</html>

6.计算属性的基本及复杂使用

基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!--此时想要将firstName和lastName拼接在一起,方法很多 -->
        <!-- 方法一 -->
        <h2>{{firstName + ' ' + lastName}}</h2>
        <!-- 方法二 -->
        <h2>{{firstName}} {{lastName}}</h2>
        <!-- 方法三,采用methods方法 -->
        <h2>{{getFullName()}}</h2>
        <!-- 方法四 采用computed计算属性-->
        <h2>{{fullName}}</h2>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: 'abc',
                firstName: 'Kobe',
                lastName: 'Broyan'
            },
            // 计算属性
            computed: {
                fullName: function () {
                    return this.firstName + ' ' + this.lastName
                }
            },
            methods: {
                getFullName: function () {
                    return this.firstName + ' ' + this.lastName
                }
            }
        })
    </script>
</body>

</html>

复杂情况

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h2>{{totalPrice}}</h2>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                books: [
                    {name: 'Unix编程艺术', price: 100},
                    {name: 'Java编程思想', price: 120},
                    {name: '深入理解计算机系统', price: 140},
                    {name: '编译原理', price: 170},
                ]
            },
            // 计算属性
            computed: {
                // filter/map/reduce
                totalPrice: function () {
                    let result = 0;
                    //方法一
                    for (let i = 0; i < this.books.length; i++) {
                        result += this.books[i].price;
                    }
        
                    // 方法二
                    for (let i in this.books) {
                        result += this.books[i].price;
                    }
                    //方法三
                    for (let book of this.books) {
                        result += book.price;
                    }
                    return result;
                }
            }
        })
    </script>
</body>

</html>

7.计算属性的setter和getter

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h2>{{fullName}}</h2>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: 'abc',                
                firstName: 'Kobe',
                lastName: 'Broyan'
            },
            // 计算属性
            computed: {
                // fullName: function () {
                //     return this.firstName + ' ' + this.lastName
                // },
                // 实际上是通过getter方法实现的,将funName看成一个对象并求其属性值
                // 并且计算属性一般没有setter函数,因为大多是只读属性,防止外部篡改数据
                //也就是说上面其实就是把get省略之后的简单写法,下面是原始写法
                fullName: {
                    set: function(newValue) {
                        const names = newValue.split(' ');
                        this.firstName = names[0]; 
                        this.lastName = names[1]; 
                    },
                    get : function () {
                        return this.firstName + ' ' + this.lastName
                    }
                }
                
            }
        })
    </script>
</body>

</html>

8.computed与methods对比

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- 方法一 采用计算属性computed--推荐使用-->
        <h2>{{fullName}}</h2>
        <!-- 方法二 过于繁琐,不建议使用-->
        <h2>{{firstName + ' ' + lastName}}</h2>
        <!-- 方法三 采用methods方法 -->
        <h2>{{getFullName()}}</h2>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: 'abc',                
                firstName: 'Kobe',
                lastName: 'Broyan'
            },
            // 计算属性
            computed: {
                fullName: function () {
                    console.log('fullName调用');
                    return this.firstName + ' ' + this.lastName
                }
            }, 
            //methods方法定义
            methods: {
                getFullName: function () {
                    console.log('getFullName调用');
                    return this.firstName + ' ' + this.lastName
                }
            }
        })
    </script>
</body>

</html>

根据代码定义,如果由若干个甚至更大数量级要显示,可以看到computed始终只调用了一次,而methods调用次数与调用变量个数相同。

当然,原因是因为computed内部有缓存,只要值没变。重复打印是不会多次调用的。特别是有循环时,computed大大提高效率

9.块级作用域:let和var

JavaScript中var是有缺陷的,ES5中if,for都没有作用域,这意味着定义的变量全局可用,随时可能被篡改。所以必须借助function作用域限制。所以在ES6中加入let,而let在if 和let是有作用域的,避免此种风险。

简单来说,ES5中var是没有块级作用域的;ES6中let是有块级作用域的。

10.const的使用和注意事项

建议:在ES6开发中,优先使用const,只有需要改变某一标识符时才使用let

注意:const只能修饰常量;并且必须初始化赋值。常量的含义是指指向的对象不能修改,但是内部属性是可以进行修改的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="../vue.min.js"></script>
    <script>
        cont obj = {
			name: 'Kobe',
			age: 40
		}
		obj.age = 45;
    </script>
</body>
</html>

11.对象字面量的增强写法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // ES5的写法
        const obj = {
            name: 'Hawking',
            age: 40
        }
        // ES6的写法
        const obj = {
            name,
            age
        }
        // 函数的增强写法
        // ES5的写法
        const obj = {
            run: function () {
                console.log("奔跑")
            }
        }
        // ES6写法
        const obj = {
            run() {
                console.log("奔跑")
            }
        }
    </script>
</body>
</html>

12.事件监听/v-on

v-on的语法糖

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h2>{{counter}}</h2>
        <button v-on:click="increment">+</button>
        <button v-on:click="decrement">-</button>
        <!-- 语法糖如下 -->
        <button @click="increment">+</button>
        <button @click="decrement">-</button>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: 'abc',
                counter: 0
            },
            methods: {
                increment() {
                    this.counter++
                },
                decrement() {
                    this.counter--
                }
            }
        })
    </script>
</body>
</html>

v-on的参数传递问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h2>{{counter}}</h2>
        <!-- 事件调用的方法没有参数 可省略函数括号-->
        <button @click="btnclick1()">按钮一</button>
        <button @click="btnclick1">按钮二</button>
        <!-- 在事件定义时,写方法时省略了括号,但是方法本身需要传入参数,
        这个时候vue会默认将浏览器产生的事件event传入方法 -->
        <button @click="btnclick2">按钮三</button>
        <!-- 方法既需要event又需要额外参数,可采用$event -->
        <button @click="btnclick3(abc, $event)">按钮四</button>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: 'abc',
                counter: 0,
                abc: 12324423423423542
            },
            methods: {
                btnclick1() {
                    console.log("执行...")
                },
                btnclick2(event) {
                    console.log(event)
                },
                btnclick3(abc,event) {
                    console.log(abc, event)
                }
            }
        })
    </script>
</body>
</html>

v-on修饰符的使用

  • .stop 调用event.stopPropagation()
  • .prevent 调用event.preventDefault()
  • .{keyCode | keyAlias} 只当事件是从特定键触发时才触发回调
  • .once 只触发一次回调
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- 1.  .stop修饰符的使用 -->
        <div @click="divClick">
            aaaaa
            <button @click.stop="btnClick">按钮</button>
        </div>
        <!-- 2.  .prevent修饰符的使用 -->
        <br>
        <form action="baidu">
            <input type="submit" value="提交" @click.prevent="submitClick">
        </form>
        <!-- 3.  监听某个键盘的键帽 -->
        <input type="text" @keyUp.enter="keyUp">
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: 'abc',
                counter: 0,
            },
            methods: {
                btnClick() {
                    console.log("btnClick")
                },
                divClick() {
                    console.log("divClick")
                },
                submitClick() {
                    console.log("submitClick")
                },
                keyUp() {
                    console.log("kyeUp")
                }
            }
        })
    </script>
</body>
</html>

13.v-if,v-else-if和v-else的使用

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h2 v-if="isShow">
            <div>ABC</div>
            <div>ABC</div>
            <div>ABC</div>
            <div>ABC</div>
            <div>ABC</div>
            {{message}}
        </h2>
        <h2 v-else>当isShow为false时显示</h2>
        <h3 v-if="score >= 90">优秀</h3>
        <h3 v-else-if="score >= 80">良好</h3>
        <h3 v-else-if="score >= 60">及格</h3>
        <h3 v-else>不及格</h3>
        <h2>
            {{result}}
        </h2>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '测试字体',
                isShow: true,
                score: 99
            },
            // 较为复杂的逻辑判断在计算属性里边实现比较好
            computed: {
                result() {
                    let showMessage = ' ';
                    if (this.score >= 90) {
                        return showMessage = '优秀'
                    }
                    else if (this.score >= 80) {
                        return showMessage = '良好'
                    }
                    else if (this.score >= 60) {
                        return showMessage = '及格'
                    }
                    else {
                        return showMessage = '不及格'
                    }
                }
            }
        })
    </script>
</body>

</html>

14.登录切换案例

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <span v-if="isUser">
            <label for="username">用户账户</label>
            <input type="text" placeholder="用户账户" id="username">
        </span>
        <span v-else>
            <label for="email">用户邮箱</label>
            <input type="text" placeholder="用户邮箱" id="email">
        </span>
        <button @click="isUser = !isUser">切换类型</button>
    </div>
    <script src="../vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '测试字体',
                isUser: true
            }

        })
    </script>
</body>

</html>

问题

如果在有输入的情况下,input未删除的内容在切换类型之后仍然还在。

答:这是因为vue底层原理出于性能考虑,为了复用未删除的输入和原先的布局。

解决方案 :给对应的input添加key,并且保证key各不相同。具体代码实现如下

 <input type="text" placeholder="用户账户" id="username" key="username">

 <input type="text" placeholder="用户邮箱" id="email" key="email">
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值