前端前端学习我爱编程

初识vue.js

2016-10-01  本文已影响2025人  恰皮

vue.js官网教程学习笔记和学习摘要

起步

安装

一个简单的方法,直接把一个vue.js引入你的HTML页面中,就像引入一个jq框架一样,首先你要下载js文档,然后用script标签把它引进去,然后在</body>之前写一个<script>标签,将你的vue.js代码写进去

vue.js官网 安装

点“开发版本”,然后就把一个“vue.js”文件下载下来了。

记住:1.引入vue.js文件 2.在<script>标签中写vue.js代码
运行效果:

运行图

概述

vue实例

构造器:

var vm = new Vue({
 // 选项
})
var vm = new Vue({
    data:{
      message:'hello'
   },
   method:{
      reverseMessage:function(){
            xxx;
      }
    }
})

扩展vue构造器:预定义选项,创建可复用的组件构造器

var MyComponent = Vue.extend({
 // 扩展选项
})// 所有的 `MyComponent` 实例都将以预定义的扩展选项被创建
var myComponentInstance = new MyComponent()

属性与方法

每个 Vue 实例都会代理其 data 对象里所有的属性:

var data = { a: 1 }
var vm = new Vue({ 
data: data//这里的data是被代理的属性
})
vm.a === data.a // -> true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // -> 2
// ... 反之亦然
data.a = 3
vm.a // -> 3

实例属性与方法

前缀:$

var data = { a: 1 }
var vm = new Vue({
  el: '#example',
  data: data
})

vm.$data === data // -> true
vm.$el === document.getElementById('example') // -> true

// $watch 是一个实例方法
vm.$watch('a', function (newVal, oldVal) {
  // 这个回调将在 `vm.a`  改变后调用
}

实例生命周期

Vue 实例在创建时有一系列初始化步骤——例如,它需要建立数据观察,编译模板,创建必要的数据绑定。在每个过程如果有相应的生命周期钩子,将会调用

var vm = new Vue({
  data: {
    a: 1
  },
  created: function () {//在实例创建后调用这个函数
    // `this` 指向 vm 实例
    console.log('a is: ' + this.a)
  }
})
// -> "a is: 1"

数据绑定语法

<span id="app">Message: {{ msg }}</span>
<script>
    var vm = new Vue() {
        el:'#app',//指定ID
        data:{
            msg:'hello'//替换ID为“app”的{{message}}
        }
})
</script>
<div id="item-{{ id }}"></div>

绑定表达式

双大括号内的文本称为绑定表达式,绑定表达式由一个简单的JavaScript表达式和可选的一个或者多个过滤器构成。

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

tip:每个绑定只能包含单个表达式

<!-- 这是一个语句,不是一个表达式: -->
{{ var a = 1 }}

<!-- 流程控制也不可以,可改用三元表达式 -->
{{ if (ok) { return message } }}
{{ message | capitalize }}//message的值通过过滤器capitalize,capitalize过滤器的作用是变换成大写,所以message的值通过过滤器capitalize的结果是返回大写化的值

tip:管道语法不是JavaScript语法,因此不能在表达式内使用过滤器,只能添加到表达式的后面。

过滤器可以串联:{{ message | filterA | filterB }

指令

前缀:“v-”
指令的值:“绑定表达式”(JavaScript表达式、过滤器)
指令的职责:表达式的值改变式把某些特殊行为应用到DOM上
eg:

<p v-if="greeting">Hello!</p>

这里,v-if是一个指令,指令的值是表达式“greeting”的值,如果值为真,就插入< p>元素,如果是假,就删除< p>元素。

<a v-bind:href="url"></a>//v-bind 指令用于响应地更新 HTML 特性,href是参数,它告诉v-bind指令将元素的href特性跟表达式url的值绑定
<a v-on:click="doSomething">//v-on 指令,它用于监听 DOM 事件
<a v-bind:href.literal="/a/b/c"></a>//.literal 修饰符告诉指令将它的值解析为一个字面字符串而不是一个表达式
<!-- 完整语法 -->
<a v-bind:href="url"></a>

<!-- 缩写 -->
<a :href="url"></a>

<!-- 完整语法 -->
<button v-bind:disabled="someDynamicCondition">Button</button>

<!-- 缩写 -->
<button :disabled="someDynamicCondition">Button</button>

v-on的缩写
eg:

<!-- 完整语法 -->
<a v-on:click="doSomething"></a>

<!-- 缩写 -->
<a @click="doSomething"></a>

计算属性

eg:

var vm = new Vue({
  el: '#example',
  data: {
    a: 1
  },
  computed: {
    // 一个计算属性的 getter
    b: function () {
      // `this` 指向 vm 实例
      return this.a + 1//b的值是计算出来的,依赖于a的值
    }
  }
})
<div id="demo">{{fullName}}</div>
<script>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  }
})

