Vue学习笔记(一)数据绑定

╄→гoц情女王★ 提交于 2020-04-06 07:34:06

Vue学习笔记(一)数据绑定

一、初识Vue

1.MVVM模式

Model-View-View-Model模式是由经典的软件架构MVC衍生来的。当View(视图层)变化时,会自动更新ViewModel(视图模型),反之亦然。View和ViewModel之间通过双向绑定建立联系。

2.如何使用Vue.js

1)可直接通过script加载CDN文件

<!--自动识别最新稳定版本的Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

2)使用Vue单文件的形式配合webpack使用

二、数据绑定

1.实例与数据

Vue.js应用的创建很简单,通过构造函数Vue就可以创建一个Vue的根实例,并启动Vue应用:

<div id="app">
        {{info}}
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                info: 'hello world'
            }
        })
    </script>
  • 变量app代表Vue实例。
  • 选项el用于指定一个页面中已存在的DOM元素来挂载Vue实例,它可以是HTMLElement,也可以是CSS选择器。挂载成功后,我们可以通过app.$el来访问元素。Vue提供了很多常用的实例属性与方法都以$开头。
  • {{info}}插值,将数据显示出来

2.生命周期

  • created:实例创建完成后调用,此阶段完成了数据观测等,但尚未挂载,$el还不可用。需要初始化处理一些数据时会比较有用。
  • mounted:el挂载到实例上后调用,一般我们的第一个业务逻辑会在这里开始。
  • beforeDestroy:实例销毁之前调用,主要解绑一些使用addEventListener监听的事件等。

这些钩子与el和data类似,也是作为选项写入Vue实例内,并且钩子的this指向的是调用它的Vue实例。

<div id="app">
        {{info}}
    </div>    
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                info: 'hello world'
            },
            created: function() {
                console.log(this.info);
            },
            mounted: function() {
                console.log(this.$el);
            }
        })
    </script>

3.插值与表达式

“{{}}”是最基本的文本插值方法,它会自动将我们双向绑定的数据实时显示出来。例如上面的info,通过任何方法修改数据info,大括号的内容都会被实时替换。

v-html:如果有的时候想输出HTML,而不是将数据解释后的文本,可以使用它。例如下面代码:

<div id="app">
        {{info}}{{link}}
        <span v-html="link"></span>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                info: 'hello world',
                link: '<a href="#">超链接</a>'

            },
            created: function() {
                console.log(this.info);
            },
            mounted: function() {
                console.log(this.$el);
            }
        })
    </script>

link的内容将会被渲染成一个a标签,而不是纯文本。这里需要注意,如果将用户产生的内容使用v-html输出后,有可能导致XSS攻击。

在{{}}中,除了简单的绑定属性外,还可以使用Js表达式进行简单的运算。

{{number/10}}
{{isOK?'确定' : 'b取消'}}
{{text.split(',').reverse().join(',')}}

4.过滤器

Vue支持在{{}}插值的尾部添加一个管道符“(|)”对数据进行过滤,经常用于格式化文本,比如字母全部大写、货币千位使用逗号分隔等。过滤的规则是自定义的,通过给Vue实例添加选项filters来设置。

<div id="app1">
        <span>当前时间:{{date|formatDate}}</span>
    </div>
    <script>
        //在月份、日期、小时等于小于10时前面补0
        var padDate = function(value) {
            return value < 10 ? '0' + value : value;
        };
        var app1 = new Vue({
            el: '#app1',
            data: {
                date: new Date()
            },
            filters: {
                formatDate: function(value) {
                    //value是需要过滤的数据
                    var date = new Date(value);
                    var year = date.getFullYear();
                    var month = padDate(date.getMonth() + 1);
                    var day = padDate(date.getDate());
                    var hours = padDate(date.getHours());
                    var minutes = padDate(date.getMinutes());
                    var seconds = padDate(date.getSeconds());
                    return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
                }
            },
            mounted: function() {
                var _this = this;
                this.timer = setInterval(function() {
                    _this.date = new Date(); //修改数据date
                })
            },
            beforeDestroy: function() {
                if (this.timer) {
                    clearInterval(this.timer);
                }
            }
        })

过滤器也可以串联,而且可以接收参数

{{message|filterA|filterB}} 串联

{{message|filterA('arg1','arg2')}} 接收参数

三、指令与事件

指令是Vue模板中最常用的一项功能,它带有前缀v-,比如v-if、v-html、v-pre等。指令的主要职责就是当其表达式的值改变时,相应地将某些行为应用到DOM上。

1.v-if:

<div id="app">
        <p v-if="isShow">显示这段文本</p>
    </div>

当数据isShow的值为true时,p元素会被插入,为false时则会被移除。数据驱动DOM是Vue的核心理念,所以不到万不得已时不要主动操作DOM,你只需要维护好数据,DOM的事Vue会帮你优雅的处理。

2.v-bind

