Vue.js中文API阅读笔记及自己踩过的坑

       emmmmm,,之前因为开项目来不及仔细读一遍,只能是用到什么找什么,然而深感对vue了解的无力(ŎдŎ;)。。还有一个周开新项目,恩,认真看一哈!( ̄▽ ̄)
【本文并没有讲解全部API,因为太多了。。总结了部分我觉得重要的点加以分析】
传送门:Vue.js中文API

  1. Vue参考MVVM模式,使用vm (ViewModel 的简称)来表示Vue实例

       vue是一个虚拟DOM的,以数据驱动为核心的前端框架。数据驱动也可以称为响应式系统,当属性的值发生变化时,视图都会“及时响应”,并更新相应的新值。

  1. 实例生命周期钩子函数

       每个 Vue 实例在被创建之前,都要经过一系列的初始化过程,例如,Vue 实例需要设置数据观察(set up data observation)、编译模板(compile the template)、在 DOM 挂载实例(mount the instance to the DOM),以及在数据变化时更新 DOM(update the DOM when data change)。在这个过程中,Vue 实例还会调用执行一些生命周期钩子函数,这样用户能够在特定阶段添加自己的代码。

Vue生命周期

       (图可能不是很清晰,小伙伴们可以参考原图

  • 对于数据的操作,比如props、data、computed的初始化都是在beforeCreate与created之间完成的,所以不了解的时候很可能会出现在别的钩子操作数据而产生奇奇怪怪的问题。
  • 有一点要注意, 一般情况下vue组件总是会走完全部的生命周期的,即使你在created或者其他早期的生命周期钩子中使用了路由跳转或者location.herf重定向。
  • 一些因生命周期问题而导致无法使页面刷新的问题有如下解决方案:
    ①this.nextTick({ })具体使用方法请移步传送门
    ②vuex
    ③setTimeout(code,millisec) 【可以强制推迟页面加载xx毫秒,强烈不推荐,暂缓之计,具体病因还是要具体解决】
  • 生命周期钩子是一个很强大的功能,可以很好地处理挂载以及异步加载相关的事件,在特定阶段执行特定的代码,比如某几张图的出现顺序、比如axios请求数据来异步刷新等。
  • 注意,任何生命周期钩子 中 this 上下文都会指向调用它的 Vue 实例。

关于生命周期具体理解推荐一篇文章来自segmentfault

3. 关于computed和watcher,留个flag,汇总一下再写

4. 修饰符(modifier)是以 . 表示的特殊后缀,表明应当以某种特殊方式绑定指令。

       关于修饰符,请移步我的一篇搬运文章☞ Vue修饰符详解

5. 渲染

       1. 根据条件进行渲染:v-if与v-show
  • v-if与v-show可以对内容进行灵活的选择性加载,是使用比较多的指令。
           其二者的区别是,v-if是“真实”的条件渲染,因为它会确保条件块(conditional block)在切换的过程中,完整地销毁(destroy)和重新创建(re-create)条件块内的事件监听器和子组件。且v-if是惰性的(lazy),如果在初始渲染时条件为 false,它不会执行任何操作。直到在条件第一次变为 true 时,才开始渲染条件块。
           相比之下,v-show 要简单得多 - 不管初始条件如何,元素始终渲染,并且只是基于 CSS 的切换。
           通常来说,v-if 在切换时有更高的性能开销,而 v-show 在初始渲染时有更高的性能开销。因此,如果需要频繁切换,推荐使用 v-show,如果条件在运行时改变的可能性较少,推荐使用 v-if。
    v-if的渲染控制
       2. 列表渲染:v-for
  • 在 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' }
    ]
  }
})

结果:
  • 也可以使用 v-for 来遍历对象的属性,接着提供第二个参数,作为对象的键名(key),然后第三个参数作为索引(index):
<div v-for="(value, key, index) in object">
  {{ index }}. {{ key }}: {{ value }}
</div>
new Vue({
  el: '#v-for-object',
  data: {
    object: {
      firstName: 'John',
      lastName: 'Doe',
      age: 30
    }
  }
})

结果:

注意,在遍历一个对象时,是按照 Object.keys() 得出 key 的枚举顺序来遍历,无法保证在所有 JavaScript 引擎实现中完全一致。

  • 关于key,下列是API的原文
<div v-for="item in items" :key="item.id">
  <!-- content -->
</div>
推荐在使用 v-for 时,尽可能提供一个 key,除非迭代的 DOM 内容足够简单,
或者你是故意依赖于默认行为来获得性能提升。
由于这是 Vue 识别节点的通用机制,因此 key 并不是仅限于与 v-for 关联,
我们将在之后的指南中看到,key 还可以其他场景使用。

因为没有用到过所以不是很理解,给个flag后续了解。

  • 带有v-if的v-for
    当它们都处于同一节点时,v-for 的优先级高于 v-if。这意味着,v-if 将分别在循环中的每次迭代上运行。当你只想将某些项渲染为节点时,这会非常有用,如下:
