Vue.js教程(二)

导读:本篇文章讲解 Vue.js教程(二),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

目录

Vue中的事件属性methods

事件绑定指令:v-on

事件传参

常用的事件修饰符

阻止默认事件

阻止冒泡事件

一次事件

 键盘事件

Vue中的计算属性computed

Vue中的监视属性watch

watch的深度监听

计算属性和监听属性的区别

Vue中class样式的动态绑定

1:字符串方式

2:对象方式

3:数组方式

Vue中style样式的动态绑定

Vue中的条件渲染

1:v-if…v-else-if…v-else

2:v-show

v-if 和 v-show 区别

Vue中的列表渲染

指令:v-for

Vue中的列表筛选

Vue中的列表排序

Vue中data数据更新

对象动态更新数据

数组动态更新数据

Vue中的表单数据绑定

指令v-text、v-html

1:v-text

2:v-html


Vue中的事件属性methods

  • 事件绑定指令:v-on

// 不需要传参的时候,函数后面可以省略()

<button v-on:click=”showMessge”>点击</button>
<button @click=”showMessge”>点击</button>                // 简写

methods: {}                 // 对于函数,vue提供了methods块,函数写在此块中

<script src="../vue.js"></script>
<body>
    <div id="app">
        <span v-on:click="fn">点击</span>
    </div>
    <script>
        new Vue({
            el: "#app",
            methods: {              
                fn() {    // 函数不用加 function 关键字
                    alert("点击了");
                }
            }
        })
    </script>
</body>
  • 事件传参

<button @click=”showMessage(‘点击了’)”>点击</button>
methods: {              
    showMessage(text) {
        alert(text);
    }
}

<script src="../vue.js"></script>
<body>
    <div id="app">
        <span v-on:click="fn('点击了')">点击</span>
    </div>
    <script>
        new Vue({
            el: "#app",
            methods: {              
                fn(text) {
                    alert(text);
                }
            }
        })
    </script>
</body>
  • 注意
  • methods中配置的函数不要使⽤箭头函数,因为箭头函数没有this指向
  • event.target.innerText能拿到标签的值,但是调⽤不加()或者加($event),这句话怎么理解呢?如下:
<script src="../vue.js"></script>
<body>
    <div id="app">
        <span v-on:click="fn">点击</span>
    </div>
    <script>
        new Vue({
            el: "#app",
            methods: {              
                fn(envet) {
                    alert(envet.target.innerText);  // 获取 span 标签文本内容
                }
            }
        })
    </script>
</body>

常用的事件修饰符

  • 阻止默认事件

// js中的阻⽌默认事件

e.preventDefault()

// vue

<a href=”https://www.baidu.com” @click.prevent=”fn”>点击</a>

<script src="../vue.js"></script>
<body>
    <div id="app">
        <a href="https://www.baidu.com" @click.prevent="fn">点击</a>
    </div>
    <script>
        new Vue({
            el: "#app",
            methods: {              
                fn() {
                    alert("@click.prevent阻止了href跳转的默认事件");
                }
            }
        })
    </script>
</body>
  • 阻止冒泡事件

// js中的阻⽌事件冒泡
e.stopPropagation()
// vue
@click.stop=”showMessge”
// 阻⽌冒泡、默认事件连⽤
@click.stop.prevent=”showMessge”

<script src="../vue.js"></script>
<body>
    <div id="app">
        <div @click="fn">
            <div @click="fn">
                <div @click.stop="fn" >点击</div>
            </div>
        </div>
    </div>
    <script>
        new Vue({
            el: "#app",
            methods: {              
                fn() {
                    alert("没有阻止会弹出3次,阻止冒泡会阻止向上事件继续执行");
                }
            }
        })
    </script>
</body>
  • 一次事件

<button @click.once=”fn”>点击</button>

<script src="../vue.js"></script>
<body>
    <div id="app">
        <div @click.once="fn">点击</div>
    </div>
    <script>
        new Vue({
            el: "#app",
            methods: {              
                fn() {
                    alert("事件只执行一次,再次点击不会执行");
                }
            }
        })
    </script>
</body>
  •  键盘事件

@keyup                 // 键盘输入事件

@keyup.enter        // 键盘回车事件

<script src="../vue.js"></script>
<body>
    <div id="app">
        <input type="text" @keyup="change" @keyup.enter="confirm">
    </div>
    <script>
        new Vue({
            el: "#app",
            methods: {              
                change() {
                    console.log("键盘输入了");
                },
                confirm() {
                    console.log("回车了");
                }
            }
        })
    </script>
</body>

Vue中的计算属性computed

vue给计算属性提供了computed

computed和普通方法属性methods有什么不同?

