Vue基础(实例和模板语法)

安装

兼容性

Vue不支持IE8及以下版本。

引入

直接下载并用<script>标签引入,Vue会被注册为一个全局变量。
开发版本包含完整的警告和调试模式;生产版本删除了警告。

命令行工具(CLI)

//全局安装vue-cli
npm install --global vue-cli
//创建一个基于webpack模板的新项目
vue init webpack my-project
//安装依赖
cd my-project
npm install
npm run dev

对不同构建版本的解释

在NPM包的dist/目录有很多不同的Vue.js构建版本。

UMD CommonJS ES Module
完整版 vue.js vue.common.js vue.esm.js
只包含运行时版 vue.runtime.js vue.runtime.common.js vue.runtime.esm.js
完整版(生产环境) vue.min.js - -
只包含运行时版(生产环境) vue.runtime.min.js - -
术语

完整版:同时包含编译器和运行时的版本。
编译器:用来将模板字符串编译成为JavaScript渲染函数的代码。
运行时:用来创建Vue实例、渲染并处理虚拟DOM等的代码。基本上就是除去编译器的其它一切。
UMD:UMD版本可以通过<script>标签直接用在浏览器中。
CommonJS:CommonJS版本用来配合老的打包工具比如Browserify或webpack1。这些打包工具的默认文件(pkg.main)是只包含运行时的CommonJS版本。
ES Module:ES module版本用来配合现代打包工具比如webpack2。这些打包工具的默认文件(pkg.module)是只包含运行时的ES Module版本。

运行时+编译器vs只包含运行时

如果需要在客户端编译模板 (比如传入一个字符串给template选项,或挂载到一个元素上并以其DOM内部的HTML作为模板),就将需要加上编译器,即完整版。

// 需要编译器
new Vue({
  template: '<div>{{ hi }}</div>'
})
// 不需要编译器
new Vue({
  render (h) {
    return h('div', this.hi)
  }
})

当使用vue-loadervueify的时候,*.vue文件内部的模板会在构建时预编译成JavaScript。最终打好的包里实际上是不需要编译器的,所以只用运行时版本即可。
因为运行时版本相比完整版体积要小大约30%,所以应该尽可能使用这个版本。如果你仍然希望使用完整版,则需要在打包工具里配置一个别名。

//webpack
module.exports = {
  // ...
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js' // 用 webpack 1 时需用 'vue/dist/vue.common.js'
    }
  }
}
//Browserify
{
  // ...
  "browser": {
    "vue": "vue/dist/vue.common.js"
  }
}
开发环境vs生产环境

对于UMD版本来说,开发环境/生产环境模式是硬编码好的:开发环境下用未压缩的代码,生产环境下使用压缩后的代码。
CommonJS和ES Module版本是用于打包工具的,因此没有压缩后的版本。需要我们自行将最终的包进行压缩。
CommonJS和ES Module版本同时保留原始的process.env.NODE_ENV检测,以决定它们应该运行在什么模式下。我们应该使用适当的打包工具配置来替换这些环境变量以便控制Vue所运行的模式。把process.env.NODE_ENV替换为字符串字面量同时可以让UglifyJS之类的压缩工具完全丢掉仅供开发环境的代码块,以减少最终的文件尺寸。

//webpack4+
module.exports = {
  mode: 'production'
}
//webpack3
var webpack = require('webpack')
module.exports = {
  // ...
  plugins: [
    // ...
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('production')
      }
    })
  ]
}

Vue实例

创建一个Vue实例

每个Vue应用都是通过用Vue函数创建一个新的Vue实例开始的。

var vm = new Vue({
  // 选项
})

当创建一个Vue实例时,可以传入一个选项对象。
一个Vue应用由一个通过new Vue创建的根Vue实例,以及可选的嵌套的、可复用的组件树组成。
所有的Vue组件都是Vue实例,并且接受相同的选项对象 (一些根实例特有的选项除外)。

数据与方法

当一个Vue实例被创建时,它向Vue的响应式系统中加入了其 data 对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生响应,即匹配更新为新的值。

var data = { a: 1 } // 我们的数据对象
var vm = new Vue({
  data: data // 该对象被加入到一个Vue实例中
})
// 获得这个实例上的属性
// 返回源数据中对应的字段
vm.a == data.a // => true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // => 2
// ……反之亦然
data.a = 3
vm.a // => 3

当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时data中存在的属性才是响应式的。也就是说如果你添加一个新的属性,比如:

vm.b = 'hi'

那么对b的改动将不会触发任何视图的更新。如果你知道你会在晚些时候需要一个属性,但是一开始它为空或不存在,那么你仅需要设置一些初始值。

data: {
  newTodoText: '',
  visitCount: 0,
  hideCompletedTodos: false,
  todos: [],
  error: null
}

这里唯一的例外是使用Object.freeze(),这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。