<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo }}
</li>
  • 关于v-once
    用法:<span v-once></span>
    在API中给出的建议是性能优化,事实也确实如此,不过需要注意的是,用v-once指令修饰的html内容在加载的时候会且只会加载一次

       划重点!!!!

       3. 数组变化检测(Array Change Detection)

       Vue 将观察数组(observed array)的变化数组方法(mutation method)包裹起来,以便在调用这些方法时,也能够触发视图更新。这些包裹的方法如下:

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

由于 JavaScript 的限制,Vue 无法检测到以下数组变动:

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

       所以,使用Vue.set(example1.items, indexOfItem, newValue)来解决第一个问题,
使用example1.items.splice(indexOfItem, 1, newValue)来解决第一和第二个问题。
这两种方法可以通过响应式系统触发状态更新。

       4. 对象变化检测(Array Change Detection)

受现代 Javascript 的限制, Vue 无法检测到对象属性的添加或删除:

var vm = new Vue({
 data: {
  a: 1
 }
})
// `vm.a` 是响应的

vm.b = 2
// `vm.b` 不是响应的

       Vue 不允许在已经创建的实例上,动态地添加新的根级响应式属性(root-level reactive property)。然而,可以使用 Vue.set(object, key, value) 方法,将响应式属性添加到嵌套的对象上。例如:

var vm = new Vue({
 data: {
   userProfile: {
     name: 'Anika'
   }
 }})

       可以向嵌套的 userProfile 对象,添加一个新的 age 属性:
       Vue.set(vm.userProfile, 'age', 27)
       还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:
       vm.$set(this.userProfile, 'age', 27)

       这是刚接触Vue的时候踩到过的一个大坑,现在想起来还头皮发麻
∑(゚Д゚ノ)ノ

6. DOM 模板解析

当时用DOM模板时,会受到一些来源于HTML的限制,比如,这种写法是报错的:

<table>
  <!--my-row是自定义模板-->
  <my-row>...</my-row>
</table>

解决方案:

<table>
  <tr is="my-row"></tr>
</table>

is属性请自行百度。

敲黑板

在使用以下字符串模板之一的场景中,这些限制将不再适用:

  • <script type="text/x-template">
  • JavaScript 内联模板字符串
  • .vue 组件
所以,用.vue吧,毕竟用的就是vue框架233333_(:з」∠)_

7. 组件复用

组件(component)是 Vue 最强大的功能之一。组件可以帮助你扩展基本的 HTML 元素,以封装可重用代码。

在编写组件时,记住是否要复用组件有好处。一次性组件跟其它组件紧密耦合没关系,但是可复用组件应当定义一个清晰的公开接口。

Vue 组件的 API 来自三部分 - props, events 和 slots :

  • Props 允许外部环境传递数据给组件
  • Events 允许组件对外部环境产生副作用(side effects)
  • Slots 允许外部环境将额外的内容组合在组件中。

8. 组件的组合与通信

组件,意味着组合在一起使用的元件,多数场景是父子关系:组件 A 可以在自己的模板中使用组件 B。这就必然的需要彼此相互通信:父组件可能会向下传递数组给子组件,然后子组件也可能会将自身发生的变化通知到父组件。然而,重要的是,为了尽可能将父子组件解耦,需要有一个定义清晰的接口。定义清晰的通信方式,可以确保组件可以相对隔离地组织代码,以及合乎逻辑易于推断,从而使它们更加易于维护,并且可能更加易于复用。

vue的大方面的功能核心就是组件,正是组件的组合嵌套复用构成了快速且多样的vue项目生态圈,而组件通信又是组件中比较重要的知识点。

  1. 父向子组件:

    • 在子组件中添加props(既可以传递数据也可以传递方法)
      常用形式<child :msg = "parentMsg"/>
      含有路由出口的使用形式<router-view :propsdata="data"/>
    • this.$broadcast 调用子组件方法(子组件在events中写被调用方法)
    • 父组件通过this.$ref获得子组件的引用
      【$refs 只在组件渲染完成后才填充,并且它是非响应式的。它仅仅作为一个直接访问子组件的应急方案 - 应当避免在模板或计算属性中使用 $refs。】
    • 使用this.$children()获得子组件的Vue实例
  2. 子向父组件:

    • this.$emit (父组件在methods中写被调用方法,并通过@event绑定到子组件) ,子组件中通过这种方法传递数给父组件同时激活父组件的被调用方法。
    • this.$dispath (父组件在events中写被调用方法)
    • 在子组件中添加插槽slot,父组件可以向子组件中插入模板 <template/> ,通过slot-scope获得子组件返回的值
    • 使用this.$parent获得父组件Vue实例 (this.$root获得根组件的Vue实例)

