Vue 学习笔记

来源:互联网 发布:傲剑八卦升级数据大全 编辑:程序博客网 时间:2024/06/06 16:52

From: https://vuejs.bootcss.com/v2/guide/#声明式渲染


安装

兼容性Vue.js 不支持 IE8 及其以下版本,因为 Vue.js 使用了 IE8 不能模拟的 ECMAScript 5 特性。 Vue.js 支持所有兼容 ECMAScript 5 的浏览器

更新日志每个版本的更新日志见 GitHub

独立版本

直接下载并用 <script> 标签引入,Vue 会被注册为一个全局变量。重要提示:在开发时请用开发版本,遇到常见错误它会给出友好的警告。

CDN

推荐:unpkg, 会保持和 npm 发布的最新的版本一致。可以在 unpkg.com/vue/ 浏览 npm 包资源。

也可以从 jsdelivr 或 cdnjs 获取,不过这两个服务版本更新可能略滞后。

NPM

在用 Vue.js 构建大型应用时推荐使用 NPM 安装, NPM 能 很好地和 诸如 Webpack 或 Browserify 模块打包器 配合使用。 Vue.js 也提供 配套工具 来开发 单文件组件。

# 最新稳定版
$ npm install vue

独立构建 vs 运行时构建

有两种构建方式,独立构建 和 运行构建。它们的区别在于前者包含模板编译器 而后者不包含。

模板编译用于编译 Vue 模板字符串成纯 JavaScript 渲染函数。如果你想用 template 选项, 你需要编译。

模板编译器的职责是将模板字符串编译为纯 JavaScript 的渲染函数。如果你想要在组件中使用 template 选项,你就需要编译器。

  • 独立构建包含模板编译器并支持 template 选项。 它也依赖于浏览器的接口的存在,所以你不能使用它来为服务器端渲染

  • 运行时构建不包含模板编译器,因此不支持 template 选项,只能用 render 选项,但即使 使用 运行时构建,在单文件组件中也依然可以写模板,因为单文件组件的模板会在构建时预编译为 render 函数。运行时构建比独立构建要轻量30%,只有 17.14 Kb min+gzip大小。

默认 NPM 包导出的是 运行时 构建。为了使用独立构建,在 webpack 配置中添加下面的别名:

resolve: {
alias: {
'vue$': 'vue/dist/vue.common.js'
}
}

对于Browserify,可以添加一个别名到 package.json 中:

"browser": {
"vue": "vue/dist/vue.common"
},