vm.$watch('firstName', function (val) {//监测‘firstName’值的变化,如果变化,就调用后面这个函数,将firstName的新值传给参数val
  this.fullName = val + ' ' + this.lastName
})

vm.$watch('lastName', function (val) {//监测‘lastName’值的变化,如果变化,就调用后面这个函数,将lasttName的新值传给参数val
  this.fullName = this.firstName + ' ' + val
})
</script>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})
computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

调用vm.fullName = 'John Doe' 时,setter会被调用,为firstName和lastName赋值,'John Doe' 传给参数newValue,var names = newValue.split(' ')将newValue以’ ‘为分隔符分隔为一个数组储存在names里面,所以names[0]的值为John,names[names.length - 1]即names[1]的值为Doe,然后getter被调用,为fullName计算值。

Class 与 Style 绑定

绑定 HTML Class

v-bind:class 指令可以与普通的 class 特性共存

eg:

<div class="static" v-bind:class="{ 'class-a': isA, 'class-b': isB }"></div>
data: {
  isA: true,
  isB: false
}

class-a是一个类名,class-b也是一个类名,通过data的isA和isB设置是否为元素绑定相应的类。渲染为:

<div class="static class-a"></div>

也可以直接绑定一个对象

<div v-bind:class="classObject"></div>
data: {
  classObject: {
    'class-a': true,
    'class-b': false
  }
}
<div v-bind:class="[classA, classB]">
data: {
  classA: 'class-a',
  classB: 'class-b'
}

渲染为:

<div class="class-a class-b"></div>

也可以:

<div v-bind:class="[classA, isB ? classB : '']">

始终添加classA类,如果isB为true,就添加classB类,如果isB为false,就不添加classB。

也可以:
eg:

<div v-bind:class="[classA, { classB: isB, classC: isC }]">

始终添加classA类,根据isB的值选择是否添加classB,根据IsC选择是否添加classC。

绑定内联样式

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
  activeColor: 'red',
  fontSize: 30
}

直接绑定到一个样式对象通常更好:

<div v-bind:style="styleObject"></div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}
<div v-bind:style="[styleObjectA, styleObjectB]">

条件渲染

<h1 v-if="ok">Yes</h1>

如果v-if的属性值——“ok”表达式的值为真,则显示“yes”,否则不显示“yes”。
eg:

<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>

如果v-if的属性值——“ok”表达式的值为真,则显示“yes”,否则不显示v-else对应的语句“No”。

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>

<strong>
tip:官网教程页没有详细说明v-if的用法,因此我在学习时使用v-if写的例子出现了问题:
首先,一开始我以为代码是这样写的:

Paste_Image.png

然而,虽然“ok”值为false,但是仍然显示:

Paste_Image.png

控制台报错:

Paste_Image.png

这个报错是说:v-if不可以用于根元素。
应将代码更正为:

Paste_Image.png

即可以用一个< div>将带有v-if的元素包裹起来,这时候控制台就不会报错了。
同样地,使用<template>包裹多个元素时,,也要用一个< div>将带有v-if的<template>包裹起来。
代码:

Paste_Image.png

显示效果:

Paste_Image.png

</strong>

<!DOCTYPE html>
<html>
<head>
    <title>try</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="two"><h1 v-show="ok">haha</h1></div>
<script>
    var vm2 = new Vue({
        el:"#two",
        data: {
            ok:true
        }
    })