有缓存的机制,可以复⽤,效率高调试方便

new Vue({
    el: “#app”,
    computed: {
    }
})

<script src="../vue.js"></script>
<body>
    <div id="app">
        <input type="text" v-model:value="fullName">
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                firstName: "张",
                lastName: "三"
            },
            computed: {         // 计算块,当插值语法{{}}计算块里的函数的时候不要加(), 示例:{{fullName}}
                fullName: {     // 标签双向绑定这个函数
                    // Object.defineProperty() 代理实现
                    get() {
                        return this.firstName + "-" + this.lastName;
                    }, 
                    set(value) {
                        this.firstName = value.split('-')[0];
                        this.lastName = value.split('-')[1];
                    }
                }
            }
        })
    </script>
</body>

Vue中的监视属性watch

<script src="../vue.js"></script>
<body>
    <div id="app">
        <button @click="change">改变属性</button>
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                flag: true          // 定义一个属性
            },
            watch: {
                flag: {             // 要监听的属性
                    handler() {     // 当监听的属性发生了改变时,执行 vue 的 handler 函数
                        console.log("属性改变了, flag=", this.flag);
                    }
                }
            },
            methods: {
                change() {
                    this.flag = !this.flag;
                }
            }
        })
    </script>
</body>
  • 被监视的属性发⽣改变时,调用handler回调函数,执⾏相关操作
  • 配置 immediate:true 实现页面初始化时调用
  • 监视的属性须存在才能进⾏监视

watch的深度监听

deep:true        // 使用深度监听才可以监听对象,不开启只能监听简单的数据类型

 监听对象中的属性

<script src="../vue.js"></script>
<body>
    <div id="app">
        <button @click="person.age++">长大一岁</button>
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                person: {
                    name: "张三",
                    age: 18
                }
            },
            watch: {
                'person.age': {                 
                    handler() {         
                        console.log("年龄变大了, age=", this.person.age);
                    }
                }
            }
        })
    </script>
</body>

使用深度监听

<script src="../vue.js"></script>
<body>
    <div id="app">
        <button @click="person.age++">长大一岁</button>
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                person: {
                    name: "张三",
                    age: 18
                }
            },
            watch: {
                person: {
                    deep: true,     // 使用深度监听,可以监听整个对象
                    handler() {
                        console.log("年龄变大了, age=", this.person.age);
                    }
                }
            }
        })
    </script>
</body>

计算属性和监听属性的区别

  • 监视属性是命令式且重复的
  • 通过计算属性实现更加简介明了
  • 两者都能实现的,优先选择使⽤computed
  • watch能实现异步调⽤(执行调用后台接口),computed不能

Vue中class样式的动态绑定

1:字符串方式

        使用场景:样式类型不确定时         //字符串使⽤的是vue实例data中的已有属性

<div v-bind:class=”bg_red”>123</div>

<div :class=”bg_red”>123</div>                // 简写

<style>
    .bg {
        background: red;
    }
</style>
<script src="../vue.js"></script>
<body>
    <div id="app">
        <div v-bind:class="bg_red">123</div>
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                bg_red: "bg"
            }
        });
    </script>
</body>

2:对象方式

        使用场景:样式个数、类名确定,通过Boolean动态展示与否

<style>
    .bg {
        background: red;
    }
    .fs {
        font-size: 30px;
    }
</style>
<script src="../vue.js"></script>
<body>
    <div id="app">
        <div :class="obj">123</div>
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                obj: {
                    bg: true,
                    fs: true
                }
            }
        });
    </script>
</body>

Vue.js教程(二)

3:数组方式

        使用场景:需要绑定的样式个数不确定,类名也不确定

<style>
    .bg {
        background: red;
    }
    .fs {
        font-size: 30px;
    }
</style>
<script src="../vue.js"></script>
<body>
    <div id="app">
        <div :class="list">123</div>
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                list: ['bg', 'fs']
            }
        });
    </script>
</body>

数组里使用三元表达式

<style>
    .bg {
        background: red;
    }
    .fs {
        font-size: 30px;
    }
</style>
<script src="../vue.js"></script>
<body>
    <div id="app">
        <div :class="[flag?a:'', b]">123</div>
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                flag: false,
                a: 'bg',
                b: 'fs'
            }
        });
    </script>
</body>

Vue中style样式的动态绑定

// 对象中的样式属性为驼峰式,值为字符串

<div v-bind:style=”{background:’red’}”>123</div> 

<div :style=”{background:’red’}”>123</div>                // 简写

<div id="app" :style="obj">123</div>
<script>
    new Vue({
        el: "#app",
        data: {
            obj: { background: 'red' }
        }
    });
</script>

