目录 § ⇧
- 0.
Vue
前置知识与学习路线 § - 1.
Vue
项目搭建 § - 2.
@vue/cli
§ - 3.
Vue
实例+1 demo
§ - 4. 使用
Vue
实例 § - 5.
vue.js
和vue.runtime.js
的区别和使用方法 §template
和render
- 6.
Vue
实例2 井字游戏 § - 7. 用
codesandbox.io
写Vue
代码 § - 8.
VuePress
§ - 9. 总结 §
[toc]
0. Vue
前置知识与学习路线 § ⇧
Node.js
已安装HTML/CSS/JS
语法Vue
文档收藏 中文文档- 利用文档的搜索功能快速定位
- 学习路线
- 需要学的
vue | @vue/cli | vuex | vue router | axios
系统学习
Vue
- CRM,过一遍文档,总结为博客
- 目录学习法
- 面试官提问学习法
- 关键词:
Vue 实例
、el 和 data
、Vue 简单数据变动管理
- 注意对比
vue2.x
和vue3.x
目标一:搞出一个使用
Vue
的项目
1. Vue
项目搭建 § ⇧
方法一:使用
Vue CLI (@vue/cli)
- 是基于
Vue.js
进行快速开发的完整系统(实现的交互式的项目脚手架) - 搜索
@vue/cli
文档 - 在终端里使用 vue 相关命令
- 「创建一个项目」CRM
方法二:手动配置,从零搭建
- 使用
webpack
或rollup
从零搭建,较复杂 - 使用
Vite
或snowpack
从零搭建
方法三:第三方在线傻瓜配置,适合
demo
- codeSandBox
- codePen
- 详见 用
codesandbox.io
写Vue
代码 §
2. @vue/cli
§ ⇧
- CRM
@vue/cli
提到的工具官网示例 - 通过
vue ui
通过一套图形化界面管理所有项目
CLI
服务(@vue/cli-service)
是一个开发环境依赖,局部安装在每个 @vue/cli 创建的项目中
CLI
服务是构建于webpack
和webpack-dev-server
之上。它包含- 加载其它
CLI
插件的核心服务; - 一个针对绝大部分应用优化过的内部的
webpack
配置; - 项目内部的
vue-cli-service
命令,提供serve
、build
和inspect
命令
- 加载其它
@vue/cli
用法 ⇧
全局安装,使用 npm 或 yarn
|
|
查看版本与环境
|
|
创建目录(新项目的脚手架)
|
|
- 路径
<path>
可用点./
按提示选择配置
- 提示选取一个
preset
- 可选默认的包含了基本的
Babel + ESLint
设置的preset
- 也可以选“手动选择特性”来选取需要的特性
- 这个默认的设置非常适合快速创建一个新项目的原型
- 而手动设置则提供了更多的选项,它们是面向生产的项目
- 选择配置操作: (回车为进行下一步,↑↓键将光标上下移动选择,空格键选择或取消勾选)
- 目前方法
present
:Manually select features
- 包含特征
features
:Babel
CSS Pre-processors
Linter / Formatter
Unit Testing
CSS
预处理器CSS pre-processors
:Sass/SCSS (With dart-sass)
- 代码校验/格式化
Linter / Formatter
:ESLint with error prevention only
- 何时触发校验
additional lint features
:Lint and fix on commit
- 单元测试方案
unit testing solution
:Jest
- 如何设置配置文件
prefer placing …
:In dedicated config files
- 是否把以上选项作为以后项目的默认配置
save this as …
:N
- 最后一步选
N
不要保存默认配置? Save this as a preset for future projects? (y/N) N
本demo的
@vue/cli
配置选项
- 选错
Ctrl + c
中断重来 - 注意默认选项
- 仅对此
demo
适用,自行斟酌真实项目的配置
|
|
- 根据提示进行下一步
- 忽略警告
warning
- 如果发现错误
error
google - 进入目录,运行
yarn serve
- 自动开启一个本地预览服务器
webpack-dev-server
来检查项目是否成功创建
运行
yarn serve
自动生成后的目录结构
|
|
项目创建成功提示
|
|
- 用
WebStorm
或VSCode
打开项目
目标二:做一个简单项目,熟悉涉及的文档
3. Vue
实例 +1 demo
§ ⇧
需求实现:在 div 里实现一个展示数字的字符串 ,按下
+1
按钮,更新data
中数据的内容
CRM 改
App.vue
|
|
main.js
|
|
demo1
小结 ⇧
通过这个简单的demo,初步了解以下五个知识点
el
data(){}
methods:{}
- 插值表达式
{{n}}
@click="add"
- 为什么可以直接导出
export default {}
带着疑问查文档,实例接收配置项
el
:实例负责管理的一个区域。如el: '#app'
,即让这个Vue
实例去接管id
为app
的DOM
元素标签里的所有内容data
:定义了需要传递的一些数据。如data: { content: 'hello world' }
,即传递了内容为'hello world'
的数据:content
。这种数据在dom
元素中用{{ }}
来来调用对应数据内容- 少了
id
,Vue
实例无法接管一个不用el
管理的区域,说明Vue
实例 接管了el
管理下的DOM
元素标签下的所有内容,没有被el
管理过的 dom元素无法显示对应数据
4. 使用new Vue
实例对象 § ⇧
类比
jQuery
实例对象const $div = new jQuery('#xxx')
$div
封装了对#xxx
所有操作,可省略为const $div = jQuery('#xxx')
或const $div = $('#xxx')
main.js
|
|
- 同样的,
const vm = new Vue()
vm
封装了实例对于组件的所有操作- 封装了对
DOM
的所有操作,封装了对data
的所有操作 - 数据、事件绑定、等
- 初始化
./public/index.html
中的<div id="app"></div>
- 改掉默认的,对
#app
进行一个MVC
的封装
main.js
|
|
CRM改
./public/index.html
|
|
- 运行
yarn serve
- 报错
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
- 提示要么使用
loader
预编译,要么使用完整版,默认使用运行时版 - 安装方法 直接用
<script>
引入CDN
vue有两种形式的代码
compiler
(模板)模式和runtime
模式(运行时)
vue
模块的package.json
的main
字段默认为runtime
模式, 指向了"dist/vue.runtime.common.js"
位置- 而在
main.js
文件中,初始化vue
使用的是compiler
模式,所以就会出现上面的错误信息
- 直接下载并用
<script>
标签引入,Vue
会被注册为一个全局变量 - 在开发环境下不要使用压缩版本,不然你就失去了所有常见错误相关的警告!
- 开发版本包含完整的警告和调试模式
- 生产版本删除了警告,33.30KB min+gzip
- 各个引用文件的区别
vue2.x V.S. vue3.x
在2.x
中通过new Vue()
的方法来初始化:
|
|
在3.x
中Vue
不再是一个构造函数,通过createApp
方法初始化:
|
|
Vue的两个版本和三个使用方法 ⇧
方法一:从HTML
得到视图 ⇧
- 「完整版
Vue
」,同时包含编译器和运行时的版本 - 编译器:用来将模板字符串编译成为
JavaScript
渲染函数的代码 - 运行时:用来创建
Vue
实例、渲染并处理虚拟DOM
等的代码。基本上就是除去编译器的其它一切 - 从
CDN
引用完整版vue.js
或完整生产版vue.min.js
- 生产版中没有注释,体积小
- 通过
import
引用vue.js
或vue.min.js
- 文档 「运行时环境 + 编译器 vs. 只包含运行时环境」
- 使用
bootCDN vue
引入 - 稳定版
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
./public/index.html
|
|
main.js
|
|
- 在
data
定义可以是一个对象或是函数 data
中的n
对应index.html>#app
内的模板数据{{n}}
- 注意
MVC
的视图没有写在JS
文件中,而是直接写在页面里index.html
- 这就是完整版的功能:直接在页面中渲染数据
改为使用
template
,放页面内容
- 页面元素可以放在
html
中,或放在template
模板字符串中 - 在客户端编译模板 (比如传入一个字符串给
template
选项,或挂载到一个元素上并以其DOM
内部的HTML
作为模板),就将需要加上编译器,即完整版
./public/index.html
|
|
main.js
|
|
./public/index.html
|
|
- 不直接写到
HTML
里面,而在JS
写到template
- 完整版可以直接在页面里写模板字符串
- 在客户端编译模板 (比如传入一个字符串给
template
选项,或挂载到一个元素上并以其DOM
内部的HTML
作为模板), 只包含运行时版(非完整版)不支持,而 完整版 支持
「非完整版」没有编译器,使用以上方法,页面中无渲染效果
不支持从
HTML
里获取视图,也不支持直接从template
获取视图(不使用vue-loader
)
方法二:用JS
构建视图 ⇧
- 使用「非完整版」,即
vue.runtime.js
,「运行时版」 - 使用「运行时版生产版」,即
vue.runtime.min.js
- 引入运行时版
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.runtime.min.js"></script>
- 不支持从
html
获取视图,使用template
也不行 - 通过
h()
即createElement
来创建DOM
- 不是给人(开发者)看的
|
|
- 用函数
render(h){return h('xxx', this.xxxData)}
h
就是对createElement
的别名封装alias
- 运行时版存在的意义是,更加地独立,功能单一
main.js
|
|
- 不适合开发(实际是打包自动生成),代码不清晰
- 体积小,适合生产环境
./public/index.html
|
|
「完整版」思路
- 视图是写在
HTML
里或template
选项的,由于有compiler
(编译器)的存在 vue
用编译器compiler
将html
字符串模板中的${{n}}
,转化为实际数据html
的DOM
(复杂的编译v-if
,v-for
、@click
),数据改变this.n += 1
时,渲染DOM
节点- 编译器的代码复杂,占用一定的体积(相对「非完整版」+
30%
) - 优点:编译器可以将含有占位符
${{}}
或者条件语句变成真实的DOM
节点,可以从HTML
得到视图 - 不适用于生产环境
「非完整版」思路
- 没有
compiler
,不直接编译${{n}}
- 在JS中通过
render()
的h()
创建节点 - 优点:没有
compiler
,所以体积小 - 缺点2:没有
compiler
,不能将HTML
变成节点,需要用JS
构建视图 - 缺点1:
HTML
就只有一个div#app
,SEO
不友好
index.html
中的<div id="app"></div>
里面会被替换为Demo
变异后的内容,但替换前是空的,这样SEO
不友好
SEO
友好 ⇧
SEO(Search Engine Optimization)
,即搜索引擎优化- 可以将搜索引擎
SEO
理解为不停地curl
网站源代码 - 根据
curl
结果猜测页面内容,命令行中输入curl https://xiedaimala.com
- 可以看到网址传回的结果
SEO
不友好
- 如果页面都是用
JS
创建的,搜索引擎curl
无效(google
除外),无法抓取信息
过时的解决方案
- 给
curl
一点内容 - 把
title
、description
、<meta name="keyword" content="xxx" >
、<meta name="description" content="xxx" >
、h1
、a
写好描述内容 - 关键字、作者人名、标题
- 原则:让
curl
能得到页面的信息,SEO
就能正常工作 - 浏览的人足够多,网站排名越靠前
- π,花钱
meta description MDN
<head>标签里有什么? Metadata-HTML中的元数据
- 常用meta整理
方法三:「非完整版」+ Vue
的单文件组件*.vue
⇧
*.vue
包含三个基本的标签,设置为snippets
|
|
- 使用
vue-loader
时,export default
的data
必须使用函数的形式,必须有返回值 - 创建一个
vue
文件
demo.vue
|
|
main.js
导入单文件组件,实例中render(h) {return h(xxx)}
|
|
vue-loader
做了什么
- 使用
vue-cli
时,已经配置好webpack
的vue-loader
- 使用
webpack
的vue-loader
,可以将.vue
文件编译成h
构建方法 yarn build
后,将<div>${{n}}</div>
转化为 render 函数的方法 (h('div', this.n)
),客户端可解析的代码- 不需要在单文件组件中写
render
函数 vue-loader
将较为直观的template
内容预编译为h()
yarn build
时转换,让用户下载只支持render
的不完整版Vue
和编译好的h('div', this.n)
- 即将编译器放到
vue-loader
实现,vue-loader
调用compiler
- 使用
vue-loader
或vueify
,*.vue
文件内部的模板会在构建时预编译成JavaScript
- 在最终打好的包里实际上是不需要编译器,所以只用运行时版本即可
- 用户下载产品时只需要下载体积小的非完整版
- 开发人员编写代码时,也不需要使用
render
方法去构造元素
使用单文件组件
*.vue
- 单文件组件
*.vue
清晰地分为视图template
、逻辑script
、样式style
vue-loader
将以上的三个部分编译成一个对象- 在
Vue
实例对象中声明属性el
的节点目标、render(h) {return h(xxx)}
,xxx
为导入的单文件组件
小结Vue
实例作用 ⇧
Vue
实例如同jQuery
实例
- 封装对
DOM
的所有操作 - 封装对
data
的所有操作
Vue
操作DOM
- 监听事件
- 改变
DOM
Vue
操作data
- 增删改查
Vue2
的bug响应式原理
Vue3
的改进
Vue
未封装ajax
- 用
axios
的ajax
功能
vue内部过程
- 首先将
vue
中的模板进行解析解析成abstract syntax tree (AST)
抽象语法树 - 将抽象语法树编译成
render
函数 - 将
render
函数再翻译成virtual DOM
虚拟DOM
- 将虚拟
DOM
显示在浏览器上
runtime-only
和runtime-compiler
的区别 ⇧
runtime-only
比runtime-compiler
更快- 因为它省略了将
vue
中的模板进行解析解析成abstract syntax tree (ast)
抽象语法树 - 跳过将抽象语法树编译成
render
函数 - 直接用
render
函数
- 因为它省略了将
- 如果是
runtime-compiler
,那么main.js
中就会出现template
从而需要过程一导致增加了一个过程,同时增加了大小 runtime-only
只能识别render
函数,不能识别template
*.vue
文件中的也是被vue-template-compiler
编译成了render
函数,所以只能在*.vue
里写template
runtime-only
模式中把template
放在了*.vue
的文件中,vue-template-compiler
的在开发依赖时将*.vue
文件中的template
解析成render
函数,因为是开发依赖,不在最后生产中,所以最后生产出来的运行的代码没有template
过程图解
template
->AST
->render
->vDOM
->UI
template
代码首先会解析成AST
(抽象语法树,abstract syntax tree
)AST
编译成render
函数render
函数变化成vDOM
(虚拟DOM
,virtual DOM
)- 最终
vDOM
的内容更新渲染到UI
上。
所以
runtime-compiler
经历的是一个template -> AST -> render -> vDOM -> 真实的DOM -> 页面
的过程runtime-only
直接使用了render
函数,所以经历的是一个render -> vDOM -> UI
的过程。runtime-only
会省去一个template -> AST -> render
的过程,也不再需要相关的compiler
或loader
,从而这种方法搭建的项目性能更高,代码也更少,项目大小也更小。
目标三:深入理解 完整版 / 运行时版 区别
5. 理解vue.js
和 vue.runtime.js
的区别和使用方法 最佳实践 § ⇧
不同项比较 | Vue 完整版 |
Vue 运行时版 |
评价 |
---|---|---|---|
特点 | 有compiler (编译器) |
无compiler |
compiler 多占约30% 体积 |
视图 | 写在HTML /template 选项 |
写在render 函数里用h 创建标签 |
h 默认,是作者写好传给render 的,可改为任意名字 |
cdn 引入 |
vue.js |
vue.runtime.js |
文件名不同,生成环境后缀为.min.js |
webpack 引入 |
需配置alias |
默认使用此版 | 维护者配置好了,满足大多数开发需求特殊需求除外 |
@vue/cli 引入 |
需额外配置 | 默认使用此版 | 维护者配置好了 |
完整版
- 对应的文件名:
vue.js
,vue.min.js
后者是压缩版,取消了注释和警告 - 支持从
html
获取视图(DOM
节点) - 支持
template
- 有
compiler
编译器
非完整版
- 对应的文件名:
vue.runtime.js
,vue.runtime.min.js
同上 - 不支持从
html
获取视图 - 不支持
template
,需要通过vue-loader
将组件中的template
模板编译为render
函数 - 没有
compiler
编译器,体积会比完整版小30%
最佳实践 ⇧
总是使用运行时版,配合
vue-loader
和vue
单文件组件,目的是让用户端空间占用空间最小,思路如下
- 保证用户体验,用户对
VUe
的依赖使用,下载的JS
文件体积更小(去掉开发环境的编译器、注释、压缩代码),但只支持h
函数(main.js
里不支持template
) - 保证开发体验,使用
webpack
的vue-loader
,开发者可直接在vue
单文件组件中写HTML
标签,也支持h
函数,打包时,自动转译 - 编译工作让
loader
自动完成,vue-loader
把vue
文件里的HTML
标签转为h
函数
引用错了会怎样
vue.js
错用成了vue.runtime.js
,无法将HTML
编译成视图,后台会报错compiler
(要么使用loader
预编译,要么使用完整版)vue.runtime.js
错用成了vue.js
,代码体积变大,vue.js
有编译HTML
功能,并不报错
template
V.S. render
⇧
template
:HTML
内容模板(<template>
)元素是一种用于保存客户端内容机制,该内容在加载页面时不会呈现,但随后可在运行时使用JavaScript
实例化,即提供模板占位符可以包裹元素,这个
template
不会被渲染到页面上,因为它天生带有display: none;
属性
Vue
中将一个字符串模板作为Vue
实例的标识使用,模板将会替换挂载的元素,挂载元素的内容都将被忽略,除非模板的内容有分发插槽(v-slot
)
template
在完整版 ⇧
- 在JS里面创建
Vue
实例,template
属性里写模板字符
|
|
- 完整版支持直接在
index.html
文件里写视图,支持模板字符 - 也支持在
main.js
里写,需要写到实例的template
属性中
例如
- 在
index.html
中添加一个id
为app
的标签<div id="app"></div>
- 接着添加script标签,引入完整版的js文件
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
- 然后在
main.js
里,直接把html
代码写入template
选项中
|
|
- 运行
Vue
后,它会直接把n
为0
写入到app
标签中 - 需注意的是,
template
中至少要有一个根元素,不能是纯文本,否则会报错 - 如果存在多个同级元素,没有根元素时,只会显示第一个元素
template
在运行时版 ⇧
- 只在单文件组件
*.vue
里写template
- 在
*.vue
文件中提供模版、方法和样式,在main.js
用new Vue
实例化render(h) {return h(xxx)}
,xxx
为导入的单文件组件
render
是渲染函数,它可以代替template
创建HTML
元素
render
函数的参数也是一个函数,一般名为h
,实际可以是任意(类似的有event
的e
)- 这个
h
就是封装过的createElement
render
函数将createElement
的返回值放到了HTML
中
|
|
createElement
这个函数中有3个参数- 第一个参数(必要参数):主要用于提供
DOM
的HTML
内容,类型可以是字符串、对象或函数(可以是一个HTML
标签字符串,组件选项对象,或者解析上述任何一种的一个async
异步函数,必填,类型:{String | Object | Function}
) - 第二个参数(类型是对象,可选):用于设置这个
DOM
的一些样式、属性、传的组件的参数、绑定事件之类(包含模板相关属性,用于设置模板元素的属性或者事件,可选,类型:{Object}
) - 第三个参数(类型是数组,数组元素类型是
VNode
,可选):主要是指该结点下还有其他结点,用于设置分发的内容,包括新增的其他组件。注意,组件树中的所有VNode
必须是唯一的(设置模板元素文本,或者创建子节点 类型:{String | Array}
)
- 第一个参数(必要参数):主要用于提供
h
函数的本质是createElement
函数,这个函数的作用就是生成一个VNode
节点,render
函数得到这个VNode
节点之后,返回给Vue.js
的mount
函数,渲染成真实DOM
节点,并挂载到根节点上- 而之所以要 叫 h,根据作者解释是,来源于 hyper script
|
|
render
在完整版 ⇧
- 可用但不使用
- 在实际开发中,由于 h 函数的参数比较复杂,通过使用
webpack
的vue-loader
能将单文件组件(以.vue
结尾的文件)转换为h
函数所需要的参数
render
在运行时版 ⇧
|
|
- 渲染函数接收一个
createElement
方法作为第一个参数用来创建VNode
- 如果组件是一个函数组件,渲染函数还会接收一个额外的
context
参数,为没有实例的函数组件提供上下文信息 - 在
js
里使用render
写视图,结构和逻辑越多,代码越不清晰,不适合直接开发,而是被动生成的代码
例如
- 在
index.html
中添加一个id
为app
的标签<div id="app"></div>
- 接着添加
script
标签,引入运行版的js
文件<script scr="https://cdn.bootcss.com/vue/2.6.11/vue.runtime.min.js"><script>
- 然后在
main.js
里,用render
函数来创建标签
|
|
单文件组件
*.vue
- 另一个方法是在
js
里引入单文件组件xxx
后,render(h) {return h(xxx)}
,通过vue-loader
编译
|
|
6. Vue
实例2 井字游戏 § ⇧
7. 用 codesandbox.io
写 Vue
代码 § ⇧
用
CodeSandbox
V.S.CodePen
生成一个可以在线编辑实时预览的 vue 项目
- 不适合IDE的各种快捷操作
- 无代码提示
特点
CodeSandbox
- 支持导出项目打包下载
Export to ZIP
-解压免配置使用 - 支持配置各种资源
- 有清晰地目录结构
Sandbox
使用的是运行时版- 支持用提供的构建工具生成生产版代码
CodePen
- 只支持一个单文件组件
*.vue
- 无文件目录
- 支持配置简单的资源
- 可将编辑和预览视图以代码链接的形式插入博客
8. 用 VuePress
写 文档 § ⇧
9. 总结 § ⇧
- 先做,然后才能知道达到什么水平
- 看文档时,多看一眼其他章节,用到时再回来细看
- 迭代
- 封装比使用更值钱
参考文章
- Vue 英文文档
- Vue 中文文档
- @vue/cli文档
- Vue gitHub
- Vue Technology LLC 曾经的技术要求
- Vue 起手式.pdf
- ESM, CJS, UMD, AMD到底应该选择哪一个
相关文章
- 无
- 作者: Joel
- 文章链接:
- 版权声明
- 非自由转载-非商用-非衍生-保持署名
- 河 掘 思 知 简