CSP 环境(内容安全策略

有些环境,如 Google Chrome Apps ,强制应用内容安全策略 (CSP)不能使用 new Function() 对表达式求值。这时可以用 CSP 兼容版本。独立的构建取决于该功能编译模板,所以无法使用这些环境。

另一方面,运行时构建的是完全兼容 CSP 的。 当通过 Webpack + vue-loader 或者 Browserify + vueify 构建时,在 CSP 环境中模板将被完美预编译到 render 函数中。

命令行工具

Vue.js 提供一个官方命令行工具,可用于快速搭建大型单页应用。该工具提供开箱即用的构建工具配置,带来现代化的前端开发流程。只需几分钟即可创建并启动一个带热重载、保存时静态检查以及可用于生产环境的构建配置的项目:

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

CLI 工具假定用户对 Node.js  和 相关构建工具有一定程度的了解。如果你是新手,我们强烈建议先在不用构建工具的情况下通读指南,熟悉 Vue 本身之后再研究 CLI。

对于大陆用户,建议将 npm 的注册表源设置为国内的镜像,可以大幅提升安装速度。

开发版本

重要: Github 仓库的 /dist 文件夹只有在新版本发布时才会更新。如果想要使用 Github 上 Vue 最新的源码,你需要自己构建。

git clone https://github.com/vuejs/vue.git node_modules/vue
cd node_modules/vue
npm install
npm run build

Bower

# 最新稳定版本
$ bower install vue

AMD 模块加载器

独立下载版本 或 通过 Bower 安装的版本 已用 UMD 包装,因此它们可以直接用作 AMD 模块。



介绍

Vue.js 是什么

Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和 Vue 生态系统支持的库开发的复杂单页应用。

Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定组合的视图组件

如果你是有经验的前端开发者,想知道 Vue.js 与其它库/框架的区别,查看对比其它框架。

起步

官方指南假设你已有 HTML、CSS 和 JavaScript 中级前端知识。如果你是全新的前端开发者,将框架作为你的第一步可能不是最好的主意——掌握好基础知识再来!之前有其他框架的使用经验是有帮助的,但不是必需的。

尝试 Vue.js 最简单的方法是使用 JSFiddle Hello World 例子。(注:你得用越的软件的网络,要不执行不稳定)你可以在浏览器新标签页中打开它,跟着我们学习一些基础示例。或者你也可以创建一个本地的 .html 文件,然后通过如下方式引入 Vue:

<script src="https://unpkg.com/vue/dist/vue.js"></script>

你可以查看安装指南来了解其他安装 Vue 的选项。请注意我们不推荐新手直接使用 vue-cli,尤其是对 Node.js 构建工具不够了解的同学。

声明式渲染

Vue.js 的核心是一个允许你采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统:

<div id="app"> {{ message }} </div>
var app = new Vue({
el: '#app',
data: { message: 'Hello Vue!' }
})
Hello Vue!

我们已经生成了我们的第一个 Vue 应用!看起来这跟单单渲染一个字符串模板非常类似,但是 Vue.js 在背后做了大量工作。现在数据和 DOM 已经被绑定在一起,所有的元素都是响应式的。我们如何知道?打开你的浏览器的控制台,并修改app.message,你将看到上例相应地更新。

除了绑定插入的文本内容,我们还可以采用这样的方式绑定 DOM 元素属性:

<div id="app-2">
<span v-bind:title="message">
Hover your mouse over me for a few seconds to see my dynamically bound title!
</span>
</div>
var app2 = new Vue({
el: '#app-2',
data: {
message: 'You loaded this page on ' + new Date()
}
})你看到的 v-bind 属性被称为指令。指令带有前缀 v-,以表示它们是 Vue.js 提供的特殊属性。
这个指令的简单含义是说:将这个元素节点的 title 属性和 Vue 实例的 message 属性绑定到一起。


你再次打开浏览器的控制台输入
 app2.message = 'some new message',你就会再一次看到这个绑定了title属性的HTML已经进行了更新。 

条件与循环

控制切换一个元素的显示也相当简单:

<div id="app-3">
<p v-if="seen">Now you see me</p>
</div>
var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})
Now you see me

继续在控制台设置 app3.seen = false,你会发现 “Now you see me” 消失了。

这个例子演示了我们不仅可以绑定 DOM 文本到数据,也可以绑定 DOM 结构到数据。而且,Vue.js 也提供一个强大的过渡效果系统,可以在 Vue 插入/删除元素时自动应用过渡效果。

也有一些其它指令,每个都有特殊的功能。例如, v-for 指令可以绑定数据到数组来渲染一个列表:

<div id="app-4">
<ol>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ol>
</div>
var app4 = new Vue({
el: '#app-4',
data: {
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue' },
{ text: 'Build something awesome' }
]
}
})
  1. Learn JavaScript
  2. Learn Vue
  3. Build something awesome

在控制台里,输入 app4.todos.push({ text: 'New item' })。你会发现列表中多了一栏新内容。

处理用户输入

为了让用户和你的应用进行互动,我们可以用 v-on 指令绑定一个监听事件用于调用我们 Vue 实例中定义的方法:

