起步
参考[:](Vue.js 2.0 快速上手精华梳理 - 掘金 (juejin.cn))
建议Vue 2.0 的学习顺序
- 扎实的 JavaScript / HTML / CSS 基本功。这是前置条件。
- 通读官方教程 (guide) 的基础篇。不要用任何构建工具,就只用最简单的 script,把教程里的例子模仿一遍,理解用法。不推荐上来就直接用 vue-cli 构建项目,尤其是如果没有 Node/Webpack 基础。
- 照着官网上的示例,自己想一些类似的例子,模仿着实现来练手,加深理解。
- 阅读官方教程进阶篇的前半部分,到『自定义指令 (Custom Directive) 』为止。着重理解 Vue 的响应式机制和组件生命周期。『渲染函数(Render Function)』如果理解吃力可以先跳过。
- 阅读教程里关于路由和状态管理的章节,然后根据需要学习 vue-router 和 vuex。同样的,先不要管构建工具,以跟着文档里的例子理解用法为主。
- 走完基础文档后,如果你对于基于 Node 的前端工程化不熟悉,就需要补课了。下面这些严格来说并不是 Vue 本身的内容,也不涵盖所有的前端工程化知识,但对于大型的 Vue 工程是前置条件,也是合格的『前端工程师』应当具备的知识。
前端生态/工程化
- 了解 JavaScript 背后的规范,ECMAScript 的历史和目前的规范制定方式。学习 ES2015/16 的新特性,理解 ES2015 modules,适当关注还未成为标准的提案。
- 学习命令行的使用。建议用 Mac。
- 学习 Node.js 基础。建议使用 nvm 这样的工具来管理机器上的 Node 版本,并且将 npm 的 registry 注册表配置为淘宝的镜像源。至少要了解 npm 的常用命令,npm scripts 如何使用,语义化版本号规则,CommonJS 模块规范(了解它和 ES2015 Modules 的异同),Node 包的解析规则,以及 Node 的常用 API。应当做到可以自己写一些基本的命令行程序。注意最新版本的 Node (6+) 已经支持绝大部分 ES2015 的特性,可以借此巩固 ES2015。
- 了解如何使用 / 配置 Babel 来将 ES2015 编译到 ES5 用于浏览器环境。
- 学习 Webpack。Webpack 是一个极其强大同时也复杂的工具,作为起步,理解它的『一切皆模块』的思想,并基本了解其常用配置选项和 loader 的概念/使用方法即可,比如如何搭配 Webpack 使用 Babel。学习 Webpack 的一个挑战在于其本身文档的混乱,建议多搜索搜索,应该还是有质量不错的第三方教程的。英文好的建议阅读 Webpack 2.0 的文档,比起 1.0 有极大的改善,但需要注意和 1.0 的不兼容之处。
Vue 进阶
- 有了 Node 和 Webpack 的基础,可以通过 vue-cli 来搭建基于 Webpack ,并且支持单文件组件的项目了。建议用 webpack-simple 这个模板开始,并阅读官方教程进阶篇剩余的内容以及 vue-loader 的文档,了解一些进阶配置。有兴趣的可以自己亲手从零开始搭一个项目加深理解。
- 根据 例子 尝试在 Webpack 模板基础上整合 vue-router 和 vuex
- 深入理解 Virtual DOM 和『渲染函数 (Render Functions)』这一章节(可选择性使用 JSX),理解模板和渲染函数之间的对应关系,了解其使用方法和适用场景。
- (可选)根据需求,了解服务端渲染的使用(需要配合 Node 服务器开发的知识)。其实更重要的是理解它所解决的问题并搞清楚你是否需要它。
- 阅读开源的 Vue 应用、组件、插件源码,自己尝试编写开源的 Vue 组件、插件。
1. 什么是vue
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的框架。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
2. Vue基础语法知识
2.1 Vue是怎么工作的
新建index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学习Vue</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el:"#app",
data() {
return {
text: 'Hello World!'
}
}
});
</script>
</body>
</html>
2.2 el优化
该 el 挂载形式,在 Vue 内部运行机制中,它会根据你传入的值,进行查找:
- 如果传入的是
#app,那它就判断查找id为app的节点; - 如果传入的是
.app,那它就查找class为app的节点; - 如果传入的是节点名
div,那它就查找节点名……
大家应该清楚,这样判断查找是需要时间的,多执行一个判断都是罪恶。 所以我们可以:
el: document.getElementById('app'),
这般操作,使得 Vue 直接将挂载点挂载到 id 上去,从而获得更好的加载速度。这算是对 el 的一个小优化。
2.3 插值表达式
通过 {{}} 这个插值表达式的使用,对data其里面的数据进行操作。
下面,我们进一步讲解这个插值表达式 {{}} 还可以进行哪种骚操作:
- 对象:{{ {name: 'jack'} }}
- 字符串 {{ 'Hello World!' }}
- 布尔值: {{ isTrue == -1 }}
- 三元表达式: {{ isTrue ? '正确' : '错误' }}
2.4 指令 v-*
在 Vue 中,如果单单使用 {{}} 这种插值表达式,是满足不了我们对数据的操作欲望的。所以,Vue 以 v-if、v-bind 等形式,提供了一些对于页面 + 数据的更为方便的操作:指令
v-textv-htmlv-ifv-else-ifv-elsev-showv-bindv-onv-modelv-for
2.5 methods
<body>
<div id="app">
<button v-on:click="addStyle">点我</button>
</div>
<script>
new Vue({
el:"#app",
data(){
return{
}
},
methods:{
addStyle(e){
console(成功添加样式)
}
}
});
</script>
-
首先,在上面的
<button>中,我们通过@click绑定了事件addStyle: -
接着,方法的编写,需要写到与
data同级的methods中:
methods:{
addStyle(e){
console(成功添加样式)
}
}
2.6 组件component
组件是 Vue 学习的重点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
<my-head></my-head>
<my-body></my-body>
<my-foot></my-foot>
</div>
<script>
var Head={
template:"<div>我是头</div>"
};
var Body={
template:"<div>我是身体</div>"
};
var Foot={
template:"<div>我是底部</div>"
};
new Vue({
el:"#app",
data(){
return{
}
},
methods:{
},
components:{
"my-head":Head,
"my-body":Body,
"my-foot":Foot
}
});
</script>
</body>
</html>
2.7 父子组件通信
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
<son :name="name"></son>
</div>
<script>
var Son={
template:"<div>我是{{name}}</div>",
props:["name"]
};
new Vue({
el:"#app",
data(){
return{
name:"皮皮虾"
}
},
methods:{
},
components:{
"son":Son
}
});
</script>
</body>
</html>
父组件中的数据,通过 v-bind:*** 的形式,将父组件中的 data,发送给子组件。而子组件呢,通过 props 的定义,获取到了父亲的数据。
2.7.1 共用组件
我们通过 Vue.component('组件名',{ }) 的形式,注册了个全局组件 beautiful-girl,这样,父子组件都可以直接调用该组件
2.8 过滤器filter
2.8.1 局部过滤器
在工作中,我们经常需要对一些后端传回来的数据进行过滤。例如:我司 Java 小哥传回来的金钱,就是分进制的,即:1元 = 100分。所以传回个 2000,其实是 20 元。那么,在 Vue 中,我们该如何对数据进行过滤呢?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
我是钱多多,我有{{money}}分,{{money | yuan }}元
</div>
<script>
new Vue({
el:"#app",
data(){
return{
money:100000
}
},
methods:{
},
filters:{
yuan(val){
return (val/100);
}
}
});
</script>
</body>
</html>
在上面,我们通过 filters 中的 yuan 方法,对数据进行了过滤,将 money 的数据,从 100000 变成了 1000。
2.8.2 全局过滤器
// 全局过滤器
Vue.filter('yuan', function(val)
{
return (val/100);
})
3 监听数据
3.1 侦听属性
监听属性 watch,我们可以通过 watch 来响应数据的变化。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
<input type="text" v-model="name" />
{{name}}
</div>
<script type="text/javascript">
var vm=new Vue({
el:"#app",
data(){
return{
name:'jiankuaji'
}
},
watch: {
name (newVal,oldValue) {
alert(newVal);
alert(oldValue);
}
}
});
</script>
</body>
</html>
3.2 计算属性computed
在上面,我们讲了通过 watch 来监听 data 中 number、string 等字段的改变。但是,在 Vue 中,为了方便我们的监听操作,Vue 还定义了个方法:computed,我们可以通过 computed,监控我们在 data 中定义的全部数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
{{name}}
{{firstName}}
</div>
<script type="text/javascript">
var vm=new Vue({
el:"#app",
data(){
return{
name:'jiankuaji',
}
},
computed:{
firstName(){
return this.name+"sd";
}
}
});
</script>
</body>
</html>
3.3 watch、computed 与 methods 对比
-
computed是根据data中的数据变化,而进行的操作。即this.任意数据改变了,那么,computed就会进行改变;而如果this.任务数据不变,那么computed就会执行它的缓存策略,不会更新 -
methods一般是根据点击之类的事件来触发的,例如用户通过@click="方法"来进行数据的改变。 -
watch属性强调自身值的变化前后的动作。watch在处理异步操作或者开销较大的操作上有优势。- 执行异步操作不能串行返回结果,使用
watch; - 开销较大的操作,避免堵塞主线程,使用
watch; - 简单且串行返回的,使用
computed。
- 执行异步操作不能串行返回结果,使用
4 用户输入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
<input v-model="name" replace="用户名称">
单个多选框
<input type="checkbox" v-model="checkbox">是否勾选
多选框
<input type="checkbox" v-model="checkboxs" value="j">j
<input type="checkbox" v-model="checkboxs" value="i">i
<input type="checkbox" v-model="checkboxs" value="a">a
<input type="checkbox" v-model="checkboxs" value="n">n
{{checkbox}} {{checkboxs}}
单选框
<input type="radio" value="男" v-model="sex">男
<input type="radio" value="女" v-model="sex">女
{{sex}}
下拉框
<select v-model="select">
<option value="">选择一个网站</option>
<option value="www.runoob.com">Runoob</option>
<option value="www.google.com">Google</option>
</select>
我选择的是{{select}}
</div>
<script type="text/javascript">
var vm=new Vue({
el:"#app",
data:{
name:'',
checkbox:true,
checkboxs:["j"],
sex:'',
select:""
}
});
</script>
</body>
</html>
5 生命周期
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
{{name}}
</div>
<script type="text/javascript">
var vm=new Vue({
el:"#app",
data(){
return{
name:'jiankuaji'
}
},
beforeCreate(){
console.log("创建前")
},
created(){
console.log("创建后")
},
});
</script>
</body>
</html>