Vue 基础(1)

https://cn.vuejs.org/

学习测试环境可通过 CDN 地址引入 Vue(项目开发和线上环境一般使用 vue-cli、webpack 打包)

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

可使用构造函数创建 Vue 实例,即应用的入口:

<div id="app">
    {{msg}}
</div>
<script>
let app = new Vue({
    el: '#app',            // 指定页面中存在的 DOM 元素挂载
    data: {                // 声明需要双向绑定的数据(渲染到页面上)
        msg: 'Hello World!'
    }
})
console.log(app.$el)    // 访问 Vue 实例中的属性
console.log(app.msg)    // 访问 Vue 实例 data 域中的属性    
</script>

与 jQuery 对比

使用 jQuery 实现 todo-list:

<div>
    <ul id="ul-list"></ul>
</div>
<script type="text/javascript">
    var $txtTitle = $('#txt-title')
    $('#btn-submit').click(function () {
        var title = $txtTitle.val()
        if (!title) 
            return
        
        var $li = $('<li>' + title + '</li>')
        $('#ul-list').append($li)
        $txtTitle.val('')
    })
</script>

使用 Vue 实现 todo-list:

<div id="app">
    <div>
        <input v-model="title">
        <button v-on:click="add">submit</button>
    </div>
    <div>
        <ul>
            <li v-for="item in list">{{item}}</li>
        </ul>
    </div>
</div>
<script type="text/javascript">
    var data = {
        title: '',
        list: []
    }
    new Vue({
        el: '#app',
        data: data,
        methods: {
            add: function () {
                this.list.push(this.title)
                this.title = ''
            }
        }
    })
</script>
  • 区别在于:jQuery 以选择器获取并修改 DOM,Vue 以数据与 DOM 元素绑定、DOM 响应数据变化;
  • 即数据和视图分离(开放封闭原则)、以数据驱动视图(DOM 操作被封装)。

生命周期

一些生命周期钩子:

  1. created:实例创建完成后调用,完成了数据的观测等而尚未挂载($el还不可用)需要初始化处理一些数据时会用到;
  2. mounted:el挂载到实例上后调用,一般第一个业务逻辑会在这里开始。相当于$(document).ready()
  3. beforeDestroy:实例销毁之前调用。主要解绑一些使用 addEventListener 监听的事件等;
  4. ...

文本插值,表达式

使用双大括号( Mustache 语法){{value}}是最基本的文本插值方法,可以将双向绑定的数据实时显示,还可以使用单行 JS 表达式:

{{1 + 1}}
{{6 > 5? msg1: msg2}}
{{var a = 6}}            // 错误,这是多行表达式
{{if(6 > 3){}}}

实例:自动刷新的计时器

<div id="dateApp">
    {{date}}
</div>
<script>
let app = new Vue({
    el: '#dateApp',
    data: {
        date: new Date()
    },
    mounted: function() {
        let _this = this;    // this 表示 Vue 实例
        this.timer = setInterval(
            () => {
                _this.date = new Date();    // 每秒刷新1次
            }, 1000
        )
    },
    beforeDestroy: function() {
        if (this.timer) {
            clearInterval(this.timer)        // 如定时器存在即销毁
        }
    }
})
</script>

过滤器

{{}} 插值的尾部添加一或多个管道符 | 可对数据进行过滤,常用于格式化文本(字母全部大写、货币千位使用逗号分隔等):

以刚才的计时器为例

{{date | formatDate}}

在 Vue 实例中定义过滤器函数:

let plusDate = function(value) {
    return value < 10? '0' + value: value
}

