目录 § ⇧
- 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:BabelCSS Pre-processorsLinter / FormatterUnit 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 - 如果发现错误
errorgoogle - 进入目录,运行
yarn serve - 自动开启一个本地预览服务器
webpack-dev-server来检查项目是否成功创建
运行
yarn serve自动生成后的目录结构
|
|
项目创建成功提示
|
|
- 用
WebStorm或VSCode打开项目
目标二:做一个简单项目,熟悉涉及的文档
3. Vue实例 +1 demo § ⇧
需求实现:在 div 里实现一个展示数字的字符串 ,按下
+1按钮,更新data中数据的内容
CRM 改
App.vue
|
|
main.js
|
|
demo1小结 ⇧
通过这个简单的demo,初步了解以下五个知识点
eldata(){}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里写templateruntime-only模式中把template放在了*.vue的文件中,vue-template-compiler的在开发依赖时将*.vue文件中的template解析成render函数,因为是开发依赖,不在最后生产中,所以最后生产出来的运行的代码没有template
过程图解
template->AST->render->vDOM->UItemplate代码首先会解析成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 代码 § ⇧
用
CodeSandboxV.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
- 文章链接:
- 版权声明
- 非自由转载-非商用-非衍生-保持署名
- 河 掘 思 知 简