</script>
</body>
</html>

显示效果:

v-show Paste_Image.png

显示效果:

Paste_Image.png

检查元素查看代码渲染结果:

Paste_Image.png

可见,v-show情况下即使为false,元素也会被渲染并保持在DOM中,只是display值为none。

v-if的情况下:


Paste_Image.png

显示效果:

Paste_Image.png

检查元素查看代码渲染结果:

Paste_Image.png

看,v-if情况下,当值为false时,元素不会被渲染出来。

tip: 在切换 v-if 块时,Vue.js 有一个局部编译/卸载过程,因为 v-if 之中的模板也可能包括数据绑定或子组件。v-if 是真实的条件渲染,因为它会确保条件块在切换当中合适地销毁与重建条件块内的事件监听器和子组件。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——在条件第一次变为真时才开始局部编译(编译会被缓存起来)。
相比之下,v-show 简单得多——元素始终被编译并保留,只是简单地基于 CSS 切换。
一般来说,v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好。

<div v-if="Math.random() > 0.5">
  Sorry
</div>
<div v-else>
  Not sorry
</div>

tip:v-else 元素必须立即跟在 v-if 或 v-show 元素的后面——否则它不能被识别。

<custom-component v-show="condition"></custom-component>
<p v-else>这可能也是一个组件</p>

用另一个 v-show 替换 v-else:

<custom-component v-show="condition"></custom-component>
<p v-show="!condition">这可能也是一个组件</p>

这样就可以达到 v-if 的效果。

列表渲染

<!DOCTYPE html>
<html>
<head>
    <title>try</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
    <li v-for="item in items">
        {{ item.message }}
    </li>
</ul>
<script>
    var vm3 = new Vue ({
        el:"#three",
        data: {
            items:[
            {message:'haha'},
            {message: 'hehe'}
            ]
        }
    })
</script>
</body>
</html>

items是一个数组,使用v-for将该数组中的每个数组元素渲染,然后显示每个数组元素的message。

v-for

在 v-for 块内我们能完全访问父组件作用域内的属性,另有一个特殊变量 $index,它是当前数组元素的索引:
eg:

<!DOCTYPE html>
<html>
<head>
    <title>try</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
    <li v-for="item in items">
        {{ parentMessage }} - {{ $index }} - {{ item.message }}
    </li>
</ul>
<script>
    var vm3 = new Vue ({
        el:"#three",
        data: {
            parentMessage: 'Parent',
            items:[
            {message:'haha'},
            {message: 'hehe'}
            ]
        }
    })
</script>
</body>
</html>

运行结果:

Paste_Image.png

另外,可以为索引指定一个别名:

Paste_Image.png

上面代码中,“xuhao”是为索引值起的一个别名,注意上下一致。

运行结果

tip:从 1.0.17 开始可以使用 of 分隔符,更接近 JavaScript 遍历器语法:
<div v-for="item of items"></div>

<!DOCTYPE html>
<html>
<head>
    <title>try</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
<template v-for="(xuhao,item) in items">
    <li>
        {{ parentMessage }} - {{ xuhao }} - {{ item.message }}
    </li>
    <li>yiyi</li>
</template>
    
</ul>
<script>
    var vm3 = new Vue ({
        el:"#three",
        data: {
            parentMessage: 'Parent',
            items:[
            {message:'haha'},
            {message: 'hehe'}
            ]
        }
    })
</script>
</body>
</html>
Paste_Image.png

因为v-for是在template上的,而每个template都有< li>yiyi</li>,所以会被多次渲染出来。

reverse Paste_Image.png Paste_Image.png

看,代码中原本是“haha”在前,“hehe”在后,使用reverse()后,“hhe”移动到了前面。

eg2:


pop Paste_Image.png Paste_Image.png

看,pop()之后只剩一个数组元素。

eg3:

push Paste_Image.png Paste_Image.png

看,push()之后为数组动态地添加了一个新元素。

vue.js用索引设置数组元素:$set(索引值,新元素)

Paste_Image.png Paste_Image.png
<!DOCTYPE html>
<html>
<head>
    <title>try</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
    <li v-for="value in object">
        {{ $key }} : {{ value }}
    </li>