let app = new Vue({
    el: '#dateApp',
    data: {
        date: new Date()
    },
    filters: {
        formatDate: function(value) {
            let date = new Date(value);        // 将字符串转换为date类型
            let year = date.getFullYear();
            let month = plusDate(date.getMonth() + 1);
            let day = plusDate(date.getDate());
            return `{year}-{month}-{day}`
        }
    }

过滤器中也可以传参数,如 {{date | formatDate(66,99)}}formatDate 的第一个和第二个参数,分别对应过滤器函数的第二个和
第三个参数(第一个参数为 date

计算属性

  1. 在一个计算属性里可以完成复杂的逻辑(运算、函数调用),最终返回一个结果;
  2. 计算属性还可以依赖多个 Vue 实例的数据,只要其中任一数据变化,计算属性就会重新执行并更新视图;
  3. 可以为计算属性(默认为 getter )定义 getter 和 setter 方法对属性进行读写;
  4. 缓存: 不管渲染不渲染,只要计算属性依赖的数据未发生变化,就永远不变(使用计算属性还是 methods 取决于是否需要缓存,当遍历大数组和做大量计算时应当使用计算属性做缓存)。

实例:计算购物车总价

<div id='app'>
{{price}}
</div>
<script>
let app = new Vue({
    el: '#app',            
    data: {                
        package1: [
            {name: 'x', price: 6999, count: 2},
            {name: 'y', price: 7999, count: 3}
        ],
        package2: [
            {name: 'x', price: 2999, count: 5},
            {name: 'y', price: 3999, count: 6}
        ]
    },
    computed: {
        price: function() {     
            let price = 0
            for (let i = 0; i < this.package1.length; i++) {
                price += this.package1[i].price * this.package1[i].count;
            }
            for (let j = 0; j < this.package2.length; j++) {
                price += this.package2[j].price * this.package2[j].count;
            }
            return price
        }
        // 计算属性直接跟一个 function,默认是 getter 方法,等价于
        /**
            price: {
                get: function() {
                    ...
                }
            }
        */
        // 也可以定义计算属性的 setter 方法,在外部可以调用:app.price = 'xxx'
        /**
            price: {
                set: function() {
                    ...
                }
            }
        */
    }
})
</script>

监听属性变化

除了使用计算属性 computed 以外,还可以使用 watch 监听单个属性的变化,两者对比:

computed:

<div id="app">
    firstName: <input type="text" v-model="firstName">
    lastName: <input type="text" v-model="lastName">
    <br>
    {{ fullName }}
</div>

<script>
    let app = new Vue({
        el: "#app",
        data: {
            firstName: "",
            lastName: ""
        },
        computed: {
            fullName() {
                return `${this.firstName} ${this.lastName}`
            }
        }
    })
</script>

watch:

<div id="app">
    firstName: <input type="text" v-model="firstName">
    lastName: <input type="text" v-model="lastName">
    <br>
    {{ fullName }}
</div>

<script>
    let app = new Vue({
        el: "#app",
        data: {
            firstName: "",
            lastName: "",
            fullName: ""
        },
        watch: {
            firstName(val) {
                this.fullName = `${val} ${this.lastName}`
            },
            lastName(val) {
                this.fullName = `${this.firstName} ${val}`
            }
        }
    })
</script>

基本指令

指令是 Vue 模板中最常用的一项功能,在 HTML 元素中带有前缀 v- 表示,有助于快速完成 DOM 操作,最常用的几个指令:

  1. v-­text:解析文本,和 {{ }} 作用一样
  2. v­-html:解析html元素
  3. v­-bind:动态更新元素上的属性,如 id、class 等,当数据变化时就会重新渲染。
  4. v-­on:绑定事件监听器
<div v-bind:class='className'></div>
<button v-on:dbclick='count'></button>

语法糖:指在不影响功能的情况下,添加某种简洁方法实现同样的效果,从而更加方便程序开发:

  1. v-bind =》 :
  2. v-on =》 @

v-bind

绑定值:

<div id='app'>
    <a v-bind:href="url">baidu</a>     <!-- 使用v-bind绑定活的属性 -->
    <img :src="imgUrl" alt="">
</div>

<script>
    new Vue({
        el: "#app",
        data: {
            url: "http://www.baidu.com"
            imgUrl: "https://www.baidu.com/img/bd_logo1.png?where=super"
        }
    })
</script>

绑定Class(绑定Style同理):

  1. v­bind:class 设置一个对象/数组可以动态地切换 class ,条件复杂时可以使用计算属性
  2. Vue 中驼峰式命名的大写字母都会被转换成中划线分隔的小写字母(建议统一写驼峰);
<div :class="{divStyle: isActive, borderStyle: isBorder}"></div>   <!-- isActive的值为 true 为激活,false 为不激活 -->
<div :class="[activeClass,errorClass]"></div>     <!-- 数组中的元素(变量)即为 class 类名 -->

v-cloak

解决初始化慢导致页面闪动的问题,一般与 display: none 结合使用

<style>
    [v-cloak]: {
        display: none
    }
</style>

v-cloak: <p v-cloak:>{{msg}}</p>    <!-- Vue 实例结束编译时移除,才会渲染msg -->

<script>
    while (true) {
        
    }

    new Vue({
        el: "#app",
        data: {
            msg: "Hello World!"
        }
    })

</script>

v-once

只渲染一次,后续修改不会重新渲染

条件渲染指令:v-if,v-else-if,v-else

  1. v-ifv-else-if后接等号和必须返回布尔值的条件,满足条件(结果为 True)才渲染,否则会从 DOM 中移除;
  2. v-if在渲染元素时出于效率考虑,会尽可能复用已有元素而非重新渲染,所以可能出错(只渲染变化的元素,实例:用户名与密码的 input 框);
  3. 上述问题的解决方法:为元素加上 key=keyName(使元素有差异而重新渲染)。

条件渲染指令:v-show

  1. v-if 类似,显现与否取决于布尔值;
  2. v-if 的区别在于 v-show 值为 false 时相当于 display: none,页面上仍然存在该元素。

列表渲染指令:v-for

数组遍历或枚举对象属性时可使用 v-for

<ul>
    <!-- arr: [{name: 'ywh'}, 'name': 'hwy'] -->
    <li v-for="item in arr">
        {{item.name}}
    </li>
    
    <li v-for="(item, index) in arr">
        {{index}}-{{i.name}}
    </li>
    
    <!-- obj: {name: 'ywh', 'age': 18, gender: 'male'} -->
    <li v-for="(value, key, index) in obj">
        {{value}}-{{key}}-{{index}}
    <li>
<ul>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容

  • 相关概念 混合开发和前后端分离 混合开发(服务器端渲染) 前后端分离后端提供接口,前端开发界面效果(专注于用户的交...
    他爱在黑暗中漫游阅读 2,775评论 4 45
  • 每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的: 实例生命周期钩子 每个 Vue 实例...
    Timmy小石匠阅读 1,372评论 0 11
  • vue概述 在官方文档中,有一句话对Vue的定位说的很明确:Vue.js 的核心是一个允许采用简洁的模板语法来声明...
    li4065阅读 7,191评论 0 25
  • Vue实例 每个 Vue.js 应用都是通过构造函数 Vue 创建一个 Vue 的根实例启动的。 每个 Vue 实...
    Miss_麦兜阅读 284评论 0 0
  • 1.安装 可以简单地在页面引入Vue.js作为独立版本,Vue即被注册为全局变量,可以在页面使用了。 如果希望搭建...
    Awey阅读 10,999评论 4 129