var obj = {
  foo: 'bar'
}
Object.freeze(obj)
new Vue({
  el: '#app',
  data: obj
})
<div id="app">
  <p>{{ foo }}</p>
  <!-- 这里的 `foo` 不会更新! -->
  <button v-on:click="foo = 'baz'">Change it</button>
</div>

除了数据属性,Vue实例还暴露了一些有用的实例属性与方法。它们都有前缀$,以便与用户定义的属性区分开来。

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 (newValue, oldValue) {
  // 这个回调将在 `vm.a` 改变后调用
})

实例生命周期钩子

每个Vue实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新DOM等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
比如created钩子可以用来在一个实例被创建之后执行代码。

new Vue({
 data: {
 a: 1
 },
 created: function () {
 // this指向vm实例
 console.log('a is:'+this.a)
 }
})
// => "a is: 1"

也有一些其它的钩子,在实例生命周期的不同阶段被调用,如mountedupdateddestroyed。生命周期钩子的this上下文指向调用它的Vue实例。
不要在选项属性或回调上使用箭头函数,比如 created:()=>console.log(this.a)vm.$watch('a',newValue=>this.myMethod())。因为箭头函数是和父级上下文绑定在一起的,this不会是如你所预期的Vue实例,经常导致Uncaught TypeError: Cannot read property of undefinedUncaught TypeError: this.myMethod is not a function之类的错误。

生命周期图示

模板语法

Vue.js使用了基于HTML的模板语法,允许开发者声明式地将DOM绑定至底层Vue实例的数据。
在底层的实现上,Vue将模板编译成虚拟DOM渲染函数。结合响应系统,Vue能够智能地计算出最少需要重新渲染多少组件,并把DOM操作次数减到最少。
你也可以不用模板,直接写渲染(render)函数,使用可选的JSX语法。

插值

文本

数据绑定最常见的形式就是使用双大括号的文本插值。

<span>Message: {{ msg }}</span>

双大括号标签将会被替代为对应数据对象上msg属性的值。无论何时,绑定的数据对象上msg属性发生了改变,插值处的内容都会更新。
通过使用v-once指令,也能执行一次性地插值,当数据改变时,插值处的内容不会更新。

<span v-once>这个将不会改变: {{ msg }}</span>
原始HTML

双大括号会将数据解释为普通文本,而非HTML代码。为了输出真正的HTML,需要使用v-html指令。

<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

动态渲染的任意HTML可能会非常危险,因为它很容易导致XSS攻击。请只对可信内容使用HTML插值,绝不要对用户提供的内容使用插值。

特性

双大括号语法不能作用在HTML特性上,遇到这种情况应该使用v-bind指令。

<div v-bind:id="dynamicId"></div>

在布尔特性的情况下,它们的存在即暗示为truev-bind工作起来略有不同。

<button v-bind:disabled="isButtonDisabled">Button</button>

如果isButtonDisabled的值是 nullundefinedfalse,则disabled特性甚至不会被包含在渲染出来的<button>元素中。

使用JavaScript表达式

对于所有的数据绑定,Vue.js都提供了完全的JavaScript表达式支持。

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>

这些表达式会在所属Vue实例的数据作用域下作为JavaScript被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。

<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如MathDate 。你不应该在模板表达式中试图访问用户定义的全局变量。

指令

指令是带有v-前缀的特殊特性。指令特性的值预期是单个JavaScript表达式(v-for是例外情况)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于DOM。

<p v-if="seen">现在你看到我了</p>

这里,v-if指令将根据表达式seen的值的真假来插入/移除<p>元素。

参数

一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind指令可以用于响应式地更新HTML特性。

<a v-bind:href="url">...</a>

在这里href是参数,告知v-bind指令将该元素的href特性与表达式url的值绑定。
v-on 指令,它用于监听DOM事件。

<a v-on:click="doSomething">...</a>

在这里参数是监听的事件名。

修饰符

修饰符是以半角句号.指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent修饰符告诉v-on指令对于触发的事件调用event.preventDefault()

<form v-on:submit.prevent="onSubmit">...</form>

缩写

v-前缀作为一种视觉提示,用来识别模板中Vue特定的特性。Vue.jsv-bindv-on这两个最常用的指令,提供了特定简写。

v-bind缩写
<!-- 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
v-on缩写
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • 1.安装 可以简单地在页面引入Vue.js作为独立版本,Vue即被注册为全局变量,可以在页面使用了。 如果希望搭建...
    Awey阅读 10,913评论 4 129
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 4,989评论 0 29
  • vue概述 在官方文档中,有一句话对Vue的定位说的很明确:Vue.js 的核心是一个允许采用简洁的模板语法来声明...
    li4065阅读 7,108评论 0 25
  • 每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的: 实例生命周期钩子 每个 Vue 实例...
    Timmy小石匠阅读 1,340评论 0 11
  • 雨天的时候最容易想起你,尤其是那种把天地冲刷一遍的瓢泼大雨啊,比如像今天。不知道是伞小或者雨太大,还是我有些笨,虽...
    楊小汪阅读 213评论 0 0