<div id="app-5">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">Reverse Message</button>
</div>
var app5 = new Vue({
el: '#app-5',
data: {
message: 'Hello Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})

Hello Vue.js!

在 reverseMessage 方法中,我们在没有接触 DOM 的情况下更新了应用的状态 - 所有的 DOM 操作都由 Vue 来处理,你写的代码只需要关注基本逻辑。

Vue 也提供了 v-model 指令,它使得在表单输入和应用状态中做双向数据绑定变得非常轻巧。

<div id="app-6">
<p>{{ message }}</p>
<input v-model="message">
</div>
var app6 = new Vue({
el: '#app-6',
data: {
message: 'Hello Vue!'
}
})

Hello Vue!

综合的例子

注:在chrome浏览器中实测发现v-if 是把对应了删除的节点,并不是简单地显示或隐藏。

v-model 双向数据绑定; 


用组件构建(应用)

组件系统是 Vue.js 另一个重要概念,因为它提供了一种抽象,让我们可以用独立可复用的小组件来构建大型应用。如果我们考虑到这点,几乎任意类型的应用的界面都可以抽象为一个组件树:

Component Tree


在 Vue 里,一个组件实质上是一个拥有预定义选项的一个 Vue 实例:

// Define a new component called todo-item
Vue.component('todo-item', {
template: '<li>This is a todo</li>'
})

现在你可以在另一个组件模板中写入它:

<ol><!-- 创建一个 todo-item 组件实例-->
<todo-item></todo-item>
</ol>

但是这样会为每个 todo 渲染同样的文本,这看起来并不是很酷。我们应该将数据从父作用域传到子组件。让我们来修改一下组件的定义,使得它能够接受一个属性字段:

//todo-item组件接受一个"prop"接口属性,它跟普通的属性一样与DOM属性通信。
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})

现在,我们可以使用 v-bind 指令将 todo 传到每一个重复的组件中:

<!-- 这里todo对象的每个todo-item,
<div id="app-7">
<ol>
<!-- Now we provide each todo-item with the todo object -->
<!-- it's representing, so that its content can be dynamic -->
<todo-item v-for="item in groceryList" v-bind:todo="item"></todo-item>
</ol>
</div>
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
var app7 = new Vue({
el: '#app-7',
data: {
groceryList: [
{ text: 'Vegetables' },
{ text: 'Cheese' },
{ text: 'Whatever else humans are supposed to eat' }
]
}
});
  1. Vegetables
  2. Cheese
  3. Whatever else humans are supposed to eat    注:实测中发现只有new Vue后,component才会生效

这只是一个假设的例子,但是我们已经将应用分割成了两个更小的单元,子元素通过 props 接口实现了与父亲元素很好的解耦。我们现在可以在不影响到父应用的基础上,进一步为我们的 todo 组件改进更多复杂的模板和逻辑。

在一个大型应用中,为了使得开发过程可控,有必要将应用整体分割成一个个的组件。在后面的教程中我们将详述组件,不过这里有一个(假想)的例子,看看使用了组件的应用模板是什么样的:

<div id="app">
<app-nav></app-nav>
<app-view>
<app-sidebar></app-sidebar>
<app-content></app-content>
</app-view>
</div>

与自定义元素的关系

你可能已经注意到 Vue.js 组件非常类似于自定义元素——它是 Web 组件规范的一部分。实际上 Vue.js 的组件语法参考了该规范。例如 Vue 组件实现了 Slot API 与 is 特性。但是,有几个关键的不同:

  1. Web 组件规范仍然远未完成,并且没有浏览器实现。相比之下,Vue.js 组件不需要任何补丁,并且在所有支持的浏览器(IE9 及更高版本)之下表现一致。必要时,Vue.js 组件也可以放在原生自定义元素之内。

  2. Vue.js 组件提供了原生自定义元素所不具备的一些重要功能,比如组件间的数据流,自定义事件系统,以及动态的、带特效的组件替换。

准备好探索更广阔的世界了?

我们刚才简单介绍了 Vue.js 核心的一些最基本的特征 - 本指南的其余部分将用更详尽的篇幅去描述其他的一些高级特性,所以一定要阅读完所有的内容哦!


原文:http://vuejs.org/guide/index.html


Vue组件

参考此文章: http://cn.vuejs.org/v2/guide/components.html#注册


列表渲染

v-for

我们用 v-for 指令根据一组数组的选项列表进行渲染。 v-for 指令需要以 item in items 形式的特殊语法, items是源数据数组并且 item 是数组元素迭代的别名。

基本用法

<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{message: 'Foo' },
{message: 'Bar' }
]
}
})

在 v-for 块中,我们拥有对父作用域属性的完全访问权限。 v-for 还支持一个可选的第二个参数为当前项的索引

<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})

结果:

  • Parent - 0 - Foo
  • Parent - 1 - Bar

你也可用of替代in作为分隔符,因为它是最接近 JS 迭代器的语法:<divv-for="item of items"></div>

Template v-for

如同 v-if 模板,你也可以用带有 v-for 的 <template> 标签来渲染多个元素块。例如:

<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider"></li>
</template>
</ul>

对象迭代 v-for

你也可以用 v-for 通过一个对象的属性来迭代。

<ul id="repeat-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
new Vue({
el: '#repeat-object',
data: {
object: {
FirstName: 'John',
LastName: 'Doe',
Age: 30
}
}
})

结果:

  • John
  • Doe
  • 30

你也可以提供第二个的参数为键名:

<div v-for="(value, key) in object">
{{ key }} : {{ value }}
</div>

