款用于构建用户界面的JavaScript框架。它基于标准HTML、CSS和JavaScript构建,并提供了一套声明式的、组件化的编程模型,可以高效地开发用户界面。无论是简单还是复杂的界面,Vue都可以胜任。

基础

对于MVVM的理解?

  • MVVMModel-View-ViewModel 的缩写
  • MVVM 的设计原理是基于 MVC
  • Model代表数据模型 ;View 代表UI 组件视图;ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步 View 和 Model 的对象,连接 Model 和 View

优势:vuemode 之间是双向数据传递的,视图改变数据就可以改变,数据改变了视图也跟着改变

Vue的生命周期

生命周期:Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载 Dom →渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。
vue 生命周期的作用:它的生命周期中有多个事件钩子,在控制整个 Vue 实例的过程时更容易形成好的逻辑
vue 生命周期总共有 8 个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后
第一次页面加载会触发以下几个钩子:beforeCreate, created, beforeMount, mounted
DOM 渲染在 mounted 周期中就已经完成

Vue的生命周期

beforeCreate:在实例创建之间执行,数据是未加载状态。
created:在实例创建、数据加载后,能初始化数据,DOM 渲染之前执行。
beforeMount:虚拟 DOM 已创建完成,在数据渲染前最后一次更改数据。el 未挂载。
mounted:页面、数据渲染完成。el 挂载完毕。可以访问 DOM 节点。
beforeUpdate:重新渲染之前触发。不会造成重渲染。
Updated:数据已经更新完成,DOM 也重新 render 完成,更改数据会陷入死循环。
beforeDestroy:实例销毁前执行,实例仍然完全可用。
destroyed:实例销毁后执行,这时候只剩下 DOM 空壳。

Vue3的生命周期?

创建期setup()
挂载期:

  • onBeforeMount()组件挂载到节点上之前执行的函数
  • onMounted()组件挂载完成后执行的函数,此时可以访问和操作DOM

更新期:

  • onBeforeUpdate()组件更新之前执行的函数
  • onUpdated()组件更新完成之后执行的函数

销毁期:

  • onBeforeUnmount()组件卸载之前执行的函数,可以进行一些善后的工作,例如清理定时器等
  • onUnmounted()组件卸载完成后执行的函数,表示组件已经被完全销毁

vue获取数据在哪个周期函数?

一般 created / beforeMount / mounted 皆可, 比如如果你要操作 DOM , 那肯定 mounted 时候才能操作

Vue实现数据双向绑定的原理

Vue2 实现数据双向绑定的原理:Object.defineProperty()
采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调

Vue3 实现数据双向绑定的原理:Proxy
属性被修改时,Proxy 对象的 set 陷阱会被触发。此时,Vue3会通知所有依赖该属性的 Watcher 对象进行更新。Watcher 对象会调用对应的更新函数,从而触发视图的重新渲染

Vue的路由实现:hash模式 和 history模式区别,上线有什么区别。

**hash模式:**在浏览器中符号“#”, 用window.location.hash读取
history模式:采用HTML5新特性;方法 pushState(),replaceState() 可修改浏览器历史记录栈popState 事件监听状态变更。
上线区别
hash模式:URL 形式:http://example.com/#/path
# 后面的部分来模拟一个完整的 URL
,不会引起页面的重新加载。
history 模式:URL 形式:http://example.com/path需配置服务器,否则会当成真正的路径要后端配置重定向,不然访问不到。

Vue组件间的参数传递 和父子组件方法调用(组件通信)

  • 父组件与子组件传值
    • 父组件传给子组件:子组件通过props方法接受数据;
    • 子组件传给父组件:$emit 方法传递参数
  • 非父子组件间的数据传递,兄弟组件传值
    • eventBus,就是创建一个事件中心,相当于中转站,可用它传递事件和接收事件。比较适合项目较小时。
    • 事件总线: Vue.prototype.$bus = new Vue();使用 Vuex
  • provide 和 inject
  • 父组件调用子组件方法:this.$refs.mychildren.function()
  • 子组件调用父组件方法: this.$parent.function()

params和query的区别

