Vue.js——学习笔记(一)
Vue-自学笔记
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
总之一句话:有问题,查官网。本笔记只适合学习复习使用。如果学习话,请自行查阅Vue官网。
本笔记来源于:自学过程,参考Vue官方文档。——大娃
基础
安装
https://cn.vuejs.org/v2/guide/installation.html 相关版本介绍
1. 直接引用
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
2. CDN
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
3. 模块化构建
<script type="module">
import Vue from 'https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.esm.browser.js'
</script>
起步
声明式渲染
<div id="app">
{{ message }}
</div> var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
//声明式渲染
条件与循环
<div id="app-2">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div> var app2 = new Vue({
el: '#app-2',
data: {
message: '页面加载于 ' + new Date().toLocaleString()
}
})
//逻辑判断,相关指令
处理用户输入
<div id="app-6">
<p>{{ message }}</p>
<input v-model="message">
</div> var app6 = new Vue({
el: '#app-6',
data: {
message: 'Hello Vue!'
}
})
//事件绑定,自动渲染
组件化应用构建
Vue.component('todo-item', {
// todo-item 组件现在接受一个
// "prop",类似于一个自定义 attribute。
// 这个 prop 名为 todo。
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
}) <div id="app-7">
<ol>
<!--
现在我们为每个 todo-item 提供 todo 对象
todo 对象是变量,即其内容可以是动态的。
我们也需要为每个组件提供一个“key”,稍后再
作详细解释。
-->
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id"
></todo-item>
</ol>
</div> Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
}) var app7 = new Vue({
el: '#app-7',
data: {
groceryList: [
{ id: 0, text: '蔬菜' },
{ id: 1, text: '奶酪' },
{ id: 2, text: '随便其它什么人吃的东西' }
]
}
}) //组件化应用构建-自定义
从上述简单的案例,让用户明白Vue能够用来干什么。虽然这些作者都已经说了,这些都只是Vue的皮毛的体现,但是就这些内容,已经颠覆了我对前端的认知了。
Vue实例
创建一个Vue实例
api:https://vuejs.org/v2/api/#Options-Data
var vm = new Vue({
// 选项
})
当创建一个 Vue 实例时,你可以传入一个选项对象( {} 这个就是选项对象。)。这篇教程主要描述的就是如何使用这些选项来创建你想要的行为。
目前你只需要明白所有的 Vue 组件都是 Vue 实例,并且接受相同的选项对象 (一些根实例特有的选项除外)
数据与方法
api: https://vuejs.org/v2/api/#Instance-Properties
注意:当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时就已经存在于
data
中的属性才是响应式的
这里唯一的例外是使用
Object.freeze()
,这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。Object.freeze(obj) 方法可以冻结一个对象。
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` 改变后调用
})
我的理解: 这些API 也就是Vue提供了能够直接访问 Vue实例对象的参数的。
生命周期钩子
api: https://vuejs.org/v2/guide/instance.html#Instance-Lifecycle-Hooks
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
注意:不要在选项属性或回调上使用箭头函数,比如
created: () => console.log(this.a)
或vm.$watch('a', newValue => this.myMethod())
。因为箭头函数并没有this
,this
会作为变量一直向上级词法作用域查找,直至找到为止,经常导致Uncaught TypeError: Cannot read property of undefined
或Uncaught TypeError: this.myMethod is not a function
之类的错误。
官方提示:下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。
自己的理解:就是在生命周期的各个阶段,调用对应的回调函数,能够进行相关的操作。给用户提供了很多操作底层的机会。生命周期图中(标红部分)每个生命周期阶段都对应的一个点,也就是相同名字的对应回调函数。
模板语法
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。
在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
插值
文本 (Mustache 语法
{{}}
)数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值
<span>Message: {{ msg }}</span>
原始HTML(
v-html
指令)<p>Using v-html directive: <span v-html="rawHtml"></span></p>
注意:你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。
Attribute (
v-bind
指令)<div v-bind:id="dynamicId"></div>
<button v-bind:disabled="isButtonDisabled">Button</button>
对于布尔 attribute (它们只要存在就意味着值为
true
),v-bind
工作起来略有不同,在这个例子中.如果
isButtonDisabled
的值是null
、undefined
或false
,则disabled
attribute 甚至不会被包含在渲染出来的 `` 元素中。使用-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 } }}
注意:模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如
Math
和Date
。你不应该在模板表达式中试图访问用户定义的全局变量。
指令
指令 (Directives) 是带有
v-
前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式 (v-for
是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
参数
一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,
v-bind
指令可以用于响应式地更新 HTML attribute。动态参数
从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:
<!--
注意,参数表达式的写法存在一些约束,如之后的“对动态参数表达式的约束”章节所述。
-->
<a v-bind:[attributeName]="url"> ... </a>
<!--
在 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>
缩写
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>
计算属性和侦听器
计算属性(computed)
对于任何复杂逻辑,你都应当使用计算属性。
基础例子
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
结果:
Original message: "大娃测试"
Computed reversed message: "试测娃大"
这里我们声明了一个计算属性
reversedMessage
。我们提供的函数将用作属性vm.reversedMessage
的 getter 函数:console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'
你可以打开浏览器的控制台,自行修改例子中的 vm。
vm.reversedMessage
的值始终取决于vm.message
的值。你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道
vm.reversedMessage
依赖于vm.message
,因此当vm.message
发生改变时,所有依赖vm.reversedMessage
的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解。大娃理解:computed:这个VM的系统属性就是定义计算属性的。里面的方法自定义。实现了动态绑定data,还实现了缓存。调用属性名,就等于调用这个计算方法的getter()方法。
计算属性缓存VS方法
注意:我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要
message
还没有发生改变,多次访问reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数。相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。
计算属性VS侦听属性
我现在还不知道侦听属性 watch 有什么用。不过能看到计算属性的缓存优势
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
计算属性的setter
计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :// ...
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 会被调用,vm.firstName
和vm.lastName
也会相应地被更新。
侦听器(Watchers)
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过
watch
选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
}
具体案例,查询官网给出的案例
大娃理解:监听器,功能也如字面意思,监听。当监听的属性发生变化的时候,做出指定的操作。
这里监听的属性可以是计算属性。
Class与Style绑定
补充概念:Truthy(真值) https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy
在 JavaScript 中,truthy(真值)指的是在布尔值上下文中,转换后的值为真的值。所有值都是真值,除非它们被定义为 假值(即除
false
、0
、""
、null
、undefined
和NaN
以外皆为真值)。
绑定HTML Class
对象语法
可以直接定义在模板中
可以:一个对象
<div v-bind:class="{ active: isActive }"></div>
或者:两个对象
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
data: {
isActive: true,
hasError: false
}
或者:也可以不定义在模板中
<div v-bind:class="classObject"></div>
data: {
classObject: {
active: true,
'text-danger': false
}
}
或者:使用计算属性
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}数组语法
我们可以把一个数组传给
v-bind:class
//方式1:
<div v-bind:class="[activeClass, errorClass]"></div>
//方式2:三元表达式+数组
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
//方式3:JS模板+数组
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
用在组件上(需要对Vue组件有了解)
其实就是在说:自定义的模板组件,你定义时候带的class样式,默认是替换不掉的
你定义的模板:
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})
然后你用的时候再加class的话
<my-component class="baz boo"></my-component>
会被渲染成这样,累加class的形式(class数据动态绑定形式的也是这样)
<p class="foo bar baz boo">Hi</p>
绑定内联样式
对象语法
<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="[baseStyles, overridingStyles]"></div>
自动添加前缀
当
v-bind:style
使用需要添加浏览器引擎前缀的 CSS 属性时,如transform
,Vue.js 会自动侦测并添加相应的前缀。很nice的配置。 如下所示,自动添加浏览器前缀
-webkit-transition: all 4s ease;
-moz-transition: all 4s ease;
-ms-transition: all 4s ease;
-o-transition: all 4s ease;
transition: all 4s ease;
多重值
从 2.3.0 起你可以为
style
绑定中的属性提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染
display: flex
。
条件渲染
v-if
v-if
指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no
Vue.js——学习笔记(一)的更多相关文章
- Vue.js学习笔记(2)vue-router
vue中vue-router的使用:
- vue.js 学习笔记3——TypeScript
目录 vue.js 学习笔记3--TypeScript 工具 基础类型 数组 元组 枚举 字面量 接口 类类型 类类型要素 函数 函数参数 this对象和类型 重载 迭代器 Symbol.iterat ...
- Vue.js学习笔记:在元素 和 template 中使用 v-if 指令
f 指令 语法比较简单,直接上代码: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" " ...
- Vue.js 学习笔记之二:数据驱动开发
在 Vue.js 框架中,与 HTML 页面元素的交互方式没有像原生 JavaScript 接口那么直接,它是通过先在 HTML 元素标签中嵌入一系列类似于普通标签属性的 Vue 指令属性来绑定数据, ...
- Vue.js 学习笔记之三:与服务器的数据交互
显而易见的,之前的02_toDoList存在着一个很致命的缺陷.那就是它的数据只存在于浏览器端,一但用户关闭或重新载入页面,他之前加入到程序中的数据就会全部丢失,一切又恢复到程序的初始状态.要想解决这 ...
- Vue.js 学习笔记之四:Vue 组件基础
到目前为止,这个系列的笔记所展示的都是一些极为简单的单页面 Web 应用程序,并且页面上通常只有几个简单的交互元素.但在实际生产环境中,Web 应用程序的用户界面往往是由多个复杂的页面共同组成的.这时 ...
- Vue.js 学习笔记之五:编译 vue 组件
正如上一篇笔记中所说,直接使用 ES6 标准提供的模块规范来编写 Vue 组件在很多情况下可能并不是最佳实践.主要原因有两个,首先是市面上还有许多并没有对 ES6 标准提供完全支持的 Web 浏览器, ...
- Vue.js——学习笔记
Vue-自学笔记 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅 ...
- Vue.js 学习笔记 一
本文的Demo和源代码已放到GitHub,如果您觉得本篇内容不错,请点个赞,或在GitHub上加个星星! https://github.com/zwl-jasmine95/Vue_test 以下所有知 ...
随机推荐
- 【Java杂货铺】用Security做权限极简入门
原来大多数单体项目都是用的shiro,随着分布式的逐渐普及以及与Spring的天生自然的结合.Spring Security安全框架越受大家的青睐.本文会教你用SpringSecurity设计单项目的 ...
- BaseAdapter教程(2) BaseAdapter的notifyDataSetChanged动态刷新
遇到了这麽一个需求,ListView滑到最底,然后会自动在底部加入新的Cell,实现动态刷新. 1. 首先,为ListView加上setOnScrollListener. lvHomePostItem ...
- SAP 配置表根据输入的值带出描述
在SAP客制功能需求中,为了程式的灵活配置采用配置表的形成,使后期使用中不需要更改源代码实现功能的增加.在配置表的使用过程中,有时候会有这样的需求:在配置中输入或选择了编码,根据编码带出描述.以下详细 ...
- Ubuntu中Unable to acquire the dpkg frontend lock解决方案
根据百度总结三种方式:第三种解决了我的问题 1. ps -e|grep apt-get 结果:6965 ? 00:00:01 apt-get 执行:sudo kill 6965 #强制解锁,会删除文件 ...
- 在Linux生成公钥后,使用git拉代码仍然需要密码的问题
一顿回车生成公钥后,用git拉代码还是需要输入密码 原因比较简单,在于.ssh 文件夹 及 authorized_keys文件的权限问题,全部修改为 700 即可,用下面命令 chmod -R 700 ...
- numpy矩阵运算--矩阵乘法
1)元素对应相乘,使用 multiply 函数或 * 运算符来实现 a = np.array([2,2,2])b = np.array([3,3,3]) c1 = a*a c1 array([4, 4 ...
- 数据中台技术汇(二)| DataSimba系列之数据采集平台
继上期数据中台技术汇栏目发布DataSimba——企业级一站式大数据智能服务平台,本期介绍DataSimba的数据采集平台. DataSimba采集平台属于DataSimba的数据计算及服务平台的一部 ...
- va_list、va_start和va_end使用
我们知道va_start,va_arg,va_end是在stdarg.h中被定义成宏的,由于1.硬件平台的不同 2.编译器的不同,所以定义的宏也有所不同. 在ANSI C中,这些宏的定义位于stdar ...
- Mac环境下安装Redis
转自:http://www.jianshu.com/p/6b5eca8d908b -安装 下载安装包 redis-3.0.7.tar.gz 官网地址:http://redis.io/download ...
- 最小生成树 HihoCoder-1097、1098、1109(最小生成树算法)
太久没写最小生成树了,快忘光了.这几天回顾了一下 最小生成树一·Prim算法 AC G++ 369ms 17MB #include "cstdio" using namespace ...