v-bind的基本用途是动态更新HTML元素上的属性。如id、class等。

3.v-on

它用来绑定事件监听器。

四、语法糖

是指在不影响功能的情况下,添加某种方法实现同样的效果,从而方便程序开发。

v-bind可以省略v-bind,用冒号":"代替。

v-on可以活力v-on,可以直接用“@”来缩写。

五、计算属性

模板内的表达式常用于简单的运算,当其过长或逻辑复杂时,会难以维护,计算属性就是解决这一问题的。

所有的计算属性都以函数的形式写在Vue实例内的computed选项内,最终返回计算后的结果。

//输出九九乘法表
<div id="app">
        <p>{{result}}</p>
        <p v-html='computedResult'></p>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                result: '输出九九乘法表'
            },
            computed: {
                computedResult: function() {
                    var str = '';
                    for (var i = 1; i < 9; i++) {
                        for (var j = 1; j <= i; j++) {
                            str = str + i + "*" + j + "=" + i * j + "&nbsp;&nbsp;&nbsp;&nbsp;";
                        }
                        str = str + "</br>";
                    }
                    return str;
                }
            }
        })
    </script>

在一个计算属性里可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果就可以。计算属性还可以依赖多个Vue实例的数据,只要其中任何一数据变化,计算属性就会重新执行,视图也会更新。

1.购物车总值计算实例

以下实例,计算购物车中的总价

<div id="app">
        总价:{{prices}}
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                goods1: [{
                    name: "三星32显示器",
                    price: 1480,
                    count: 2
                }, {
                    name: "飞利浦32显示器",
                    price: 1680,
                    count: 2
                }],
                goods2: [{
                    name: "AOC32曲面显示器",
                    price: 1250,
                    count: 2
                }, {
                    name: "长城曲面显示器",
                    price: 1150,
                    count: 2
                }]
            },
            computed: {
                prices: function() {
                    var prices = 0;
                    for (var i = 0; i < this.goods1.length; i++) {
                        prices = prices + this.goods1[i].price * this.goods1[i].count;
                    }
                    for (var i = 0; i < this.goods2.length; i++) {
                        prices = prices + this.goods2[i].price * this.goods2[i].count;
                    }
                    return prices;
                }
            }
        })
    </script>

每一个计算属性都包含一个getter和一个setter,上面的示例都是计算属性的默认用法,只是利用了getter来读取。当需要时,也可以提供一个setter函数,当手动修改计算属性的值就像修改一个普通数据那样时,就会触发setter函数,执行一些自定义的操作。

绝大多数情况下,我们只会用默认的getter方法来读取一个计算属性,在业务中很少用到setter,所以在声明一个计算属性时,可以直接使用默认的写法,不必将getter和setter都声明。

计算属性除了上述简单的文本插值外,还经常用于动态地设置元素的样式名称class和内联样式style。当使用组件时,计算属性也经常用来动态传递props。

计算属性一是可以依赖其他计算属性,二是不仅可以依赖当前Vue实例的数据,还可以依赖其他实例的数据。

2.计算属性缓存

上面的例子中,使用methods的方法也可以实现相同的效果,但它与计算属性还是不同的。

计算属性是基于它的缓存的。一个计算属性所依赖的数据发生变化时,它才会重新取值,所以它所依赖的数据不发生变化,计算属性也就不更新。

六、v-bind及class与style绑定

v-bind的主要用法是动态更新HTML元素上的属性。

1.绑定class的几种方式

  • 对象语法
<div class="" id="app1">
        <button @click="changeClass">切换class</button>
        <p :class="{'active':isActive}">这是一段文本内容</p>
    </div>

    <script>
        var app1 = new Vue({
            el: '#app1',
            data: {
                isActive: true,
            },
            methods: {
                changeClass: function() {
                    if (this.isActive) {
                        this.isActive = false;
                    } else {
                        this.isActive = true;
                    }
                }
            }
        })
    </script>

对象中也可以传入多个属性,来动态切换class。另外,:class可以与普通class共存。

<div class="static" :class="{'active':isActive,'error':isError}"></div>

当:class的表达式过长或逻辑复杂时,还可以绑定一个计算属性,一般当条件多于两个时,都可以使用data或computed。除了计算属性,你也可以直接绑定一个Object类型的数据,或者使用类似计算属性的methods。

  • 数组语法

当需要应用多个class时,可以使用数组语法,给:class绑定一个数组,应用一个class列表;

< p   :class = "[isActive,isArror]" > 数组语法 </ p >

也可以使用三元表达式来根据条件切换class

<p:class="[{'active':isActive},isArror]"></p>

  • 在组件上使用

如果直接在自定义组件上使用class或:class,样式规则会直接应用到这个组件的根元素上。

2.绑定内联样式

使用v-bind:style可以给元素绑定内联样式,方法与:class类似,也有对象语法和数组语法,

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!