</ul>
<script>
    var vm3 = new Vue ({
        el:"#three",
        data: {
            object: {
                FirstName: 'Frank',
                LastName: 'Jane',
                age: 20
            }
        }
    })
</script>
</body>
</html>
Paste_Image.png

也可以给对象的键提供一个别名:

<!DOCTYPE html>
<html>
<head>
    <title>try</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
    <li v-for="(key,value) in object">
        {{ key }} : {{ value }}
    </li>
</ul>
<script>
    var vm3 = new Vue ({
        el:"#three",
        data: {
            object: {
                FirstName: 'Frank',
                LastName: 'Jane',
                age: 20
            }
        }
    })
</script>
</body>
</html>
Paste_Image.png

方法与事件处理器

方法处理器

<!DOCTYPE html>
<html>
<head>
    <title>try</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="four">
    <button v-on:click="greet">greet</button>//为button绑定一个单击事件处理器,当被点击时执行greet方法
</div>
<script>
    var vm3 = new Vue ({
        el:"#four",
        data: {
            name:'vue.js'
        },
        methods: {
            greet: function (event) {
                alert('hello ' + this.name + '!')
                alert(event.target.tagName)
            }
        }
    })
    vm3.greet();//页面加载后执行此函数,因为没有调用它的元素,所以不会执行alert(event.target.tagName)这一句
</script>
</body>
</html>

运行结果:

Paste_Image.png Paste_Image.png

点击按钮:

Paste_Image.png Paste_Image.png

内联语句处理器

eg:

<div id="four">
    <button v-on:click="greet('hi')">greet</button>
</div>
<script>
    var vm3 = new Vue ({
        el:"#four",
        data: {
            name:'vue.js'
        },
        methods: {
            greet: function (msg) {
                alert(msg)
            }
        }
    })
</script>
Paste_Image.png

点击按钮:

Paste_Image.png

有时也需要在内联语句处理器中访问原生 DOM 事件。可以用特殊变量 $event 把它传入方法:
eg:

<div id="four">
    <button v-on:click="greet('hi',$event)">greet</button>
</div>
<script>
    var vm3 = new Vue ({
        el:"#four",
        data: {
            name:'vue.js'
        },
        methods: {
            greet: function (msg,event) {
                alert(event)
            }
        }
    })
</script>
Paste_Image.png

事件修饰符

Vue.js 为 v-on 提供两个 事件修饰符:.prevent 与 .stop

eg1:

<div id="four">
    <button v-on:click="doThis"><a v-on:click="doThis">greet</a></button>
</div>
<script>
    var vm3 = new Vue ({
        el:"#four",
        data: {
            name:'vue.js'
        },
        methods: {
            doThis: function (event) {
                alert('haha')
            }
        }
    })
</script>

上例会冒泡,点击的时候会出现两次弹窗,因为冒泡,< a>和< button>都触发了click。

eg2:

Paste_Image.png

上例不会冒泡,点击的时候只出现一次弹窗。

eg3:

Paste_Image.png

由于submit按钮的默认行为,点击submit后会重载页面,因此会发现,在此例中,点击submit后,首先出现了弹窗,然后整个页面被刷新。

eg4:

Paste_Image.png

添加了事件修饰符,.prevent,避免了点击提交按钮的时候页面被重载。

按键修饰符

监听键盘事件时,vue.js允许为v-on添加按键修饰符,并为最常用的按键提供了别名:

Paste_Image.png

按下tab键时,执行submit方法,出现弹窗。

表单控件绑定

基础用法

<div id="four">
    <span>Message is: {{ message }}</span>
    <br>
    <input type="text" v-model="message" placeholder="edit me" />
</div>

<script>
    var vm3 = new Vue ({
        el:"#four",
        data: {
            message:''
        },
    })
</script>

注意:一定要将“Message is”和input输入框包裹在一起,上例中将它们用一个div包裹在一起,并且id要写在包裹它们的标签上,即div标签上。

Paste_Image.png Paste_Image.png

实现双向数据绑定,同步显示。