一点补充:在某些场景中,我们可能需要对一个 prop 进行「双向绑定」 - 事实上,这个功能在 Vue 1.x 中已经由 .sync 修饰符实现。但是在2.0中移除,在2.3.0+中以语法糖的形式再次加入。虽然用的不多,如果想了解请移步API

  1. 通过bus.js或者自身的vue实例来进行不同组件之间的数据传递
    • 通过new一个Vue对象作为通信的桥梁(bus.$emit() => bus.$on())
    • 自身的vue实例(this.$emit() => this.$on())
  2. Flux以及Vuex(全局单例模式)同时也可用于解决不同组件之间的通信问题(解决了繁杂事件订阅和广播)
  3. 路由传参
    这里要注意,第一种方式是无法传参的,要传参必须通过第二种方式,即以 name 的形式而不能以路径的形式。所以在路由中的定义如下第三张图。
    不带参
    带参
    路由表中的定义

关于slot,与props相似,简单来说就是props把数据扔到子组件中,slot把html扔到子组件中。关于slot留个flag后续写个专栏具体补充。。。

请注意,props是单向数据流,按照自上而下单向流动方式构成

9. 动态组件

  • 简单来说,与v-bind动态选择css一个样子,根据父组件给的变量决定显示哪个组件,或者都不显示。
  • 使用方式:<component v-bind:is="组件名"></component>
  • 有一点需要注意,像v-if一样,动态加载组件是需要重渲染的,所以如果想避免重新渲染可以添加keep-alive属性来保持已渲染的组件不被移除。
    <component v-bind:is="组件名" keep-alive></component>
  • activate延迟加载
    activate是和data等属性平级的一个属性,形式是一个函数,函数里默认有一个参数,而这个参数是一个函数。
    如下实例:
data(){
    return{
      //...
    }
},
activate (done) { //执行这个参数时,才会切换组件  
    var self = this;  
    // 
    axios.get("/test", function (data) {    
    self.hello = data;  
    done(); //ajax执行成功,切换组件  
    })  
}  

注意:
【1】只有在第一次渲染组件时,才会执行activate,且该函数只会执行一次(在第一次组件出现的时候延迟组件出现)

【2】没有keep-alive时,每次切换组件出现都是重新渲染(因为之前隐藏时执行了destroy过程),因此会执行activate方法。

10. 组件杂项

以下全部有待补充,惯例,flaggggggggggggg

  • 异步组件/代码分离
    应用做大了以后可以进行性能优化,后续详细补充
  • 命名规范
  • 组件之间的循环引用
  • 组件库
  • 其他

11. 过渡&动画

概述

过渡和动画可以对页面内容以及用户体验做一些良好的提升,避免生硬的切换效果带来的挫顿感。个人看法:如果不考虑模块化发布或者工程量不是很大,在系统功能完善之后进行过度动画的添加可以对页面逼格进行大幅提升~

从页面中添加(显示)、移除(隐藏)或者更新一些成员的时候,Vue提供了多种的过渡动画来避免生硬的元素转变。包括以下工具:

  • 在 CSS 过渡和动画中自动处理 class
  • 可以配合使用第三方 CSS 动画库,如 Animate.css
  • 在过渡钩子函数中使用 JavaScript 直接操作 DOM
  • 可以配合使用第三方 JavaScript 动画库,如 Velocity.js
单元素/组件的过渡

Vue提供了transition外层包裹容器组件(wrapper component),可以给下列情形中的任何元素和组件添加进入/离开(enter/leave)过渡:

  • 条件渲染(使用 v-if)
  • 条件展示(使用 v-show)
  • 动态组件
  • 组件根节点

一个demo:

<template>
<div id="demo">
  <button v-on:click="show = !show">
    Toggle
  </button>
  <transition name="fade">
    <p v-if="show">hello</p>
  </transition>
</div>
</template>

<script>
new Vue({
  el: '#demo',
  data: {
    show: true
  }
})
</script>

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}

.fade-enter, .fade-leave-to /* .fade-leave-active 在低于版本 2.1.8 中 */ {
  opacity: 0;
}
</style>
其他的予以保留 flaggggg

正在开新项目,闲下来继续更新

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

推荐阅读更多精彩内容

  • Vue 实例 属性和方法 每个 Vue 实例都会代理其 data 对象里所有的属性:var data = { a:...
    云之外阅读 2,204评论 0 6
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,046评论 0 29
  • Vue 框架的入口就是 Vue 实例,其实就是框架中的 view model ,它包含页面中的业务处理逻辑、数据模...
    阿根廷斗牛阅读 909评论 0 2
  • JavaScript 变量可以是局部变量或全局变量。私有变量可以用到闭包。 全局变量 变量声明时如果不使用 var...
    S大偉阅读 339评论 0 0
  • 《诗经》所反映的社会生活内容十分丰富,它包括天文地理,政治经济,祭祀典礼,战争徭役,定都建国,燕飨欢,狩猎...
    熠悦之阅阅读 297评论 0 0