**用法:**query 用 path 引入,params 用 name 引入,接收参数类似,分别是 this.$route.query.name , this.$route.params.name
**url地址显示:**query 类似于 ajax 中 get 传参,params 类似于 post,或者说 query 在浏览器地址栏中显示参数,params 不显示

1
2
3
4
5
6
7
8
9
10
11
12
// params传值
{path:/user/:id} // 路由里:id
<router-link to ="/user/123"></router-link> // 组件传值 用/id
this.$router.params.id // js代码中获取路由传递的id值

// query传值
{path:'/user'} // 路由
// 组件传值 使用?拼接 参数之间用&
<router-link to ="/user? id=123"></router-link>
<router-link to ="/user?id=123&name=zs"></router-link> //组件传值
this.$router.query.id //取值
this.$router.query.name //取值

vuex是什么?怎么使用?哪种功能场景使用它?

vuex 是一种集中式状态管理模式,它按照一定的规则管理状态,保证状态的变化是可预测的。
vuex 可以理解为一种开发模式或框架,通过状态集中管理驱动组件的变化,应用级的状态集中放在store中,改变状态的方式是提交 mutations,异步逻辑封装在 action 中

使用方式:
在 main.js 引入 store,注入。只用来读取的状态集中放在 store 中;
改变状态的方式是提交 mutations ,这是个同步的事物; 异步逻辑应该封装在 action 中。

场景:单页应用中,组件之间的状态、音乐播放、登录状态、加入购物车
state:定义初始化状态
getters:获取状态
mutations:设置状态
actions:异步提交 mutations
modules:把状态管理模块化,各自的组件构成各自的模块

css只在当前组件起作用

在 style 标签中写入 scoped 即可 例如:<style scoped></style>

v-if 和 v-show 区别

相同点:v-if 与 v-show 都可以动态控制 dom 元素显示隐藏
**不同点:**v-if 将 dom 元素整个添加或删除 ,v-show 隐藏是为该元素添加 css–display:none,dom 元素还在

routeroute和router的区别

$route路由信息对象,包括 path,params,hash,query,fullPath,matched,name等路由信息参数。 而$router 是VueRouter 路由实例 对象包括了路由的跳转方法,钩子函数等。

vue.js的两个核心是什么?

数据驱动、组件系统

computed、watch、methods的区别

computed 要有返回值,支持缓存。watch 不支持缓存。methods 不支持缓存。
**watch 项目用处:**搜索框输入框的监听;监听路由地址的改变

vue几种常用的指令

1
2
3
4
5
6
7
v-for (循环指令,可以循环数组或对象)
v-if (是否渲染元素,会销毁并重建)
v-bind (动态绑定数据)
v-on (绑定事件监听器)
v-show (显示隐藏元素,修改元素的 display 属性)
v-else(与 v-if 配合使用)
v-model (实现双向绑定)

v-for与v-if 一起使用

由于v-for会先执行,v-if 将分别重复运行于每个 v-for 循环中。这可能会导致不必要的计算,性能下降,特别是在处理大型数据集时,可能会使代码的逻辑变得不清晰。
Vue 2中在同一个元素上同时使用这两个指令时 v-for 的优先级高于 v-if
Vue 3中,v-if 的优先级高于 v-for。不推荐一起使用 在外层包装一个 template 标签

v-on 可以绑定多个方法吗?

可以 … 例: <p @click=“one(),two()”>点击

vue中key 值的作用

原理是vue 在**pacth过程中通过 key 可以精准判断两个节点是否是同一个, 从而避免平凡更新不同元素,减少dom操作,提升性能
key值
对数据改变之后的diff更新比较有很大的性能提升**,或者说有了key和没有key是两种比较和更新机制
作用主要是为了高效的更新虚拟DOM。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果,就不会达到最小更新
index值不是一定不变的,若不加key值,删除前面的项。后面的index可能变也可能不变,如加个定时器时会变,不加定时器不变

$nextTick的使用

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新的 DOM。

$nextTick能获取到最新dom是什么原理

当修改了数据,Vue 会将这些变更放入一个异步任务队列,而不是立即更新 DOM。
$nextTick回调函数是在任务队列中的所有任务执行完毕后调用的,这意味着 DOM 更新已经完成。

