vue 学习
CDN
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
一. Vue 实例
1.1 创建一个 Vue 实例
每一个Vue应用都是通过Vue函数创建一个新的 Vue 实例开始的
var vm = new Vue({
//选项
})
vm ViewModel 之缩写
一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成。举个例子,一个 todo 应用的组件树可以是这样的:
根实例
└─ TodoList
├─ TodoItem
│ ├─ DeleteTodoButton
│ └─ EditTodoButton
└─ TodoListFooter
├─ ClearTodosButton
└─ TodoListStatistics
1.2 数据与方法
当一个 Vue 实例被创建时,它将 data 对象中的所有的属性加入到 Vue 的响应式系统中。
当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值
// 我们的数据对象
var data = { a: 1 }
// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
data: data
})
// 获得这个实例上的属性
// 返回源数据中对应的字段
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` 改变后调用
})
1.3 生命周期钩子
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
比如 created 钩子可以用来在一个实例被创建之后执行代码:
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
// => "a is: 1"
也有一些其它的钩子,在实例生命周期的不同阶段被调用,如 mounted
、updated
和 destroyed
。生命周期钩子的 this
上下文指向调用它的 Vue
实例。
生命周期图示:
graph TD
A[new_Vue/新建Vue实例] --> B[初始化-事件&生命周期]
B-->|beforeCreate|C[初始化-注入&校验]
C -->|created|D{是否指定-el-选项?}
D -->|否|E[当调用vm.$mount<el>函数时使用]
D-->|是|F{是否指定-template-选项?}
E-->F
F-->|是|G[将template编译到render函数中<即渲染>]
F-->|否|H[将el外部的HTML作为template编译]
G-->|beforeMount|I[创建vm.$el 并用其替换<el>]
H-->|beforeMount|I
I-->|mounted|J((挂载完毕))
J-->|当data被修改时<beforeUpdate>|N[虚拟DMO重新渲染并应用更新]
N-->|当data被修改时<updateed>|J
J-->|当调用vm.$destroy|K[解除绑定,销毁子组件以及时间监听器]
K-->L((销毁完毕))
L-->M[destroyed]
二.模板语法
2.1 插入值
2.1.1 文本
Mustache 语法(双大括号)
<span>Message : {{ msg }} </span>
Mustache 标签将会被替代为对应数据对象上 msg 属性的值。无论何时,绑定的数据对象上msg属性发生了改变,插值处的内容都会更新。
若果不想被多次修改,可以使用 指令 v-once
<span v-once>这个将不会改变: {{ msg }}</span>
2.1.2 原始HTML
双大括号传入的数据会被解释成为普通文本,而非HTML代码,为了输出纯正的 HTML ,需要使用 v-html指令.
<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
当传参数 (<span style=‘color:red’>This should be red. ) 给{{ rawHtml }}后,渲染为:
Using mustaches: <span style=‘color:red’>This should be red. ## Mustache 插入值 接受输出为文本
Using v-html directive: This should be red. ## v-html 接受的是html代码,并编译渲染
这个 span 的内容将会被替换成为属性值 rawHtml,直接作为 HTML——会忽略解析属性值中的数据绑定。
注意,你不能使用 v-html 来复合局部模板,因为 Vue 不是基于字符串的模板引擎。反之,对于用户界面 (UI),组件更适合作为可重用和可组合的基本单位。
2.1.3 Attribute(特性)
Mustache 语法不能作用在 HTML attribute 上,遇到这种情况应该使用 v-bind 指令:
<div v-bind:id="dynamicId"></div>
v-bind 是将<div> 标签中的某些属性与Vue实例中的数据相关联,比如:
1. <div id="head" ></div> #id标签==固定为head==,后续在css中或者js中调用
2.<div v-bind:id="hhhhead" ></div>#id标签 为动态变化,
<script>
var vm = new Vue({
el:"#app", #上一级的容器,app可以理解为一个组件或一个子程序
data:{
hhhhead:heading # 一旦渲染成功,2.中的id 将被替换为heading,网页元素中可见<div id="heading" ></div>
},
})
</script>
对于布尔 attribute (它们只要存在就意味着值为 true),v-bind 工作起来略有不同,在这个例子中:
<button v-bind:disabled="isButtonDisabled">Button</button>
如果 isButtonDisabled 的值是 null、undefined 或 false,则 disabled attribute 甚至不会被包含在渲染出来的 元素中。
2.1.4 使用JavaScript表达式
迄今为止,在我们的模板中,我们一直都只绑定简单的属性键值。但实际上,对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。
<div id="app">
{{ number + 1 }} --->11
{{ ok ?'YES':'NO' }} #三元表达式 ok 为 true 输出 'YES'否则输出'NO';
{{ message.split('').reverse().jion('') }} #复函计算
</div>
<div v-bind:id="'list-' + id"> </div>
<script>
var vm = new Vue({
el:"#app", #容器,app可以理解为一个组件或一个子程序
data:{
number:10, #页面上会计算 10+1
ok:true,
}
})
</script>
这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}
模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 Math 和 Date 。++你不应该在模板表达式中试图访问用户定义的全局变量。++
2.2 指令
指令(Directives)是带有 v-
前缀的特殊attribute.指令attribute的值预期是单个JavaScript表达式(v-for除外).
指令的职责是: 当表达式的值发生改变的时候,将其产生的连带影响,响应式地作用于DOM.
<p v-if='seen'>现在你看到我了<p>
这里 v-if 指令将根据表达式seen
的 true or false 来插入/删除元素<p>.
2.2.1 参数
一些指令能够接受一个’参数’,在指令之后以冒号表示,eg: 告知 v-bind
指令可以用于响应式地更新 HTML attrubute:
<a v-bing:href='url'>...</a> #在这里== href 是参数==,告知 v-bind 指令将该元素的 href attribute 与表达式 url 的值绑定。
-
v-bind 是将<div> 标签中的某些属性与Vue实例中的数据相关联,比如:
1. <div id="head" ></div> #id标签==固定为head==,后续在css中或者js中调用 2.<div v-bind:id="hhhhead" ></div>#id标签 为动态变化, <script> var vm = new Vue({ el:"#app", #上一级的容器,app可以理解为一个组件或一个子程序 data:{ hhhhead:heading # 一旦渲染成功,2.中的id 将被替换为heading,网页元素中可见<div id="heading" ></div> }, }) </script>
-
v-on 监听DMO事件:
<a v-on:click='doSomeing'>...</a> #在这里参数是监听的事件名
2.2.2 动态参数
2.6.0
Vue从2.6.0开始,可以用方括号 [] 括起来的 JavaScript 表达式作为一个指令的参数
<!--
注意,参数表达式的写法存在一些约束,如之后的“对动态参数表达式的约束”章节所述。
-->
<a v-bind:[attributeName]="url"> ... </a>
这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。
例如,如果你的 Vue 实例有一个 data 属性 attributeName,其值为 “href”,那么这个绑定将等价于 v-bind:hre
同样地,你可以使用动态参数为一个动态的事件名绑定处理函数:
<a v-on:[eventName]="doSomething"> ... </a>
#当 eventName 的值为 "focus" 时,v-on:[eventName] 将等价于 v-on:focus。
对动态参数值的约束(没懂)
对动态参数的值的约束 动态参数预期会求出一个字符串,异常情况下值为 null。这个特殊的 null 值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。
对动态参数表达式的约束(没懂)
动态参数表达式有一些语法约束,因为某些字符,如空格和引号,放在 HTML attribute 名里是无效的。例如:
<!-- 这会触发一个编译警告 -->
<a v-bind:['foo' + bar]="value"> ... </a>
变通的办法是使用没有空格或引号的表达式,或用计算属性替代这种复杂表达式。
在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写:
<!--
在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`。
除非在实例中有一个名为“someattr”的 property,否则代码不会工作。
-->
<a v-bind:[someAttr]="value"> ... </a>
修饰符
修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():
<form v-on:submit.prevent="onSubmit">...</form>
例子
<div @click="click1">
<div @click="click2">
click me //一旦单击了""click me"按钮之后,先执行本层div 然后在执行父级div.
//若不想让父级div执行.则在子级div添加修饰符 .stop
//@click.stop="click2"
</div>
</div>
2.3 缩写
v-
前缀作为一种视觉提示,用来识别模板中 Vue 特定的 attribute。当你在使用 Vue.js 为现有标签添加动态行为 (dynamic behavior) 时,v-
前缀很有帮助,然而,对于一些频繁用到的指令来说,就会感到使用繁琐。同时,在构建由 Vue 管理所有模板的单页面应用程序 (SPA - single page application) 时,v- 前缀也变得没那么重要了。因此,Vue 为 v-bind 和 v-on 这两个最常用的指令,提供了特定简写:
v-bind简写
<!-- 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a :[key]="url"> ... </a>
v-on 简写
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>
它们看起来可能与普通的 HTML 略有不同,但 : 与 @ 对于 attribute 名来说都是合法字符,在所有支持 Vue 的浏览器都能被正确地解析。而且,它们不会出现在最终渲染的标记中。缩写语法是完全可选的