Vue中的条件渲染

1:v-if…v-else-if…v-else

<script src="../vue.js"></script>
<body>
    <div id="app">
        <button @click="change">切换</button>
        <p v-if="dice===1">Java</p>
        <p v-else-if="dice===2">Vue</p>
        <p v-else-if="dice===3">C++</p>
        <p v-else="dice">go</p>
    </div>
    <script>
        Vue.config.productionTip = false;
        const app = new Vue({
            el: '#app',
            data: {
                dice: ""
            },
            methods: {
                change() {
                    this.dice = Math.floor(Math.random() * 4)
                    console.log(this.dice);
                }
            }
        })
    </script>
</body>

特点:

  • 语法和原⽣js的 if…else if…else ⼀样
  • 不展示时直接移除DOM元素,适合切换频率低的场景
  • v-if 、 v-else-if 、 v-else 要连⽤

2:v-show

<p v-show=”dice===1″>Java</p>

<p v-show=”dice===2″>Vue</p>

v-if 和 v-show 区别

  • v-if 有更高的切换开销(因为dom不存在,切换的时候要加载dom),v-show 有更高的初始渲染开销(因为dom存在,渲染的时候dom较多)。
  • 如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好

Vue中的列表渲染

指令:v-for

        定义:用 v-for 指令基于一个数组来渲染一个列表。 v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,item 则是被迭代的数组元素的别名

        语法:

        <div v-for=”item in items”>{{item}}</div>        // items是data中定义的变量

        遍历数组

<script src="../vue.js"></script>
<body>
    <div id="app">
        <div v-for="item in list"> {{item.name}} - {{item.age}} </div>
        <!-- <div v-for="(item, index) in list"> {{item.name}} - {{item.age}} -{{index}} </div> 带下标的方式-->
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                list: [
                    {name:"张三", age:18},
                    {name:"李四", age:19},
                    {name:"王五", age:20}
                ]
            }
        })
    </script>
</body>

        遍历对象

<script src="../vue.js"></script>
<body>
    <div id="app">
        <div v-for="(value, key, index) in obj"> {{value}} - {{key}} - {{index}} </div>
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                obj: {name:"张三", age:18}
            }
        })
    </script>
</body>

        什么是key?

        为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一的 key。默认的以下标为key

        key的作用:

  • key 值使用数组的索引index,或者不加,在数组元素顺序打乱时,会产生不必要的DOM更新以及界面效果出问题 
  • key 主要用在 Vue 虚拟 DOM(类似 js 对象格式的数据) 的 Diff 算法,新旧虚拟 DOM 对比,复用不变的旧节点,渲染改变的节点,提高渲染速度

Vue中的列表筛选

方式一:watch

<script src="../vue.js"></script>
<body>
    <div id="app">
        <input type="text" v-model="inputValue">
        <div v-for="item in newList"> {{item.name}} - {{item.age}} </div>
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                inputValue: "",
                list: [
                    { name: "张三", age: 18},
                    { name: "李四", age: 19},
                    { name: "王五", age: 20}
                ],
                newList: [] // 定义一个新的数组,防止旧数组的数据被改变
            },
            watch: {
                inputValue: {           // 监听input输入框被改变
                    immediate: true,    // 初始化执行
                    handler(val) {      // 如果input被改变执行handler, val是输入框的值
                        this.newList = this.list.filter((i) =>{
                            return i.name.indexOf(val) !== -1;
                        });
                    }
                }
            }
        })
    </script>
</body>

方式二:computed

<script src="../vue.js"></script>
<body>
    <div id="app">
        <input type="text" v-model="inputValue">
        <div v-for="item in newList"> {{item.name}} - {{item.age}} </div>
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                inputValue: "",
                list: [
                    { name: "张三", age: 18 },
                    { name: "李四", age: 19 },
                    { name: "王五", age: 20 }
                ],
            },
            computed: {
                newList: {
                    get() {
                        return this.newList = this.list.filter((i) => {
                            return i.name.indexOf(this.inputValue) !== -1;
                        });
                    },
                    set() { }
                }
            }
        })
    </script>
</body>

Vue中的列表排序

<script src="../vue.js"></script>
<body>
    <div id="app">
        <input type="text" v-model="inputValue">
        <button @click="keyWord=1">升序</button>
        <button @click="keyWord=2">降序</button>
        <button @click="keyWord=0">原顺序</button>
        <div v-for="item in newList"> {{item.name}} - {{item.age}} </div>
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                inputValue: "",
                keyWord: 0,
                list: [
                    { name: "张三", age: 19 },
                    { name: "李四", age: 18 },
                    { name: "王五", age: 20 }
                ]
            },
            computed: {
                newList() {
                    const arr = this.list.filter((i) => {
                        return i.name.indexOf(this.inputValue) !== -1;
                    });
                    if (this.keyWord) {
                        arr.sort((a1, a2) => {
                            return this.keyWord === 1
                                ? a1.age - a2.age
                                : a2.age - a1.age;
                        });
                    }
                    return arr;
                },
            }
        })
    </script>