项目初始化页面闪动问题

vue 页面在加载的时候闪烁花括号{},v-cloak 指令和 css 规则如 [v-cloak]{ display:none }一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
如下所示:

1
2
3
4
5
6
7
8
9
10
/*css样式*/
[v-cloak] {
display: none;
}
<!--html代码-->
<div id="app" v-cloak>
<ul>
<li v-for="item in tabs">{{item.text}}</li>
</ul>
</div>

怎么理解vue中的 diff 算法?

diff 算法是虚拟DOM的产物,通过新旧虚拟 dom 对比, 将变化的地方更新在真实的 dom 上
diff 算法能精准找到发生的变化的地方

vue 怎么缓存 keep-alive

keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染;可以实现组件缓存,当组件切换时不会对当前组件进行卸载;有 includeexclude 两个属性,可以有条件的进行组件缓存
keep-alive功能:当组件切换为非激活状态时,不会触发销毁流程,而是将组件实例及其状态完整封存。这一特性使其成为保留组件状态、优化渲染性能的核心工具。
生命周期钩子联动。当组件在 keep-alive 内切换时,会触发专属生命周期钩子:

  • function a() { var i = 0; function b(){ alert(++i); } return b;}var c = a();c()js
  • deactivated:组件失活时调用(被切换出但未销毁)

应用场景1:路由页面状态持久化

1
2
3
4
5
6
7
8
<!-- 缓存所有路由组件 -->
<keep-alive>
<router-view></router-view>
</keep-alive>
<!-- 精准缓存指定路由组件 -->
<keep-alive :include="['Home', 'Profile']">
<router-view></router-view>
</keep-alive>

应用场景2:动态组件状态保留

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<keep-alive>
<component :is="currentComponent"></component>
</keep-alive>
</template>

<script>
export default {
data() {
return { currentComponent: 'Login' }
}
}
</script>

vue组件中data为什么必须是一个函数?

JavaScript 的特性所导致,在 component 中,data 必须以函数的形式存在,不可以是对象。组建中的 data 写成一个函数,数据以函数返回值的形式定义,这样每次复用组件的时候,都会返回一份新的 data ,相当于每个组件实例都有自己私有的数据空间,它们只负责各自维护的数据,不会造成混乱。而单纯的写成对象形式,就是所有的组件实例共用了一个 data ,这样改一个全都改了。

assets和static的区别?

这两个都是用来存放项目中所使用的静态资源文件
两者的区别:
assets 中的文件在运行 npm run build 的时候会打包,也就是会被压缩体积,代码格式化之类的。打包之后也会放到 static 中
static 中的文件则不会被打包
**建议:**将图片等未处理的文件放在 assets 中,打包减少体积。而对于第三方引入的资源文件(如:iconfont.css等)可以放在static 中,因为这些文件已经经过处理了。

vue的常用修饰符

.prevent:提交事件不再重载页面;等同于 JavaScript 中的 event.preventDefault(),防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播)
.stop:阻止单击事件冒泡;等同于 JavaScript 中的 event.stopPropagation() ,防止事件冒泡。
.self:只会触发自己范围内的事件,不包含子元素;
.capture:事件侦听,事件发生的时候会调用;与事件冒泡的方向相反,事件捕获由外到内
.once:只会触发一次
.passive:提升移动端的性能。

vue其他修饰符?

按键修饰符:.enter.delete.space.esc.up.down
系统修饰键:.ctrl.alt
鼠标按钮修饰符:.left.right

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 阻止单击事件继续传播
<a v-on:click.stop="doThis"></a>
// 提交事件不再重载页面
<form v-on:submit.prevent="onSubmit"></form>
// 修饰符可以串联
<a v-on:click.stop.prevent="doThat"></a>
// 只有修饰符
<form v-on:submit.prevent></form>
// 添加事件监听器时使用事件捕获模式 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理
<div v-on:click.capture="doThis">...</div>
// 只当在 event.target 是当前元素自身时触发处理函数 即事件不是从内部元素触发的
<div v-on:click.self="doThat">...</div>
// 点击事件将只会触发一次
<a v-on:click.once="doThis"></a>
// 滚动事件的默认行为 (即滚动行为) 将会立即触发, 不会等待onScroll完成,这其中包含 `event.preventDefault()` 的情况
<div v-on:scroll.passive="onScroll">...</div>