第三个参数为索引:

<div v-for="(value, key, index) in object">
{{ index }}. {{ key }} : {{ value }}
</div>

在遍历对象时,是按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下是一致的。

整数迭代 v-for

v-for 也可以取整数。在这种情况下,它将重复多次模板。

<div>
<span v-for="n in 10">{{ n }}</span>
</div>

结果:1 2 3 4 5 6 7 8 9 10

组件 和 v-for

了解组件相关知识,查看 组件 。完全可以先跳过它,以后再回来查看。

在自定义组件里,你可以像任何普通元素一样用 v-for 。

<my-component v-for="item in items"></my-component>

然而他不能自动传递数据到组件里,因为组件有自己独立的作用域。为了传递迭代数据到组件里,我们要用 props(属性)

<my-component
v-for="(item, index) in items"
v-bind:item="item"
v-bind:index="index">
</my-component>

不自动注入 item 到组件里的原因是因为这使得组件会紧密耦合到 v-for 如何运作。在一些情况下,明确数据的来源可以使组件可重用。

下面是一个简单的 todo list 完整的例子:

<div id="todo-list-example">
<input
v-model="newTodoText"
v-on:keyup.enter="addNewTodo"
placeholder="Add a todo"
>
<ul>
<li
is="todo-item"
v-for="(todo, index) in todos"
v-bind:title="todo"
v-on:remove="todos.splice(index, 1)"
></li>
</ul>
</div>
Vue.component('todo-item', {
template: '\
<li>\
{{ title }}\
<button v-on:click="$emit(\'remove\')">X</button>\
</li>\
',
props: ['title']
})
new Vue({
el: '#todo-list-example',
data: {
newTodoText: '',
todos: [
'Do the dishes',
'Take out the trash',
'Mow the lawn'
]
},
methods: {
addNewTodo: function () {
this.todos.push(this.newTodoText)
this.newTodoText = ''
}
}
})
  • Do the dishes 
  • Take out the trash 
  • Mow the lawn 

为什么要用 is 特性?


说直白点,如果<ul><todo-item></todo-item></ul>这样就不能复用todo-item这个组件了,vue.js只认标准的HTML(如:<ul><li></li></ul>)。 如果真要用,那就用is特性像这样:<ul><li is="todo-item"></li></ul>

key

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。这个类似 Vue 1.x 的 track-by="$index" 。

这个默认的模式是有效的,但是只适用于不依赖子组件状态 或 临时 DOM 状态(例如:表单输入值)的列表渲染输出。

为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用 和 重新排序现有元素,你需要为每项提供一个唯一 key属性。理想的 key 值是每项都有唯一 id。这个特殊的属性相当于 Vue 1.x 的 track-by ,但它的工作方式类似于一个属性,所以你需要用 v-bind 来绑定动态值(在这里使用简写):

<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>

建议尽可能使用 v-for 来提供 key ,除非迭代 DOM 内容足够简单,或者你是故意要依赖于默认行为来获得性能提升。

因为它是 Vue 识别节点的一个通用机制, key 并不特别与 v-for 关联,key 还具有其他用途,我们将在后面的指南中看到其他用途。

数组更新检测

变异方法

Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

你打开控制台,然后用前面例子的 items 数组调用变异方法:example1.items.push({ message: 'Baz' }) 。

重塑数组

变异方法(mutation method),顾名思义,会改变被这些方法调用的原始数组。相比之下,也有非变异(non-mutating method)方法,例如: filter()concat()slice() 。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:

example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})

你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。 Vue 实现了一些智能启发式方法来最大化 DOM 元素重用,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。

注意事项

由于 JavaScript 的限制, Vue 不能检测以下变动的数组:

  1. 当你利用索引直接设置一个项时,例如: vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如: vm.items.length = newLength

为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果, 同时也将触发状态更新:

// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice`
example1.items.splice(indexOfItem, 1, newValue)

为了解决第二类问题,你也同样可以使用 spliceexample1.items.splice(newLength)

显示过滤/排序结果

有时,我们想要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据。在这种情况下,可以创建返回过滤或排序数组的计算属性

例如:<liv-for="n in evenNumbers">{{ n }}</li>

data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
}

或者,你也可以在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 使用 method 方法:

<li v-for="n in even(numbers)">{{ n }}</li>
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
even: function (numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}

原文: http://vuejs.org/guide/list.html


0 0