# Vue.js 开发去哪儿网App
(版本:2.5->2.6->3.0)
# 前言
学习方法
- 视频教程带你入门:
初学者如果没有MVVM模式的基础学习Vue,可能初期切换思路有比较大的难度,这个时候可以借助视频教程辅助入门,而如果你对React或者Angular有过工作经验或者足够多的了解,那么可以省略这一步了,直接读官方文档会是更好的选择。 - 细读文档:
Vue的官方文档上基本包含了Vue的所有知识点,文档看透,Vue也就掌握的很好了。 - 高级知识点深究:
Vue中的一些难点,比如说服务器端渲染(SSR),预渲染,高级异步组件,递归组件,Vuex,vue-router,weex这样的内容,这个阶段需要把这些知识一一攻克。 - 源码阶段:
到了这个阶段的同学,基本上可以游刃有余的使用Vue进行项目开发了,接下来就是深挖Vue的实现原理了,你可以通读Vue,Vuex,vue-router这些库的源码,做到从底层理解Vue的设计思路。 - 横向学习:
当你从底层驾驭了Vue,是时候开始扩展你的知识广度了,你可以尝试学习React,Angular等其他框架,横向打通这些框架之间的关联:我们经常说某些框架好,某些框架不好,但是实际上如果你深入学习每个框架,它们都有自己优秀的设计理念和适用场景,只有你对每一个框架有了深入的理解后,才能够横向对比理解框架各自最大的优势。到时候,我相信大家也就不会随便喷其他框架了,Vue也可以用的炉火纯青了。
- 视频教程带你入门:
课程结构
基础内容 ➡️ 基础语法 ➡️ MVVM模式 ➡️ 组件化
生命周期 ➡️ 动画特效
实战项目 ➡️ 环境搭建 ➡️ 使用Git ➡️ 数据模拟 ➡️ 本地开发
联调 ➡️ 真机测试 ➡️ 上线课程知识结构
Axios、Vuex、Stylus、插件
Vue Router、异步组件、递归组件、公用组件
# 基础复习
var app = new Vue({
el:’#app’,
data:{
msg: ‘ hello’
}
})
2
3
4
5
6
实例外引用该vue实例里的数据,这样用:
app.$data.msg
msg是变量名。注意要加$data
绑定属性,传入数据,不用加花括号!如::value="todo"
# v-model原理
引申:v-model原理
(🍎 这篇文章还讲了 “自定义组件怎么实现v-model”)
<input v-model="todo" />
// 等同于
<input :value="todo" @input="todo = $event.target.value" />
2
3
解释:
$event
指代当前触发的事件对象。
$event.target
指代当前触发的事件对象的dom
$event.target.value
就是当前 dom 的 value值
在@input
方法中,value => todo
在:value
中,todo => value
如此,形成了一个闭环,也就是所说的数据的双向绑定。
说明:
这个语法糖必须是固定的,什么意思?
也就是说,满足语法糖规则:属性必须为 value,方法名必须为 input,缺一不可。
# jQuery实现todolist的面向对象写法
function Page(){ }
$.extend(Page.prototype,{
init:function(){
this.bindEvents()
},
bindEvents:function(){
var btn = $("#btn");
btn.on('click',$.proxy(this.handleBtnClick,this));
},
handleBtnClick:function(){
alert('123')
}
})
var page = new Page();
page.init();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# jQuery实现todolist的面向对象写法 FAQ (听课 2-4 课后问答)
this.bindEvents()
和this.handleBtnClick
, 同样是方法,this.handleBtnClick
加上括号为什么会出错?- 前面那个有括号,是执行方法的动作;
后面那个没有括号,它是作为一个方法的参数,是个方法本身,不是执行动作。
- 前面那个有括号,是执行方法的动作;
btn.on("click", $.proxy(this.handleBtnClick, this))
写法,是不是类似于以前 面向过程 写法中 把this赋值给一个变量,把this储存起来?- 是的,它和es6里面的
bind(this)
是一个东西
- 是的,它和es6里面的
三个this是不是都是指向的构造函数的实例?对这三个this都有点蒙。
- 都指向vue实例,vue底层帮你做了绑定
之所以在构造函数的原型里面分三步写出点击事件,没有像dom一样直接获取元素绑定事件,是不是为了方便以后的分节引用?
- 为了方便清空引用
我现在具备js基础知识,但是jquery基本是不怎么会的,想请教一下老师这种情况,边看老师讲的Vue边看jquery文档感觉效率很低,就比如proxy这个用法
$.proxy(this.handleBtnClick,this)
看了文档不太能理解,有么有什么好的学习方法?- 没有好办法,硬着头皮学
$.extend(){}
这是什么方法?- jQuery.extend()方法,$是jQuery的简写。
- 用于将一个或多个对象的内容合并到目标对象,跟vue没有什么关系,这里只是用jquery的方法演示下功能的实现和vue做一个对比。
- JQuery的extend扩展方法 (很具体,讲了原理,还讲了应用。)
$.extend(Page.prototype,{})
与Page.prototype = {}
有什么不同- 建议你打开jquery的代码,搜索
extend
关键字,去尝试看下这个方法的实现源码,很简单的,看过九洞,其实两者差别不大,前者是向prototype上增加内容,后者是直接覆盖prototype - 一个是jquery方法extend向page原型上添加,一个是js原生方法
page.prototype
。
- 建议你打开jquery的代码,搜索
构造函数是什么,怎么用?
- JS 中构造函数和普通函数的区别
- 严格说来,构造函数归属于javascript中的知识部分,你首先需要了解js的构造函数,原型对象,及简单的面向对象的知识,jquery 在老师的编码中,实际只是起到了一个工具的作用,一个是
$.extend()
合并对象,另一个$.proxy()
绑定this指向。 - 我认为理解
$.extend
$.proxy
obj.on
这三个jquery API就OK。 - 老师使用
$.extend
给类Page的原型扩展方法,以便实例对象访问。使用on给btn注册事件。使用$.proxy
规定执行handleBtnClick
函数内部的this指向。
$.proxy
是什么?- jQuery $.proxy() 方法
- $.proxy用法(解决this转移问题)
描述:接受一个函数,然后返回一个新函数,并且这个新函数始终保持了特定的上下文语境。
实例:
强制执行 objPerson 内的 "test" 函数的上下文。
做一下就大致明白,这里不用$.proxy的话,this.name 和 this.age 都取不到值。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>菜鸟教程(runoob.com)</title> <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"> </script> <script> $(document).ready(function(){ var objPerson = { name: "John Doe", age: 32, test: function(){ $("p").after("Name: " + this.name + "<br> Age: " + this.age); } }; $("button").click($.proxy(objPerson,"test")); }); </script> </head> <body> <button>执行 test 函数</button> <p></p> </body> </html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 附加:Javascript简写条件语句
- 史上最全JavaScript常用的简写技巧(推荐)
以下只取部分可能常见常用的。
- 简写变量声明
在定义函数的时候,你可能需要先声明多个变量,例如:
let x;
let y;
let z = 3;
2
3
这时,你可以使用简写的方式节省很多时间和空间,即同时声明多个变量:
let x, y, z=3;
- 简写 if 执行条件 这可能微不足道,但值得一提。在你做if条件检查的时候,其赋值操作可以省略,例如:
if (likeJavaScript === true)
可以简写为:
if (likeJavaScript)
只有当likeJavaScript是真值的时候,以上两个语句才可以替换。如果判断假值,例如:
let a;
if ( a !== true ) {
// do something...
}
2
3
4
可以简写为:
let a;
if ( !a ) {
// do something...
}
2
3
4
- 三元运算符
const x = 20;
let answer;
if (x > 10) {
answer = 'is greater';
} else {
answer = 'is lesser';
}
2
3
4
5
6
7
可以写成:
const answer = x > 10 ? 'is greater' : 'is lesser';
(迷惑:const x = 20 跑哪去了?)
也可以嵌套if语句:
const big = x > 10 ? " greater 10" : x
- 简写短路求值
当给一个变量分配另一个值的时候,你可能想确定初值不是null,undefined或空值。这时,你可以写一个多重条件的if语句:
if (variable1 !== null || variable1 !== undefined || variable1 !== '') {
let variable2 = variable1;
}
2
3
或者可以使用短路求值的方法:
const variable2 = variable1 || 'new';
- 简写 JavaScript 循环方法
当你想使用纯 javascript 而不依赖外库(例如jQuery)的时候,这是非常有用的。
for (let i = 0; i < allImgs.length; i++)
可以简写为:
for (let index in allImgs)
也可以使用Array.forEach:
function logArrayElements(element, index, array) {
console.log("a[" + index + "] = " + element);
}
[2, 5, 9].forEach(logArrayElements);
// logs:
// a[0] = 2
// a[1] = 5
// a[2] = 9
2
3
4
5
6
7
8
# 视图模式
Model-View-Controller(模型-视图-控制器):
用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑.它强制性地使应用程序的输入、处理和输出分开。
最典型的MVC就是JSP +servlet+javabean的模式。
MVVM,m-v-vm
专注于m,vue来实现vm,节约至少30%代码量
vue中VM的实现:虚拟dom,definproperty,可以在课程全部学完之后再去了解。
# 前端组件化
每一个组件就是页面上的一个区域。
我的理解:拼乐高。
(听课 2-5)
# 听课 2-6 使用组件改造todolist
vue.component是创建全局组件的方法,注意是全局组件
如果组件注册的时候这样命名:'TodoItem',引用的时候就可以这样引用:
<todo-item></todo-item>
v-bind 向组件传入一个绑定值,如:
<todo-item v-bind:content="item" v-for="item in list"></todo-item>
把item的内容传给content,
然后子组件就要接收content的内容,用props,然后就可以在子组件的template中引用content了。如:
vue.component('TodoItem',{
props:['content'],
template: "<li>{{content}}</li>"
})
2
3
4
局部组件的使用:
可以在实例外面定义,然后在实例里注册,才能使用(目前来看是跟全局组件一样使用)。如:
var TodoItem = {
props:['content'],
template: "<li>{{content}}</li>"
}
var app = new Vue({
...
components:{
TodoItem: TodoItem
},
...
})
2
3
4
5
6
7
8
9
10
11
12
# 听课 2-7 简单的组件间传值
学了用 v-bind 和 props 从父组件向子组件传值,那如何从子组件向父组件传值呢?
$emit (啊,学过了,老忘 😢),可以传递事件和数据(值)
var TodoItem = {
props:['content'],
template: "<li @click="deleteItem">{{content}}</li>",
methods: {
deleteItem: function () {
$emit("delete")
}
}
}
2
3
4
5
6
7
8
9
子组件想传递给父组件触发的事件,父组件要监听才能触发。
如下,监听deleteItem,监听到时触发父组件里面的delete事件:
<todo-item @delete="deleteItem" v-bind:content="item" v-for="item in list"></todo-item>
这个时候,案例里面想要 在点击某个事项时,可以删掉这个事项,此时如何实现? 思路: 点击在父组件上,触发
v-bind: 简写成 :
# 到vue官网仔细通读“介绍”章节文档
(听课 2-8 章节作业)
答疑:
https://coding.imooc.com/learn/list/203.html
https://coding.imooc.com/learn/questiondetail/61185.html
https://coding.imooc.com/learn/questiondetail/55421.html
https://coding.imooc.com/learn/questiondetail/50428.html
https://coding.imooc.com/learn/questiondetail/123153.html
https://coding.imooc.com/learn/questiondetail/132470.html
https://coding.imooc.com/learn/questiondetail/136091.html
https://coding.imooc.com/learn/questiondetail/127956.html