vue深度监听(watch)

1
2
3
4
5
6
7
8
9
10
11
12
13
watch:
// 第一种
"a.b.c":function(newValue, oldValue){
console.log(newValue, oldValue);
}
// 第二种
a: {
deep: true, // deep为ture 意味着开启了深度监听a对象里面任何数据变化都会触发
handler(newValue, oldvalue){
//这个函数是固定写法
console.log(newValue, oldValue);
}
}

Vue-router

vue路由的钩子函数 (路由守卫)

首页可控制导航跳转,beforeEach,afterEach等,一般用于页面title修改。一些需要登录才能调整页面的重定向功能。
beforeEach((to,from,next)=>{});

  • to:route 即将进入的目标路由对象,
  • from:route 当前导航正要离开的路由
  • next:function一定要调用该方法resolve这个钩子。执行效果依赖 next 方法的调用参数。可控制网页跳转。

router.afterEach((to,from)=>{});

  • to:已进入的目标路由对象
  • from:已离开的路由对象

vue-router有哪几种导航钩子?以及它的参数?

第一种:全局导航钩子:router.beforeEach(to,from,next),**作用:**跳转前进行判断拦截。
第二种:组件内的钩子
第三种:单独路由独享组件
beforeRouteEnter、afterEnter、beforeRouterUpdate、beforeRouteLeave
**参数:**to(去的那个路由)、from(离开的路由)、next(一定要用这个函数才能去到下一个路由,不用就拦截)

Vue-router的跳转原理

Vue-router的跳转原理: 通过不同的模式来实现页面的无刷新跳转,主要包括 hash 模式、history 模式和 abstract 模式。

  • hash:使用 URL hash 值来作路由。默认模式。
  • history:依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式。
  • abstract:支持所有 JavaScript 运行环境,如 Node.js 服务器端

路由之间的跳转:

  • 声明式(标签跳转)
    • <router-view>标签用于展示路由组件,DOM节点中使用 v-link 进行跳转,或使用 router-link 标签
  • 编程式(js跳转)

怎么定义vue-router的动态路由及如何获取传过来的动态参数?

在 router 目录下的 index.js 文件中,对 path 属性加上/:id
使用 router 对象的 params id
**用 watch 去监听 router 变化:**当路由发生变化的时候,在 watch 中写具体的业务逻辑

1
2
3
4
5
watch:{
$router(to, from){
console.log(to.path);
}
}

Vue的路由实现: hash模式和history模式(Vue的两种状态)

**hash模式:**即地址栏URL的#符号
通过 window.onhashchange 监听,匹配不同的 url 路径,进行解析,加载不同的组件,然后动态的渲染出区域内的html 内容,不会被包含在HTTP请求中,对后端完全没有影响
HashHistory 有两个方法:

  • HashHistory.push() 是将路由添加到浏览器访问历史的栈顶
  • hashHistory.replace() 是替换掉当前栈顶的路由

因为hash发生变化的url都会被浏览器历史访问栈记录下来,因此尽管浏览器没有请求服务器,但页面状态是和url关联起来的,浏览器还是可以进行前进后退的

history模式
利用 HTML5 History Interface 中新增的 pushState()replaceState() 方法。这两个方式应用于浏览器的历史记录栈,提供了对历史记录的修改功能。history模式不怕页面的前s进和后腿,就怕刷新,当刷新时,若服务器没有相应的响应或者资源,就会刷出404,而hash模式不会
route从当前router跳转对象里面可以获取namepathqueryparams等(<routerlink>传的参数有this.route 从当前 router 跳转对象里面可以获取 `name、path、query、params` 等 (`<router-link>`传的参数有`this.route.query或者this.route.params接收)导航到不同URL,则使用route.params` 接收) 导航到不同URL,则使用 `router.push方式,返回上一个history也是使用router.go/router.go/router.back` 方法