文章目录
1.什么是Vue CLI
2.Vue CLI使用环境
Vue CLI使用前提 - Node
Vue CLI使用前提 - Webpack
3.vue cli2
vue cli2安装
npm install @vue/cli -g vue脚手架3安装
npm uninstall vue-cli -g 卸载vue脚手架
使用脚手架3也可以初始化脚手架2的模板
拉取使用脚手架2的模板:npm install @vue/cli-init -g
使用Vue CLI2初始化项目:vue init webpack my-project
使用Vue CLI3初始化项目:vue create my-project
创建vue cli2项目
vue cli2目录结构详解
4.Runtime-Compiler和 Runtime-only的区别
在构建vue cli项目时,会让我们选择Runtime-Compiler和Runtime-only版本,那他们的区别是什么?
简单总结
如果在之后的开发中,你依然使用template,就需要选择Runtime-Compiler
如果你之后的开发中,使用的是.vue文件夹开发,那么可以选择Runtime-only
区别在于main.js文件
为什么存在这样的差异呢?
我们需要先理解Vue应用程序是如何运行起来的。
Vue中的模板如何最终渲染成真实DOM。
我们来看下面的一幅图。
vue程序运行过程
他们的区别:runtime-compiler 需要把模板解析成ast在编译为render函数,而runtime-only 是直接就是render函数,
问:那么使用runtime-only时,他们的template怎么编译的,
答:之前我们在webpack的时候,对vue文件导出的时候安装了一个npm install vue-loader vue-template-compiler --save-dev vue-loader负责加载vue文件 vue-template-compiler 负责编译模板template 为render函数
// runtime-compiler(v1)
// template (模板) ----解析----> ast(抽象语法树) —编译–> render(渲染函数) —调用函数转为—> vdom(虚拟dom) —最后渲染-> UI(真实dom)
// runtime-only(v2)(1.性能更高 2.下面的代码量更少)
// render —> vdom -> UI
npm run build
npm run dev
5.vue cli3
cli3的创建项目过程: https://www.cnblogs.com/fqh123/p/12442778.html
vue-cli 3 与 2 版本有很大区别:
vue-cli 3 是基于 webpack 4 打造,vue-cli 2 还是 webapck 3
vue-cli 3 的设计原则是“0配置”,移除的配置文件根目录下的,build和config等目录
vue-cli 3 提供了 vue ui 命令,提供了可视化配置,更加人性化
移除了static文件夹,新增了public文件夹,并且index.html移动到public中
vue cli3目录结构:
vue cli3的main.js:
这里的$ mount(’#app’),与 el:#app 差不多el最后也是是用$mount()挂载替换
Vue CLI3的配置文件
VueCli3查看配置文件
1、通过ui查看,启动配置服务器:vue ui
这个随便在哪里启动都可以,我们要点击导入,才可以查看该项目的配置
导入项目
查看插件和插件版本
这里也可以添加插件
这里可以添加配置
这里可以打包项目和运行项目
cli3的配置文件隐藏到这里
如果我们想扩展配置,这里导出之后,会和隐藏的配置一起合并,注意:名字一定要是vue.config.js
6.箭头函数
箭头函数的基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// 箭头函数: 也是一种定义函数的方式
// 1.定义函数的方式: function
const aaa = function () {
}
// 2.对象字面量中定义函数
const obj = {
bbb() {
}
}
// 3.ES6中的箭头函数
// const ccc = (参数列表) => {
//
// }
const ccc = () => {
}
</script>
</body>
</html>
箭头函数参数和返回值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// 1.参数问题:
// a.放入两个参数
const sum = (num1, num2) => {
return num1 + num2
}
// b.放入一个参数,一个参数时可省略括号
const power = num => {
return num * num
}
// 2.函数中
// a.函数代码块中有多行代码时大括号不可省略
const test = () => {
console.log('Hello World');
console.log('Hello Vuejs');
}
// b.函数代码块中只有一行代码时大括号可省略
const mul = (num1, num2) => num1 * num2
console.log(mul(20, 30));
//3.没有参数且函数代码块中只有一行代码时
const demo = () => console.log('Hello Demo')
console.log(demo());
</script>
</body>
</html>
箭头函数中的this的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// 什么时候使用箭头
// setTimeout(function () {
// console.log(this);
// }, 1000)
//
// setTimeout(() => {
// console.log(this);
// }, 1000)
// 问题: 箭头函数中的this是如何查找的了?
// 答案: 向外层作用域中, 一层层查找this, 直到有this的定义.
// const obj = {
// aaa() {
// setTimeout(function () {
// console.log(this); // window
// })
//
// setTimeout(() => {
// console.log(this); // obj对象
// })
// }
// }
//
// obj.aaa()
const obj = {
aaa() {
setTimeout(function () {
//这种形式都为window
setTimeout(function () {
console.log(this); // window
})
//外一层为function,依旧为window对象
setTimeout(() => {
console.log(this); // window
})
})
setTimeout(() => {
//这种形式都为window
setTimeout(function () {
console.log(this); // window
})
//外一层为箭头函数,为obj对象
setTimeout(() => {
console.log(this); // obj
})
})
}
}
obj.aaa()
</script>
</body>
</html>
7.什么是Promise?
ES6中一个非常重要和好用的特性就是Promise。但是初次接触Promise会一脸懵逼,这TM是什么东西?看看官方或者一些文章对它的介绍和用法,也是一头雾水。
Promise到底是做什么的呢?
Promise是异步编程的一种解决方案。
那什么时候我们会来处理异步事件呢?
一种很常见的场景应该就是网络请求了。我们封装一个网络请求的函数,因为不能立即拿到结果,所以不能像简单的3+4=7一样将结果返回。所以往往我们会传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去。如果只是一个简单的网络请求,那么这种方案不会给我们带来很大的麻烦。但是,当网络请求非常复杂时,就会出现回调地狱。
OK,我以一个非常夸张的案例来说明。
网络请求的回调地狱
我们来考虑下面的场景(有夸张的成分):
我们需要通过一个url1从服务器加载一个数据data1,data1中包含了下一个请求的url2
我们需要通过data1取出url2,从服务器加载数据data2,data2中包含了下一个请求的url3
我们需要通过data2取出url3,从服务器加载数据data3,data3中包含了下一个请求的url4
发送网络请求url4,获取最终的数据data4
上面的代码有什么问题吗?
正常情况下,不会有什么问题,可以正常运行并且获取我们想要的结果。
但是,这样额代码难看而且不容易维护。我们更加期望的是一种更加优雅的方式来进行这种异步操作。
如何做呢?就是使用Promise。Promise可以以一种非常优雅的方式来解决这个问题。
8.Promise基本使用
定时器的异步任务
我们先来看看Promise最基本的语法。
这里,我们用一个定时器来模拟异步事件:
假设下面的data是从网络上1秒后请求的数据
console.log就是我们的处理方式。
这是我们过去的处理方式,我们将它换成Promise代码
这个例子会让我们感觉脱裤放屁,多此一举
首先,下面的Promise代码明显比上面的代码看起来还要复杂。
其次,下面的Promise代码中包含的resolve、reject、then、catch都是些什么东西?
我们先不管第一个复杂度的问题,因为这样的一个屁大点的程序根本看不出来Promise真正的作用。
定时器异步事件解析
Promise三种状态
Promise链式调用
Promise链式调用
promise的all方法
当有需求是需要两个网络请求都成功的时候,才能完成需求,
之前的处理方法是:定义两个标识符判断是否都成功
let isResult1 = false
let isResult2 = false
$ajax({
url: '',
success: function () {
console.log('结果1');
isResult1 = true
handleResult()
}
})
// 请求二:
$ajax({
url: '',
success: function () {
console.log('结果2');
isResult2 = true
handleResult()
}
})
function handleResult() {
if (isResult1 && isResult2) {
//
}
}
使用Promise的all方法,//当两个请求都成功,调用resolve时,才会进入then,否则不会进入
Promise.all([
new Promise((resolve, reject) => {
$.ajax({
url: 'url1',
success: function (data) {
//当两个请求都成功,调用resolve时,才会进入then,否则不会进入
resolve(data)
}
})
}),
new Promise((resolve, reject) => {
$.ajax({
url: 'url2',
success: function (data) {
resolve(data)
}
})
})
]).then(results => {//这里的results是一个数组,results[0]是第一个请求成功返回的数据。results[1]是第二个请求成功返回的数据。
console.log(results);
})