一.背景知识和环境相关
1.Node.js是Ryan Dahl于2009年5月基于Chrome V8引擎构建的一个开源和跨平台的JavaScript运行环境。主要在Windows、Linux、Unix、MacOSX等不同平台上运行。(Chrome V8引擎是谷歌开源的一个高性能JS引擎,并用在谷歌浏览器中,可以编译、执行JS代码 。)
2.NPM (Node Package Manager):npm是Node.js的默认包管理器
3.webpack是基于模块化的打包(构建)工具,它通过一个开发时态的入口模块为起点,分析出所有的依赖关系,然后经过一系列的过程(语法转换、资源压缩、模块合并),最终生成运行时态的文件。
4.vue cli(vue 脚手架):vue标准化开发工具,.vue文件需要脚手架做转换。vue cli集成了webpack。
5.vue特点:
组件化:页面分模块,一个模块写成.vue(里面封装了html、css、js)
声明式编码:无需直接操作DOM
虚拟DOM:diff算法
6.环境搭建流程(配置指令csdn:https://blog.csdn.net/qq_53152029/article/details/125286792)
- 下载安装node.js
- 配置npm淘宝镜像并检查
- 过npm安装webpack并检查
- 通过npm安装vue cli(又称vue脚手架)并检查
- vue create 文件,创建脚手架,过程中会选择vue版本(也可以vue init webpack 文件)
- 在脚手架文件目录下,npm run server(若webpack创建,则npm run dev),不同方式初始化出的项目目录不同。
- localhost:8080测试是否成功
二.Vue学习
1.Vue实例
-
1.1.MVVM
Model:data
View:模板/DOM
ViewMolde:vue实例,内部有DOM Listeners->,<-Data Bindings两个过程 -
1.2.所有的 Vue 组件都是 Vue 实例,并且接受相同的选项对象 (一些根实例特有的选项除外)。
-
1.3.数据与方法:
当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
值得注意的是只有当实例被创建时就已经存在于 data 中的 property 才是响应式的
除了数据 property,Vue 实例还暴露了一些有用的实例 property 与方法。它们都有前缀 $,以便与用户定义的 property 区分开来。 -
1.4.实例生命周期钩子(https://cn.vuejs.org/guide/essentials/lifecycle.html):
每个 Vue 实例在被创建时都要经过一系列的初始化过程----例如,需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
有一些其它的钩子,在实例生命周期的不同阶段被调用,如 mounted、updated 和 destroyed。生命周期钩子的 this 上下文指向调用它的 Vue 实例。
官网图
生命周期引出问题:
Vue生命周期(基于组件概念和原生DOM页面/浏览器等概念的生命周期)
- 常用生命周期:created、mouted、updated
小程序生命周期(基于页面监听概念的生命周期)
- 常用生命周期:onLoad(只执行一次,此时一些this数据已经挂上了就一直挂上了,当前页跳到下一页,后再点左上角返回,回来就不掉onLoad了)、onReady、onShow(页面前后台切换都会调用,如当前页跳到下一页,后再点左上角返回,回来会再掉一次onShow)
2.模板语法
- 2.1.声明式渲染(DOM文本):
插值语法(用于解析标签体):{{}}
{{}}里可以写方法
解决插值表达式闪烁问题:v-cloak
< div id=“app” v-cloak>{{ msg }}< /div>
[v-cloak] {
display: none;
}
- 2.2.条件与循环、处理用户输入(attribute、DOM结构等):
指令语法(用于解析标签):v-xx
通过methods做事件处理(回调函数,js里的DOM事件回调函数)
不要在property或回调上使用箭头函数,造成this错误
用户输入可以用v-model双向绑定
el两种写法,el可以用.$mount挂载的方式替代,这么使用更加灵活。
data有两种写法,一是data对象式,二是data函数式
一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind 指令可以用于响应式地更新 HTML attribute。另一个例子是 v-on 指令,它用于监听 DOM 事件。
“动态参数”:从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数。
<a v-bind:[attributeName]=“url”> …
这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data property attributeName,其值为 “href”,那么这个绑定将等价于 v-bind:href。
“(事件修饰符)修饰符”:
<a href=’www.baidu.com’ @click.prevent=”showInfo”>hh
.native: Vue给自定义组件绑定原生事件(常见使用场景,click点不动,加个native试试)
.prevent阻止默认事件(点了不自动跳到百度了,如上)
.stop 阻止事件冒泡
.once 事件只触发一次
.capture等等
v-bind 缩写是 :
v-on 缩写是 @
- 2.3.使用JavaScript表达式
我们一直都只绑定简单的 property 键值。但实际上,对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持,每个绑定都只能包含单个表达式。
3.计算属性和侦听器(侦听属性)
js:
Object.denfineProperty(obj2,’x’,{
// 这样没写死
get(){},
set(){}
})
// vue通过数据代理(上述getter、setter),给data:{}做了代理。
// 3.1计算属性:对于任何复杂逻辑,你都应当使用计算属性。
new Vue(
{
el:’#root’
data:{
firstname:’wang’
sename:’ze yu’
}
computed:{
fullname:{
// 用get set,保证调用时候,属性变得时候能计算出来
// get调用:1.初次读取fullname,2.所依赖的数据发生变化
// 计算属性有缓存,method没有缓存
get(){
return this.firstname+this.lastname
}
}
--------------------------------------------------------------------------------
// 下面这种写法也行
fullname: function () {
return this.firstName + ' ' + this.lastName
}
}
}
)
// data中写attribute会挂到vm上
// method中写fun会挂到vm上
// computed中不是这样
// 3.2侦听属性:Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时
new Vue(
{
el:’#root’
data:{
firstname:’wang’
sename:’ze yu’
}
watch:{
firstname:{
handler(newValue, oldValue){
}
}
firstname:function(val){
This......逻辑
}
}
}
}
)
也可以通过vm.$watch(‘attribute’,{
handler(newValue, oldValue){
}
})
4.Class与Style绑定
-
可以给 HTML 元素赋予多个 class,例如:< span class=“left_menu important”>。这么做可以把若干个 CSS 类合并到一个 HTML 元素。
-
绑定class样式,class用来绑定样式,:class用来动态改变样式,vue会自动给合并
方式:对象语法、数组语法、用在组件 -
绑定内联样式,style用来绑定内联样式(内联样式写在标签上,class样式写在外边),动态改变样式
方式:对象语法、数组语法、自动添加前缀(涉及浏览器引擎)、多重值
5.条件渲染
v-if/v-else
key管理复用元素
v-show
-
v-show和v-if:
v-show指令:是根据条件显示DOM元素的指令,可以用来动态控制DOM元素的显示和隐藏。当v-show值为false时,绑定DOM的 display:none,当v-show值为true时,绑定DOM会 移除display:none。v-show后面跟的是判断条件,不管初始条件是什么,元素总是会被渲染。
v-if 指令:就是根据表达式值的真假来销毁或者重建一个我们绑定的DOM元素 -
v-show指令设置隐藏是给绑定的DOM元素添加CSS样式:display:none,但是DOM元素仍然存在;v-show 由false变为true时不会触发组建的生命周期。
-
v-if指令设置隐藏是将DOM元素整个删除,此时DOM元素不再存在。v-if 由false变为true时,触发组件的beforeCreate、create、beforeMount、mounter钩子,由true变为false时,触发组件的beforeDestory、destoryed方法。v-if 也是惰性的,如果初始渲染时条件为假,则什么也不做。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
不推荐在同一元素上使用 v-if 和 v-for。当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。请查阅列表渲染指南以获取详细信息。
6.列表渲染
v-for
我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
不要使用对象或数组之类的非基本类型值作为 v-for 的 key。请用字符串或数值类型的值。
(会产生效率、加text错位等问题,涉及虚拟DOM的diff算法,以后研究)
数组更新检测
注意:由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。深入响应式原理中有相关的讨论。
7.事件处理
v-on
可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
事件修饰符(修饰符可以串联)
.native: Vue给自定义组件绑定原生事件(常见使用场景,click点不动,加个native试试)
.prevent阻止默认事件(点了不自动跳到百度了,如上)
.stop 阻止事件冒泡。事件冒泡:事件不仅会发生在目标元素上,还会沿着 DOM 树向上传播。例如,当用户单击一个按钮时,单击事件将首先触发按钮上的处理程序。如果该处理程序没有调用 stopPropagation() 来停止事件冒泡,则事件将向父元素传播,依此类推,直到文档根节点。
(场景:父组件绑定了点击事件a,子组件绑定了点击事件b,若触发了子组件的点击事件b,但不想让其触发父组件点击事件a,则用stop)
.once 事件只触发一次
.capture等等
按键修饰符:在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符。
系统修饰符:可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
8.表单输入绑定
你可以用 v-model 指令在表单 < input>、< textarea> 及 < select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
自带一些好用的修饰符:.lazy、.number、.trim
9.组件
一个页面由若干组件构成,组件套组件。(封装思想)
- 组件:实现页面中局部功能代码和资源的集合。
- 组件的复用:取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。
- 组件的命名:有规范
- 组件的嵌套:注意父子组件,子组件在父组件中注册,层级关系。
非单文件组件:1个文件中包含有n个组件(a.html)
组件由new出来的vm管理:1.定义(创建)组件(.extend)、2.注册组件(局部注册)(.compment or compents:{})、3. 编写组件标签(<命名></命名>)
全局注册相比局部注册,任意vm都能玩都能用,局部相当于只在指定vm里注册了。
每次调用v.extend(),返回的都是一个全新的VueComponent。组件也是VueComponent实例对象。
VM(Vue的实例对象)和VC(VueComponent的实例对象):组件是可复用的vue实例,仅有的例外是像el这样的根实例特有的选项。
单文件组件:1个文件中只有1个组件(a.vue)
两种方式处理加工.vue:1.webpack 2.vue cli
<template>
<!--组件的结构-->
<!--模板里面必须有个根元素,也就是<div></div>-->
<!--template的作用其实也就是个分割-->
</template>
<script>
// 组件交互相关代码
// Vue.expend这些个都省略了,因为vue底层帮你干
// 因为vue组件生来就是为了被别人调用,所以需要暴露(有接口的感觉)
//
export default {
// 配置对象,name、data、method等等
}
</script>
<style>
/* 组件的样式 */
</style>
main.js入口文件(有的脚手架里叫index.js,react里叫app.js)里写vm
App.vue(hand of king)
assets静态资源文件
run的流程:npm run serve -> main.js -> app和组件s -> index.html
main中vue的render 搞精简版vue,
vue cli隐藏了许多重要的配置文件
在vue中,html标签里,ref属性可以代替id,method通过this.$refs拿到标签。
在组件标签里,id拿的是div,ref拿到组件的实例对象。
vue常用API$ refs :给.vue的dom节点(div)或组件(son)记上ref属性(< div ref=”box1” />或< sonComp ref=”box1” />),在js里用this.$refs.box1就能拿到这个dom元素或是拿到这个组件的引用从而操作组件的方法数据。
vue常用API$ nextTick() :在修改数据后使用,将回调延迟到下次DOM更新循环后执行。即,在vue中更改数据后,dom那边还没更新渲染,此时直接打印出来dom的值还是旧值,而用$nextTick()后,会回调dom更新渲染数据后,此时打印出来dom的值就是新值了。
props(property属性):组件中的props:{},可以在复用组件时动态变值,如果写在data:{}里就相当于给组件写死了。组件标签上传prop值,name=”12”(name传的是12字符串),:name2=”12”(传的number12,因为v-bind:name2=”就是js表达式的值”,传的是引号里js表达式的值)
vue不希望改prop,即不希望用method再改prop。如果非要改,由于prop优先级先于data,即vue会先准备prop里的,再初始化data里的,可以通过配置data里的和prop里的建立关系,再改。(vue组件先通过prop拿到数据,然后才再初始化data里的东西,vue的工作细节)
mixin(混入):两个组件共享一个配置(函数),复用一些功能
vue中的mixins:[name1,nam2,…]
插件:plung…,Vue.use(plung…),能增强vue,把一些全局的挂到Vue上
10.路由
路径:组件(key:value)
11.文件含义
.gitignore:git忽略文件,某些文件/文件夹不接受git管理
babel.config.js:es6转es5,babel转换文件
package.json:npm规范包说明书
package-lock.json:包管理文件
main.js:入口,run后首启
12.文件含义
vue inspect > output.js:显示隐藏的vue脚手架配置
vue.config.js:个性化定制脚手架(vue官网查字典)
13.全局事件总线
任意组件间的通信:
Vue.prototype.$ bus = this,(.$bus也可以挂在window上做出总线,但有点不好)
在vm(main.js里)的beforecreate钩子上挂(写这条语句)
$ on,监听自定义事件
(eg监听自定义事件hello)
this.x.$on(‘hello’,(data)=>{ consol.log(‘data’) })
$ off,beforedestory钩子关掉事件
this.x.$off(‘hello’)
$ emit,触发事件
this.x.$emit(‘hello’,666)
14.vuex
在vue中实现集中式状态(数据)管理的一个vue插件,也可以用来组件间通信。
(当多个组件共享读写某个数据,用事件总线有一些乱,此时vuex可以解决,相当于不用在每个组件里写on和emit。抽出来个共享区域vuex)
总结:事件总线中通信,把数据放在自己身上,别的地方想用;vuex中通信,把数据抽出来放在vuex上,大家通用。
15.vue插槽
vue中的插槽,指的是子组件中提供给父组件使用的一个占位符,用< slot></ slot>标签表示,父组件可以在这个占位符中填充任何模板代码,比如HTML、组件等,填充的内容会替换掉子组件的< slot></ slot>标签(替换占位符)。
vue中的插槽大致可以分为默认插槽、具名插槽和作用域插槽三种。
默认插槽
默认插槽是最简单的一种插槽,和上面的描述一致,就是通过替换占位符达到在父组件中更改子组件中内容的效果。
在子组件中放置一个占位符(插槽):
<template>
<span>
<span>谁是最可爱的人?</span>
<slot></slot>
</span>
</template>
<script>
export default {
name: 'child'
}
</script>
然后在父组件中引用这个子组件,并给这个占位符(插槽)填充内容:
<template>
<div>
<span>今日问答:</span>
<child>
<span>当然是yanggb了</span>
</child>
</div>
</template>
这个时候页面展现的内容就会是【今日问答:谁是最可爱的人?当然是yanggb了】。
在上面的例子中,如果在子组件中没有放置< slot>< slot>标签占位符,就不会有【当然是yanggb了】这个答案了,问题永远得不到任何回应,这就是插槽因此而存在的意义。事实上,如果子组件中没有使用插槽,父组件要是需要往子组件中填充模板或者html,基本上是没有其他办法能做到的。
具名插槽
来想象一个这样的场景:在子组件中有两个要替换占位符的地方(两个插槽),这时候父组件如果要将相应的内容填充到相应的插槽中,靠默认插槽是没有办法的,因为没有办法判断相应的内容要填充到哪个插槽中。为了应对这样的场景,具名插槽应运而生。
所谓的具名插槽,其实就是给子组件中的插槽取一个名字,而父组件就可以在引用子组件的时候,根据这个名字对号入座,将相应内容填充到相应的插槽中。
在子组件中放置两个具名插槽:
<template>
<div>
<span>我是第一个插槽</span>
<slot name="yanggb1"></slot>
<span>我是第二个插槽</span>
<slot name="yanggb2"></slot>
</div>
</template>
<script>
export default {
name: 'child'
}
</script>
在父组件中引用该子组件,并通过v-slot:[name]的方式将相应的内容填充到相应的插槽中:
<template>
<div>
<span>两个插槽:</span>
<child>
<template v-slot:yanggb1>
<span>yanggb1,</span>
</template>
<template v-slot:yanggb2>
<span>yanggb2</span>
</template>
</child>
</div>
</template>
这时候页面展示的内容就会是【两个插槽:第一个插槽yanggb1,第二个插槽yanggb2】。
使用默认插槽和具名插槽的注意事项
1.如果子组件中存在多个默认插槽,那么父组件中所有指定到默认插槽的填充内容(未指定具名插槽),会全部填充到子组件的每个默认插槽中。
2.即使在父组件中将具名插槽的填充顺序打乱,只要具名插槽的名字对应上了,填充的内容就能被正确渲染到相应的具名插槽中,一个萝卜一个坑。
3.如果子组件中同时存在默认插槽和具名插槽,但是在子组件中找不到父组件中指定的具名插槽,那么该内容会被直接丢弃,而不会被填充到默认插槽中。
作用域插槽
作用域插槽的概念和使用,相比于前面的默认插槽和具名插槽,会比较难于理解和运用。前面的两个插槽强调的是填充占位的【位置】,而作用域插槽强调的则是数据作用的【范围】。
所谓的作用域插槽,其实就是带参数(数据)的插槽,即在子组件的插槽中带入参数(数据)提供给父组件使用,该参数(数据)仅在插槽内有效,父组件可以根据子组件中传过来的插槽参数(数据)对展示内容进行定制。
在子组件中放置一个带参数(数据)的插槽:
<template>
<div>
<span>插槽中的参数值是</span>
<slot :yanggb="yanggb"></slot>
</div>
</template>
<script>
export default {
name: 'child',
data() {
return {
yanggb: {
yanggb1: 'yanggb1',
yanggb2: 'yanggb2'
}
}
}
}
</script>
在父组件中引用该子组件,并通过slot-scope来接受子组件的插槽中传过来的参数和使用该数据。
<template>
<div>
<span>作用域插槽:</span>
<child>
<template slot-scope="yanggb">
{{ yanggb.yanggb.yanggb1 }}
</template>
</child>
</div>
</template>
这时候页面展示的内容就会是【作用域插槽:插槽中参数值是yanggb1】。
另外,因为在template的{{}}是支持表达式的,这个时候就可以利用子组件传过来的参数值的不同进行页面内容的定制。
<template>
<div>
<span>作用域插槽:</span>
<child>
<template slot-scope="yanggb">
{{ yanggb.yanggb.yanggb1 || '空值' }}
</template>
</child>
</div>
</template>
这时候,如果子组件中传过来的参数是空值,页面的展示内容就会是【作用域插槽:插槽中参数值是空值】。
作用域插槽的使用场景多种多样,在各种框架中的应用也是十分广泛,比如ElementUI中的对表格的某一行或某一列进行展示内容的定制,就是作用域插槽的一个典型应用场景。
16.路由与组件(Vue路由和组件分别在什么场景使用)
切换子路由和切换组件都能到达切换视图的效果,什么场景下该用子路由,什么场景下该使用子组件呢? 例如:例如Tab切换,三个Tab对应不同的视图,切换Tab时,是通过逻辑控制显示不同的子组件比较好,还是添加一个子路由,通过跳转路由的方式切换视图好。从这个问题的思考,衍生出这个问题:既然我们控制子组件的显示隐藏即可做到切换视图的目的,那么vue-router的存在比这种控制子组件切换视图的方式好在哪里呢,在开发过程中对于两种方式的选择有什么好的实践吗?
-
vue-router vue-router 底层其实是用 hash 和 history api 来模拟浏览器的路由(前进,后退,刷新)行为的。传统的页面跳转我们可能会这样做,比如从 a.html 跳转到 b.html : a.html < a href=“./b.html”> go b.thml </ a> 那么组件模式下呢,比如有 a.vue 跳转到 b.vue 组件: a.vue < router-link to=“/b”> go b.vue < router-link> 可以看出,路由让我们实现了单页面开发中的“多页面”间切换效果。
-
is属性(动态组件):is是一个动态组件的特殊属性,用于在运行时动态地绑定组件类型。(之前用v-if切换“组件级别”不太对)
component-is vue有个内置组件 < component /> 可以实现一些动态组件加载,就像楼主说的多Tab切换。当然官文上也介绍了。其实它跟 组件很像,不同的是: router-view 通过改变 URL 或编程式导航都可触发视图更新 component 只能通过编程式改变 is 的组件名字触发视图更新。 -
所以 vue-router 和 component-is 区别还是很明显的: vue-router 适用于应用级别的页面间的导航。而 component-is 适用于区域性功能型模块级别的导航。假如你想开发一个公共组件,一个 router 组件下面可能包含多个component-is(体现在工程目录里就是views里的某个view包含components里的某个或多个component)。适合用哪个,依你的项目而定,绝大多还是会选择 vue-router 来做路由管理,vuex 来做页面间数据存储。
其实它们的底层原理差不多(如果你说的「切换组件」是指 ,那底层原理几乎一样),关键区别在于业务。有一个简单的原则:如果你需要用户通过URL直达某一个视图(包括子视图),那就用路由方案。
两者的层级不一样。1.路由是对应功能页面级别。比如XXX查询列表页面。这个页面上有新增,修改,删除等等 2.在一个页面上,可能元素比较多,比如有多个tab。如果代码都写在这个vue文件里,行不行?行!但可读性和扩展性比较差。通常为了结构更清晰采用组件的方式。 简单来说,就是页面是否需要跳转?还是一个页面根据不同的状态展示不同的内容?前者是路由,后者是组件。(当然,之前学的时候但凡.vue都叫他组件,别搞混)
17.vue中< keep-alive >< /keep-alive >
在组件切换(配合:is属性)时保留该组件的状态,而不是重新渲染该组件。用keep-alive包住动态切换的组件。有include属性,可以控制缓存哪个/几个特定组件。
18.scroll
参考文献:
https://blog.csdn.net/weixin_52212950/article/details/123609373
vue监听页面滚动
https://blog.csdn.net/qq_29483485/article/details/124493063
19.window.addeventlistener
参考文献:
https://blog.csdn.net/qq_52421092/article/details/128471017
https://www.cnblogs.com/ConfidentLiu/p/7815624.html
20.组件中常用disabled的属性
一种是直接: disabled=”true”;一种是:disabled=”method()”,可以写组件什么时候disabled掉的策略。
21.vue中的this
代码中没加this,可能出现不报错,导致数据没挂载上,排查问题可以注意
this动态获取
22.this.$forceUpdate()
vue中,数据的绑定会自动发生变化。但如果是复杂的对象,例如一个对象数组,你直接去给数组上某一个元素增加属性,或者直接把数组的length变成0,vue就无法知道发生了改变。或者for嵌套太多没render上。
this. $set()可解决这个问题(vue文档),this. $forceUpdate() 更方便,可以强制刷新挂上变化数据
23.v-for遍历对象(value,key,index)和遍历数组(item,index)
- 遍历对象:遍历对象时可以传入三个值,按顺序可以为value、value和key、value和key和index
- 遍历数字:遍历数组时可以传入两个值,按顺序可以为item、item和index
24.异步组件(懒加载的一种方式)
以下使用方式的前提条件是webpack 2 和 ES2015 语法加在一起
(如果你是一个 Browserify 用户同时喜欢使用异步组件,很不幸这个工具的作者明确表示异步加载“并不会被 Browserify 支持”,至少官方不会。Browserify 社区已经找到了一些变通方案,这些方案可能会对已存在的复杂应用有帮助。对于其它的场景,我们推荐直接使用 webpack,以拥有内置的头等异步支持。)
(首先懒加载验证需要webpack打包后启的项目才能体现,因为同时依赖webpack的代码分割能力。)
-
vue路由懒加载:把不同路由对应的组件分割成功不同的代码块,然后当路由被访问的时候才加载(下载)对应组件。在路由配置中import。
-
vue组件懒加载:‘my-components’: ()=>import(‘组件路径’) 和 v-if结合。
vue异步组件懒加载需要配合v-if使用。 -
vue异步组件懒加载和v-if条件渲染组件惰性加载的区别:
1.首先,直接v-if不是懒加载,v-if是条件渲染。因为此时v-if的组件内容已经在打包后的主js文件中了(相当于代码没分块),但是没渲染,并且组件内的接口也没发送请求(估计是没执行)。
2.用了’my-components’: ()=>import(‘组件路径’) 和 v-if的,他的js干脆没在打包后的主js文件中。当触发需要时(此时用的是v-if),才懒加载出来js文件并执行(相当于该组件代码分块到另一段js文件中了)。从瀑布流也能看出该文件是后加载的。
3.综上,vue异步组件更符合懒加载的精神。
验证方式用webpack打包后看js文件,v-if的vue组件或内容直接放到了业务逻辑js中。而
(有时报错,如果使用Babel转译代码,需要安装@babel/plugin-syntax-dynamic-import插件来支持动态导入语法,并在.babelrc中配置。)
25.vue中引入子组件,在html里多次< my-compents / >创建,是互相隔离且不同的dom节点,所以数据也是隔离的。(相当于new)
app.vue
FuLiCalculater.vue
页面效果
26.在vue中动态的引入图片为什么要使用require?
- 因为动态添加src被当做静态资源处理了,而被编译过后的静态路径无法正确的引入资源,所以要加上require。
原理:webpack会打包编译src引入的路径,也会打包编译图片的路径和名称。
- 动态引入一张图片,没有使用require:src后面的属性值,实际上是一个变量。webpack会根据v-bind指令去解析src后面的属性值,故没有编译,就是写在代码里的字符串路径。
- 动态引入一张图片,使用require:使用了require方法引入的资源,该资源就会当成模块并根据配置文件进行打包,并返回最终的打包结果。
- 静态引入一张图片,没有使用require:在webpack编译的vue文件的时候,遇见src等属性会默认的使用require引入资源路径。
Tips:webpack打包的时候,对图片资源进行了相关的配置。对于小于8k的图片,会将图片转成base64 直接插入图片,不会再在dist目录生成新图片。对于大于8k的图片,会打包进dist目录,之后将新图片地址返回给src。该配置可以自己修改。