吐血整理-Vue学习笔记
2020-06-03 04:57
375 查看
学习一个新内容时,最好的方式就是跟随官方文档来进行学习。
以下的学习也是基于Vue的官方文档:https://cn.vuejs.org/v2/guide/
文章目录
- 概述
- 1、引入
- 2、基本使用
- 3、vue的页面标签
- 4、组件
- 5、实例属性与方法
- 6、生命周期-主要有几个周期相关的方法
- 7、模板语法
- 8、计算属性
- 9、对象语法
- 10、条件渲染
- 11、列表渲染
- 12、监听事件
- 13、表单控件绑定
- 14、深入原理
- 15、注册自定义指令
- 待续
概述
现在说到前端三大框架,一般都是指这三个:
Angular、
React、
Vue。
其中,
Angular是一整套的前端解决方法,相比
React和
Vue要厚重得多,所以相对来说学习成本也就更高。但熟悉了之后的
Angula仍是很多大型前端的很好的一个选择。
而
React与
Vue,相对来说,
React更接近原生、更易于理解。
而
Vue相对而言封装了更多的方法,提供了更便捷的使用。而且
Vue的学习曲线相对于这三大框架来说,可以说是最简单的。这可能与
Vue是国内作者开发,更加贴近国人使用习惯也有一定关系吧。
注: Angular是Google开发 React是FaceBook开发
之前项目用到了Vue,当时学习Vue的时候做了笔记并进行了分享,故现将当时的笔记稍微整理一下发上来回顾一下,互相学习。
1、引入
<script src="https://unpkg.com/vue"></script>
2、基本使用
界面上定义标签
<div id="app"> {{ message }} </div>
js里定义Vue,以操作vue实体的方式操纵页面元素。
var app = new Vue({ el: '#app', //用字段代表页面标签 data: { //数据实体,以下数据直接通过{{}}引用 message: 'Hello Vue!', //对应界面上的{{message}} seen: true, test1: 1, todos: [{a:1,b:2},{a:1,b:2},{a:1,b:2}], isActive: true, hasError: false, activeClass: 'active', errorClass: 'text-danger' }, method: { //方法体 reverseMessage: function () { this.message = this.message.split('').reverse().join(''); } }, computed: { //计算属性,可以作为根实体属性一样引用 active: function(){ return true; }, message2: function(){ return this.message + "_2"; } }, watch: { //监控实体元素的值变动 val当前新值, oldVal 改变前的值 message: function (val, oldVal) { this.clearData(); this.refresh(); } } });
3、vue的页面标签
v-bind:title="message"
:绑定标签的title事件,message即为上面定义的message,此种方式可以直接引用。无法这么使用:title={{message}}
v-if="[表达式]"
:vue的if 语句,直接替换[表达式]即可,如:v-if="seen"
、v-if="test1 == 1"
, 表达式通过,则显示该标签,否则不显示v-for="todo in todos"
:循环,使用如下:<li v-for="todo in todos">{{ todo.a }}</li>
:带上了for所在的标签进行循环<template v-for="item in listData"><li>{{ todo.a }}</li></template>
:循环template内的内容
v-on:绑定一个事件监听器, 如
<button v-on:click="reverseMessage">逆转消息</button>
v-model:实现表单输入和应用状态之间的双向绑定,如:
<p>{{ message }}</p>
<input v-model="message">(修改input内的值,对应message的值就修改,于是
<p>内容就会改变)
v-once:一次性地插值,当数据改变时,插值处的内容不会更新, 如:
<p v-once>{{ message }}</p>
v-html:直接替换html,而不是数据值,如:
<div v-html="rawHtml"></div>
4、组件
组件是可复用的 Vue 实例,且带有一个名字。在这个例子中是
<button-counter>。
// 定义一个名为 button-counter 的新组件 Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' })
语法为:Vue.component([组件名], [组件参数], template),其中 template 即为组件的内容填充模板。
我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用,且与 new Vue 接收相同的选项:
<!-- 界面上调用组件 --> <div id="components-demo"> <button-counter></button-counter> </div>
调用<button-counter>标签,就会自动写入上面定义里模板template里的内容
//js中使用自定义组件 new Vue({ el: '#components-demo' })
注:
- 组件可以复用,产生多个实例
data
必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。(即组件设置的值是全局的,通过方法返回的,则可以生成多个副本)
5、实例属性与方法
vue 实例暴露了一些有用的实例属性与方法。这些属性与方法都有前缀
$,以便与代理的
data属性区分。
如:
app.$el:获取Vue实例关联的页面标签元素(详情参照步骤2)。
app.$el === document.getElementById('app')(输出结果为:true)
//示例代码: var app = new Vue({ el: '#app', //用字段代表页面标签 data: { //数据实体,以下数据直接通过{{}}引用 message: 'Hello Vue!', //对应界面上的{{message}} } });
6、生命周期-主要有几个周期相关的方法
beforeCreate: 初始化标签、方法前
在实例初始化之后,数据观测(data observer)和event/watcher 事件配置之前调用
created: 初始化标签、方法后
实例已经创建完成之后被调用,在这一步,实例已经完成以下的配置:数据观测(data observer)、属性和方法运算、watch/event 事件回调
beforeMount: 创建了vue实体的el标签前
在挂载开始之前被调用,相关的 render 函数首次被调用
mounted:
el被新创建的
vm.$el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个文档内元素,当 mounted 被调用时
vm.$el也在文档内。
beforeUpdate:
(数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。)
updated:
(由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。)
activated: (keep-alive 组件激活时调用。)
deactivated: (keep-alive 组件激活时调用。)
beforeDestroy:vm.$destroy()调用前
(实例销毁之前调用。在这一步,实例仍然完全可用)
destroyed:
(Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。)
7、模板语法
- 绑定数据:任意位置使用
{{}}
, 如<p>{{message}}</p>
:将数据解释为纯文本 - 输出真正的 HTML,如:
<div v-html="rawHtml"></div>
:div的内容会被替换成为rawHtml,直接作为HTML。注意,你不能使用v-html
来复合局部模板 - 标签属性绑定,如:
<div v-bind:id="dynamicId"></div>
即为:<div id="dynamicId"></div>
<a v-bind:href="url"></a>
即为:<a href="url"></a>
等等 - 正常的JavaScript表达式都可以,如:
{{ message.split('').reverse().join('') }}
等。
有个限制就是,每个绑定都只能包含单个表达式:
{{ if (ok) { return message } }}
不会生效,
{{ok ? message : ""}}
才可以 - 缩写:
v-bind:id="1"
-->:id="1"
v-on:click="test"
-->
@click="test"
8、计算属性
就是调用一个有返回值的方法,将这个方法名当为一个参数来使用。这个方法名的使用,就是计算属性。
如:
{{message}}是直接用
data绑定的一个值,但假设现在
message需要通过一些实时计算等,来生成最终值,那就可以用到计算属性。
计算属性关键字为:
computed,
写法为:在声明Vue的时候进行定义,每个计算属性,都用写方法的方式进行定义,如下:
(
message2在界面上类似
message的方式进行调用:
{{message2}},这个message2会实时根据message的变化而变化。)
//示例代码: var app = new Vue({ el: '#app', //用字段代表页面标签 data: { //数据实体,以下数据直接通过{{}}引用 message: 'Hello Vue!', //对应界面上的{{message}} }, computed: { //计算属性,可以作为根实体属性一样引用 active: function(){ return true; }, message2: function(){ return this.message + "_2"; } }, });
9、对象语法
v-bind:class
: 通过[class名]:[true/false]
,动态添加class。
即:
前的class根据:
后的true/false决定是否加载, 还可以与前面的正常class并存,如:
<div class="static" v-bind:class="{ active: true, 'text-danger': false }"></div>
等同于<div class="static" v-bind:class="static active"></div>
(注:active是数据值,也可以是计算属性)<div v-bind:class="[activeClass, errorClass]">
:语法数组,
即v-bind:class=""
里面可以通过一个式子带入多个class- 组件-例子:(参考4)
Vue.component('my-component', {template: '<p class="foo bar">Hi</p>'})
用component
声明,第一个参数my-component
为模板上的标签名,第二个参数里的template
字段,代表需要替换上模板里的具体内容,且替换后原本模板上的属性也会保留,如class等。
示例:
//界面上 <my-component class="baz boo"></my-component> //js里 Vue.component('my-component', { template: '<p class="foo bar">Hi</p>' }) //最终界面被渲染为 <p class="foo bar baz boo">Hi</p>
v-bind:style
:绑定style, 类似class。且,使用需要特定前缀的 CSS 属性时,如transform
,Vue.js 会自动侦测并添加。
可以使用data绑定,也可以使用计算属性,都是直接写入就可以,不需要带上{{}}
。
示例:
<!-- activeColor、fontSize 是data绑定数据 --> <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> <!-- styleObject 是计算属性绑定数据 --> <div v-bind:style="styleObject"></div>`
10、条件渲染
v-if
:用法如下:
<h1 v-if="ok">Yes</h1> <h1 v-else>No</h1> <div v-if="type === 'A'">A</div> <div v-else-if="type === 'B'">B</div> <div v-else>Not A/B/C</div>
注:
v-else元素必须紧跟在带
v-if或者
v-else-if的元素的后面,否则它将不会被识别。
- 用
key
管理可复用元素:
如下,只显示其中一个template
,但对于input
已输入的值,不管切换显示哪个template
,已经输入的input
的值都会传承下来,只会替换input
的placeholder
值。
换句话说,就是template
里面相同的标签不会重新渲染,只会相应的替换掉里面的不同。
key
的作用,就是给Vue去区分两个template
的input
是不是同一个。这样,切换template
的时候,不同的input
就会重新渲染,即删除了原来的input
,重新写了一个input
。
<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address"> </template> <!-- 改后: --> <template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username" key="t1"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address" key="t2"> </template>
-
v-show
:类似v-if
,通过条件控制后面内容显不显示。
但v-show=false
,是将控件设置为display:none
,
而v-if=false
,是直接不执行那一块的代码了。
所以:
v-if
有更高的切换开销,因为每切换一次,就得渲染 / 删除一次元素。
而v-show
有更高的初始渲染开销,即初始化的时候就已经渲染好了元素,只是根据v-show
的结果来设置display
而已,此后的切换,也只是修改display
值。
因此:
如果需要非常频繁地切换,则使用v-show
较好;
如果在运行时条件不太可能改变,则使用v-if
较好。 -
v-for
:具有比v-if
更高的优先级
11、列表渲染
v-for="(item, index) in items"
:item
是当前元素,index
是当前序号,items
是列表内容,也可以是计算属性,还可以是带返回值的方法.- 同前面所说的,直接标签内含
v-for
,标签本身也一起循环,如:<p v-for="item in items">{{item.a}}</p>
。
使用template
,则里面的内容才进行循环,如:<template v-for="item in items"><p>{{item.a}}</p></template>
<li v-for="todo in todos" v-if="!todo.isComplete">{{ todo }}</li>
:for
和if
可以在同一标签内使用,且for
优先级高于if
key
值: 用v-for
正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有唯一 id。
示例:
<div v-for="item in items" :key="item.id"> <!-- 内容 --> </div>
-
由于 JavaScript 的限制, Vue 不能检测以下变动的数组:
1、当你利用索引直接修改一个值时,例如:vm.items[indexOfItem] = newValue
2、当你直接修改数组的长度时,例如:vm.items.length = newLength
为了解决第一类问题,以下两种方式都可以实现和vm.items[indexOfItem] = newValue
相同的效果, 同时也将触发状态更新:Vue.set
方法:Vue.set(items, indexOfItem, newValue)
Array.prototype.splice
方法:items.splice(indexOfItem, 1, newValue)
为了解决第二类问题,你可以使用
splice
方法:items.splice(newLength)
12、监听事件
click
:直接在引号中可以书写方法,如:<button v-on:click="counter += 1">增加1</button>
$event
:当前事件,类似this
的使用。如:<button v-on:click="warn('Form cannot be submitted yet.', $event)">
- 一些其他的事件监听:
keyup.enter
、keyup.tab
、keyup.esc
等
写法示例:<input v-on:keyup.13="submit">
13、表单控件绑定
使用
v-model在元素上指定,可以与其他地方创建数据绑定,即修改一个地方的值,其他地方也对应会更新最新值。
- 单个勾选框,绑定字段为:
checked
。根据勾选状态,checked
值对应为true/false
,在label
里面,对应显示true/false
。示例如下:
<input mtype="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked}}</label>
- 如果是多个复选框之类的,
v-model=[数组]
,如:checkedNames
是数组,勾选返回为checkBox
的value
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label>
- 下拉: 返回value,如果没有显式设置value,返回text
<select v-model="selected"> <option disabled value="1">请选择</option> <option value="11">A</option> <option value="12">B</option> <option value="13">C</option> </select>
- 动态选项,用
v-for
渲染option选项,数组设置好value和text, selected为当前选中值
<select v-model="selected"> <option v-for="option in options" v-bind:value="option.value">{{ option.text }}</option> </select> <span>Selected: {{ selected }}</span>
new Vue({ el: '...', data: { selected: 'A', options: [ { text: 'One', value: 'A' }, { text: 'Two', value: 'B' }, { text: 'Three', value: 'C' } ] } });
- 通过
v-bind
绑定动态值到标签下:
<!-- 勾选框,只会返回true/false,但v-bind:true/false后,可以根据true/false返回其他 --> <!-- 如以下,true返回a,false返回b --> <input type="checkbox" -model="toggle" v-bind:true-value="a" v-bind:false-value="b">
- 修饰符:
lazy
、number
、msg
,例:(msg
为绑定的字段)
v-model.lazy="msg"
:在 “change” 事件时更新msg
值,而不是平时跟着"input" 填写内容而更新
v-model.number="msg
:自动将msg
值转为 Number 类型
v-model.trim="msg"
:自动过滤msg
值的首尾空格
14、深入原理
- 把一个普通 JavaScript 对象传给 Vue 实例的
data
选项,Vue 将遍历此对象所有的属性,并把这些属性全部转为getter/setter
。 - 每个组件实例都有相应的
watcher
实例对象,当依赖项的setter
被调用时,会通知watcher
重新计算 - Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行
getter/setter
转化过程,所以属性必须在
data
对象上存在才能让 Vue转换它,这样才能让它是响应的
var vm = new Vue({ data:{a:1} }) vm.b = 2; //可行的 vm.data.b=2; //是不行的 Vue.set(vm.someObject, 'b', 2); //但可以调用:Vue.set(object, key, value) this.$set(this.someObject,'b',2); //或调用:this.$set(object, key, value)
- 异步DOM更新:如果同一个
watcher
被多次触发,只会一次推入到队列中。
如果你想在 DOM 状态更新后做点什么,可以在数据变化之后立即使用Vue.nextTick(callback)
。这样回调函数在 DOM 更新完成后就会调用。
//组件内使用 vm.$nextTick() Vue.nextTick(function () { vm.$el.textContent === 'new message'; // true })
15、注册自定义指令
- 除了核心功能默认内置的指令 (
v-model
和v-show
),Vue 也允许注册自定义指令。
可以为全局指令,也可以为局部指令,如:
//局部指令 directives: { focus: { // 指令的定义。例: //钩子函数:当绑定元素插入到 DOM 中。 inserted: function (el) { el.focus() } } } //全局指令 Vue.directive('focus', { // 钩子函数:当绑定元素插入到 DOM 中。 inserted: function (el) { // 聚焦元素 el.focus() } }) //使用的语法为:v-focus property <input v-focus>
- 自定义指令的时候,有几个钩子函数可选:
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。
componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind
:只调用一次,指令与元素解绑时调用。
注:VNode简单来说,就是Vue需要渲染的界面上的节点及其子节点,称为虚拟节点(virtual node),简称VNode。
示例:(效果:在div中输出钩子函数的一些参数值)
<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
Vue.directive('demo', { bind: function (el, binding, vnode) { var s = JSON.stringify; el.innerHTML = 'name: ' + s(binding.name) + '<br>' + 'value: ' + s(binding.value) + '<br>' + 'expression: ' + s(binding.expression) + '<br>' + 'argument: ' + s(binding.arg) + '<br>' + 'modifiers: ' + s(binding.modifiers) + '<br>' + 'vnode keys: ' + Object.keys(vnode).join(', '); } }) new Vue({ el: '#hook-arguments-example', data: { message: 'hello!' } })
示例解析:
指令钩子函数会被传入以下参数:
el
:指令所绑定的元素,可以用来直接操作 DOM。binding
:一个对象,包含以下 property:name
:指令名,不包括v-
前缀。value
:指令的绑定值,
例如:v-my-directive="1 + 1"
中,绑定值为 2。oldValue
:指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式,
例如v-my-directive="1 + 1"
中,表达式为"1 + 1"
。arg
:传给指令的参数,可选,
例如v-my-directive:foo
中,参数为"foo"
。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为{ foo: true, bar: true }
。
vnode:Vue 编译生成的虚拟节点。
oldVnode:上一个虚拟节点,仅在
update和
componentUpdated钩子中可用。
注:除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的
dataset来进行。
待续
以上是整理出来的一部分内容,结合官方文档,可学习初步进行vue的使用了。
之后会再整理出路由等更加深入一些的内容进行分享。
相关文章推荐
- Vue2.x源码学习笔记-源码目录结构整理
- Vue2.x源码学习笔记-Vue实例的属性和方法整理
- css学习笔记之兼容&bug(吐血整理)
- Vue2.x源码学习笔记-Vue静态方法和静态属性整理
- Vue1.0基础学习笔记整理
- vue.js入门学习笔记整理
- 【算法】数据结构与算法分析学习笔记——各类二叉查找树的吐血整理
- python学习笔记--报错整理
- Linux Shell脚本学习 笔记整理
- Vue学习笔记十二:安装和使用路由
- 韩顺平PHP学习视频笔记整理001html简介1
- C#学习笔记整理_变量等基础语法(必看篇)
- 在某网课学习前端笔记整理js篇19-js对象、this指针、对象的一些方法
- c++学习笔记序列之错误码整理(不断更新中)
- Vue.js学习笔记(三)
- vsftp服务器搭建-学习笔记整理
- iOS学习笔记-精华整理
- 深度学习数学基础笔记整理(一)
- java学习笔记知识点整理02
- java同步与异步的学习笔记整理