</body>

Vue中data数据更新

对象动态更新数据

需求:给obj对象里动态添加一个属性age=18

data: {

        obj: { name: “张三” }      

}

实现方式:

使用 Vue.set() 或者 this.$set

注意:this.$set不能给vue实例的根数据对象(data)添加属性

<script src="../vue.js"></script>
<body>
    <div id="app">
        <div>{{obj.name}}</div>
        <div>{{obj.age}}</div>
        <button @click="add">add</button>
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                obj: { name: "张三" }
            },
            methods: {
                add() {
                    // this.obj.age=18              // 错误的实现 因为没有被vue代理get/set方法,而且不是响应式的(渲染页面)
                    // Vue.set(this.obj, 'age', 18);
                    this.$set(this.obj, 'age', 18);
                }
            }
        })
    </script>
</body>

数组动态更新数据

vue封装了数组方法用于更新数组数据

  • push()                // 向数组的末尾添加新元素,可以添加一个或多个元素
  • pop()                  // 删除数组的最后一项,并返回删除的元素
  • shift()                 // 删除数组的第一项,并返回第一个元素的值
  • unshift()             // 向数组首位添加新元素,可以添加一个或多个并返回新的长度
  • splice()              // 对数组进行增删改
  • sort()                 // 对数组的元素进行排序
  • reverse()           // 对数组进行倒序

Vue中的表单数据绑定

<script src="../vue.js"></script>
<body>
    <div id="app">
        <form v-on:submit.prevent="submit">
            <!-- <form @submit.prevent="submit">  prevent:阻止默认刷新事件-->
            账号:<input type="text" v-model="userInfo.username" /><br /><br />
            密码:<input type="password" v-model="userInfo.password" /><br /><br />
            手机号:<input type="number" v-model.number="userInfo.phone" /><br /><br />
            性别:男<input type="radio" name="sex" value="male" v-model="userInfo.sex" />
            女<input type="radio" name="sex" value="female" v-model="userInfo.sex" /><br /><br />
            方向:
            前端<input type="checkbox" value="front" v-model="userInfo.direction" />
            后端<input type="checkbox" value="back" v-model="userInfo.direction" />
            测试<input type="checkbox" value="test" v-model="userInfo.direction" /><br /><br />
            地区:
            <select v-model="userInfo.city">
                <option value="">请选择地区</option>
                <option value="beijing">北京</option>
                <option value="shanghai">上海</option>
                <option value="guangzhou">广州</option>
                <option value="shenzhen">深圳</option>
            </select><br /><br />
            备注:<textarea v-model="userInfo.remarks"></textarea><br /><br />
            <input type="checkbox" v-model="userInfo.agree" />请阅读并接受<a
                href="https://www.baidu.com">《用户协议》</a><br /><br />
            <button>提交</button>
        </form>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                userInfo: {
                    username: '',
                    password: '',
                    phone: '',
                    sex: '',
                    direction: [],
                    city: '',
                    remarks: '',
                    agree: '',
                },
            },
            methods: {
                submit() {
                    console.log(this.userInfo);
                },
            },
        });
    </script>
</body>

指令v-text、v-html

1:v-text

<div v-text=”message”></div>

        特点:

  • 在所在节点渲染文本内容
  • 会替换节点中所在的内容
<script src="../vue.js"></script>
<body>
    <div id="app">
        <div v-text="message"></div> <!-- 效果和 <div>{{message}}</div> 一样 -->
    </div>
    <script>
        Vue.config.productionTip=false;
        const app = new Vue({           
            el: '#app',
            data: {
                message: "Hello Vue"
            }
        })
    </script>
</body>

2:v-html

<div v-html=”message”></div>

特点:

  • 在所在节点渲染html结构的内容
  • 替换节点所在的所有内容

注意:

  • 在网站上动态渲染任意HTML是危险的,容易导致 XSS 攻击(注入恶意指令代码到网页)
  • 只在可信内容上使用 v-html ,不要用在用户提交的内容上
<script src="../vue.js"></script>
<body>
    <div id="app">
        <div v-html="message"></div>
    </div>
    <script>
        Vue.config.productionTip = false;
        const app = new Vue({
            el: '#app',
            data: {
                message: "<h1>Hello Vue</h1>"
            }
        })
    </script>
</body>

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/72521.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!