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)
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页面/浏览器等概念的生命周期)
小程序生命周期(基于页面监听概念的生命周期)
2.模板语法
插值语法(用于解析标签体):{{}}
{{}}里可以写方法
解决插值表达式闪烁问题:v-cloak
< div id=“app” v-cloak>{{ msg }}< /div>
[v-cloak] {
display: none;
}
通过methods做事件处理(回调函数,js里的DOM事件回调函数)
不要在property或回调上使用箭头函数,造成this错误
用户输入可以用v-model双向绑定
el两种写法,el可以用.$mount挂载的方式替代,这么使用更加灵活。
data有两种写法,一是data对象式,二是data函数式
一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind 指令可以用于响应式地更新 HTML attribute。另一个例子是 v-on 指令,它用于监听 DOM 事件。
“动态参数”:从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数。
…
这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data property attributeName,其值为 “href”,那么这个绑定将等价于 v-bind:href。
“(事件修饰符)修饰符”:
hh
.native: Vue给自定义组件绑定原生事件(常见使用场景,click点不动,加个native试试)
.prevent阻止默认事件(点了不自动跳到百度了,如上)
.stop 阻止事件冒泡
.once 事件只触发一次
.capture等等
v-bind 缩写是 :
v-on 缩写是 @
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 阻止事件冒泡
.once 事件只触发一次
.capture等等
按键修饰符:在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符。
系统修饰符:可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
8.表单输入绑定
你可以用 v-model 指令在表单 < input>、< textarea> 及 < select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
自带一些好用的修饰符:.lazy、.number、.trim
9.组件
一个页面由若干组件构成,组件套组件。(封装思想)
非单文件组件: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
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中的插槽大致可以分为默认插槽、具名插槽和作用域插槽三种。
默认插槽
默认插槽是最简单的一种插槽,和上面的描述一致,就是通过替换占位符达到在父组件中更改子组件中内容的效果。
在子组件中放置一个占位符(插槽):
谁是最可爱的人?
然后在父组件中引用这个子组件,并给这个占位符(插槽)填充内容:
今日问答:
当然是yanggb了
这个时候页面展现的内容就会是【今日问答:谁是最可爱的人?当然是yanggb了】。
在上面的例子中,如果在子组件中没有放置< slot>< slot>标签占位符,就不会有【当然是yanggb了】这个答案了,问题永远得不到任何回应,这就是插槽因此而存在的意义。事实上,如果子组件中没有使用插槽,父组件要是需要往子组件中填充模板或者html,基本上是没有其他办法能做到的。
具名插槽
来想象一个这样的场景:在子组件中有两个要替换占位符的地方(两个插槽),这时候父组件如果要将相应的内容填充到相应的插槽中,靠默认插槽是没有办法的,因为没有办法判断相应的内容要填充到哪个插槽中。为了应对这样的场景,具名插槽应运而生。
所谓的具名插槽,其实就是给子组件中的插槽取一个名字,而父组件就可以在引用子组件的时候,根据这个名字对号入座,将相应内容填充到相应的插槽中。
在子组件中放置两个具名插槽:
我是第一个插槽
我是第二个插槽
在父组件中引用该子组件,并通过v-slot:[name]的方式将相应的内容填充到相应的插槽中:
两个插槽:
yanggb1,
yanggb2
这时候页面展示的内容就会是【两个插槽:第一个插槽yanggb1,第二个插槽yanggb2】。
使用默认插槽和具名插槽的注意事项
1.如果子组件中存在多个默认插槽,那么父组件中所有指定到默认插槽的填充内容(未指定具名插槽),会全部填充到子组件的每个默认插槽中。
2.即使在父组件中将具名插槽的填充顺序打乱,只要具名插槽的名字对应上了,填充的内容就能被正确渲染到相应的具名插槽中,一个萝卜一个坑。
3.如果子组件中同时存在默认插槽和具名插槽,但是在子组件中找不到父组件中指定的具名插槽,那么该内容会被直接丢弃,而不会被填充到默认插槽中。
作用域插槽
作用域插槽的概念和使用,相比于前面的默认插槽和具名插槽,会比较难于理解和运用。前面的两个插槽强调的是填充占位的【位置】,而作用域插槽强调的则是数据作用的【范围】。
所谓的作用域插槽,其实就是带参数(数据)的插槽,即在子组件的插槽中带入参数(数据)提供给父组件使用,该参数(数据)仅在插槽内有效,父组件可以根据子组件中传过来的插槽参数(数据)对展示内容进行定制。
在子组件中放置一个带参数(数据)的插槽:
插槽中的参数值是
在父组件中引用该子组件,并通过slot-scope来接受子组件的插槽中传过来的参数和使用该数据。
作用域插槽:
{{ yanggb.yanggb.yanggb1 }}
这时候页面展示的内容就会是【作用域插槽:插槽中参数值是yanggb1】。
另外,因为在template的{{}}是支持表达式的,这个时候就可以利用子组件传过来的参数值的不同进行页面内容的定制。
作用域插槽:
{{ yanggb.yanggb.yanggb1 || '空值' }}
这时候,如果子组件中传过来的参数是空值,页面的展示内容就会是【作用域插槽:插槽中参数值是空值】。
作用域插槽的使用场景多种多样,在各种框架中的应用也是十分广泛,比如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> 可以看出,路由让我们实现了单页面开发中的“多页面”间切换效果。
其实它们的底层原理差不多(如果你说的「切换组件」是指 ,那底层原理几乎一样),关键区别在于业务。有一个简单的原则:如果你需要用户通过URL直达某一个视图(包括子视图),那就用路由方案。
两者的层级不一样。1.路由是对应功能页面级别。比如XXX查询列表页面。这个页面上有新增,修改,删除等等 2.在一个页面上,可能元素比较多,比如有多个tab。如果代码都写在这个vue文件里,行不行?行!但可读性和扩展性比较差。通常为了结构更清晰采用组件的方式。 简单来说,就是页面是否需要跳转?还是一个页面根据不同的状态展示不同的内容?前者是路由,后者是组件。(当然,之前学的时候但凡.vue都叫他组件,别搞混)
17.scroll
参考文献:
https://blog.csdn.net/weixin_52212950/article/details/123609373
vue监听页面滚动
https://blog.csdn.net/qq_29483485/article/details/124493063
18.window.addeventlistener
参考文献:
https://blog.csdn.net/qq_52421092/article/details/128471017
https://www.cnblogs.com/ConfidentLiu/p/7815624.html
19.组件中常用disabled的属性
一种是直接: disabled=”true”;一种是:disabled=”method()”,可以写组件什么时候disabled掉的策略。
20.vue中的this
代码中没加this,可能出现不报错,导致数据没挂载上,排查问题可以注意
this动态获取
21.this.$forceUpdate()
vue中,数据的绑定会自动发生变化。但如果是复杂的对象,例如一个对象数组,你直接去给数组上某一个元素增加属性,或者直接把数组的length变成0,vue就无法知道发生了改变。或者for嵌套太多没render上。
this. $set()可解决这个问题(vue文档),this. $forceUpdate() 更方便,可以强制刷新挂上变化数据
22.v-for遍历对象(value,key,index)和遍历数组(item,index)