<div id="four">
    <span>Message is: </span>
    <p>{{ message }}</p>
    <br>
    <textarea v-model="message" placeholder="edit me"></textarea>
</div>

<script>
    var vm3 = new Vue ({
        el:"#four",
        data: {
            message:''
        },
    })
</script>
Paste_Image.png Paste_Image.png
<div id="four">
    <input type="checkbox" id="check" v-model="checked">
    <label for="check">{{ checked }}</label>
</div>

<script>
    var vm3 = new Vue ({
        el:"#four",
        data: {
            message:''
        },
    })
</script>
Paste_Image.png Paste_Image.png

会根据勾选状态改变勾选框的label值。

多个勾选框,选中的同时显示选中的value值:
eg:

<div id="four">
    <input type="checkbox" id="jack" v-model="checkedName" value="jack">
    <label for="jack">jack</label>
    <input type="checkbox" id="jane" v-model="checkedName" value="jane">
    <label for="jane">jane</label>
    <input type="checkbox" id="jim" v-model="checkedName" value="jim">
    <label for="jim">jim</label>
    <br>
    <span>check: {{ checkedName }} </span>
</div>

<script>
    var vm3 = new Vue ({
        el:"#four",
        data: {
            checkedName:[]
        },
    })
</script>
Paste_Image.png Paste_Image.png Paste_Image.png Paste_Image.png
<div id="four">
    <input type="radio" id="one" value="one" v-model="message">
    <label for="one">one</label>
    <input type="radio" id="two" value="two" v-model="message">
    <label for="two">two</label>
    <br>
    <span>picked: {{ message }}</span>
</div>

<script>
    var vm3 = new Vue ({
        el:"#four",
        data: {
            message:''
        },
    })
</script>
Paste_Image.png Paste_Image.png Paste_Image.png
<div id="four">
    <select v-model="select">
        <option selected="selected">A</option>
        <option>B</option>
        <option>C</option>
    </select>
    <span>selected: {{ select }}</span>
</div>

<script>
    var vm3 = new Vue ({
        el:"#four",
        data: {
            select:''
        },
    })
</script>
Paste_Image.png Paste_Image.png Paste_Image.png

eg2:

Paste_Image.png Paste_Image.png

动态选项,用v-for渲染:
eg:

<div id="four">
    <select v-model="select">
        <option v-for="option in options" v-bind:value="option.value">//v-bind:value为option设置value值
        {{ option.text }}//option.text为option设置标签文本
        </option>
    </select>
    <br>
    <span>selected: {{ select }}</span>//select和v-model对应,v-model指示的是option的value值
</div>

<script>
    var vm3 = new Vue ({
        el:"#four",
        data: {
            options:[
            { text:'one', value:'a'},
            { text:'two', value:'b'},
            { text:'three', value:'c'}
            ]
        },
    })
</script>
Paste_Image.png Paste_Image.png
<div id="four">
    <input type="checkbox" id="check" v-model="checked" v-bind:true-value="yes" v-bind:false-value="no">
    <label for="check">{{ checked }}</label>
</div>

<script>
    var vm3 = new Vue ({
        el:"#four",
        data: {
            checked:'',
            yes:'yes',
            no:'no'
        },
    })
</script>

这样,当单选框被勾选时,value值为vue实例中的yes属性值,当单选框不被勾选时,value值为vue实例中的no属性值。

Paste_Image.png Paste_Image.png

lazy:
在默认情况下,v-model 在input 事件中同步输入框值与数据,可以添加一个特性 lazy,从而改到在 change 事件中同步:

Paste_Image.png

number:
如果想自动将用户的输入转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个特性 number:

Paste_Image.png

debounce:
debounce 设置一个最小的延时,在每次敲击之后延时同步输入框的值与数据。如果每次更新都要进行高耗操作(例如在输入提示中 Ajax 请求),它较为有用。

Paste_Image.png

注意 debounce 参数不会延迟 input 事件:它延迟“写入”底层数据。因此在使用 debounce 时应当用 vm.$watch() 响应数据的变化。若想延迟 DOM 事件,应当使用 debounce 过滤器。

上一篇下一篇

猜你喜欢

热点阅读