内容较多需要分几部
一.vue2面试题 - 生命周期有哪些?发送请求在created还是mounted?
1.1.生命周期有哪些
| vue2.X系统自带有8个 |
| beforeCreate |
| created |
| beforeMount |
| mounted |
| beforeUpdate |
| updated |
| beforeDestroy |
| destroyed |
复制
1.2.进入组件执行哪些生命周期
| beforeCreate |
| created |
| beforeMount |
| mounted |
复制
1.3在created中如何获取dome
| 只要异写异步代码,获取dom在异步中获取的就可以 |
| 列 |
| 定时器方法 |
| setTimeout(()=>{ |
| 获取dome的方法 |
| }) |
| |
| vue自带nextTick方法 |
| this.$nextTick(res=>{ |
| 获取dome的方法 |
| }) |
复制
1.4为什么发送请求不在beforeCreate里?
| 如果请求是在methods封装好的,在beforeCreate掉用的时候是拿不到methods里面的方法的 |
复制
1.5beforeCreate和created有什么区别
| beforeCreate中没有$data |
| created中有$data |
| |
| created中是可以拿到methods中的方法的 |
复制
1.6.父组件引入子组件生命周期执行顺序
父组件引入了子组件,会先执行父组件的前3个生命周期,再执行子组件的4个生命周期
| 父:beforeCreat、create、beforeMount |
| 子:beforeCreate、create、beforeMount、mounted |
| ... |
| 父:mounted |
复制
1.7发送请求在created中mounted?
| 这个问题需要看具体情况,按照上面的父组件引入子组件的顺序来看, |
| 如果需要优先加载子组件内容需要再mounted中,如果组件间没有依赖关系,在哪个都可以 |
复制
1.8加入keep-alive组件会执行哪些生命周期
如果使用了keep-alive组件,当前的组件会额外增加两个生命周期(系统8+2)
| activated 进入到组件 激活时 |
| deactivated 销毁时 |
复制
如果加入keep-alive第一次进入会执行5个生命周期
| beforeCreate |
| created |
| beforeMount |
| mounted |
| activated |
复制
1.9第二次或者第N次进入组件会执行哪些生命周期
| activated |
| |
| 如果没加入keep-valive会永远执行 |
| beforeCreate |
| created |
| beforeMount |
| mounted |
复制
2.0你在什么情况下使用过哪些生命周期,说一说生命周期的使用场景
| created 单组件请求 |
| mounted 同步获取dom, 如果子组件先请求父组件再请求 |
| activated 判断id是否相同,如果不相同发起请求 |
| deactivated 关闭页面记录视频播放时间,初始化的时候从上一记录开始 |
复制
二.关于组件
2.1组件传值(通信)的方式
| 父传后代 (后代拿到了父的数据) |
| 1.子组件通过props来接受父的传参 |
| props:{ |
| str1:{ |
| type:String, |
| default:'' |
| } |
| } |
| *这种方式父传子方便,但是传孙子背比较困难,并且不能修改父组件中的数据* |
| |
| 2.子组件直接使用父组件中的数据 |
| 子组件通过 this.$parent.xxx使用父组件中的数据 |
| *子组件可以直接修改父组件中的数据* |
| *缺点:这可能会破坏组件的封装性和可维护性。* |
| |
| 3.依赖注入 |
| 优势:父组件可以直接向某个后代组件传递参数,(不需要一级一级的找) |
复制
| 后代传父(父拿到了后代的数据) |
| 1.子组件传给父组件 |
| 子组件自定义事件 this.$emit('事件名字',传值) |
| 父组件 <组件名 @事件='事件名字'> </组件名> |
| 在methods中使用 |
| |
| 2. |
复制
复制
2.2父组件直接修改子组件中的值
| 1. 使用this.$children |
| 注意this.$children获取得是一个数据使用的时候应该: this.$children [索引] |
| * 繁琐 * |
| |
| 2. <组件名 ref='命名'></组件名> |
| this.$refs.命名.xxx = 'yyyyy' |
复制
2.3子组件如何修改父组件中的值
| 可以使用 this.$parent.xxx 获取到父组件中的值并修改 |
复制
2.4如何找到父组件
复制
2.5如何找到根组件
复制
2.6keep-alive
复制
2.7slot/插槽
| 1.匿名插槽:(没有名字) |
| |
| 子组件 |
| <div> |
| <div>返回</div> |
| <slot></slot> |
| </div> |
| <组件名> <div style='color:pink'>温馨提示</div></组件名> |
| 注意: 匿名插槽中的slot代表的是 组件的包括的所有内容 |
| |
| |
| |
| |
| 2.具名插槽(有名字) |
| 子组件 |
| <div> |
| <slot name="title"></slot> |
| <div>返回</div> |
| <slot name="text"></slot> |
| </div> |
| <组件名> |
| <template #title> |
| <h2 style="color: pink">标题</h2> |
| </template> |
| <template #text> |
| <div style="color: pink">温馨提示</div> |
| </template> |
| </组件名> |
| 注意: 名字需要在template标签中 |
| |
| |
| |
| 3.作用域插槽(传值) |
| 子组件 |
| <div> |
| <slot name="title"></slot> |
| <div>返回</div> |
| <slot name="text" :arr='arr'></slot> |
| </div> |
| data(){ |
| return { |
| arr:['a','b','c'] |
| } |
| } |
| 父组件接收 |
| <template #text='{arr}'> |
| <div style="color: pink">温馨提示</div> |
| </template> |
| 注意: 传多个使用,隔开 {arr,list,str} |
复制
2.8provide/inject
| provide/inject ===> 依赖注入 |
| |
| |
| // 父级组件提供 'foo' |
| <template> |
| <div> |
| <div>{{foo}}</div> |
| <son></son> |
| </div> |
| </template> |
| |
| <script> |
| import Son from "./Son"; |
| export default { |
| name: "parent", |
| components: { Son }, |
| provide() { |
| return { |
| foo: this.foo |
| }; |
| }, |
| data() { |
| return { |
| foo: { |
| too:"测试" |
| }, |
| }; |
| }, |
| mounted() { |
| console.log(this.foo) |
| }, |
| }; |
| </script> |
| |
| |
| |
| |
| //孙级组件,接收foo |
| <template> |
| <div>{{foo}}</div> |
| </template> |
| |
| <script> |
| export default { |
| name: "grandSon", |
| inject: ["foo"], |
| mounted() { |
| console.log(this.foo) |
| }, |
| }; |
| </script> |
复制
2.9如何封装组件
| 组件一定要难点,设计的知识点:slot,组件通信... |
复制
三关于VueX
3.1VueX有哪些属性
| 1.state 全局共享属性存放数据 |
| 2.getters 针对数据进行二次修改 |
| 3.mutations |
| 4.actions |
| 5.modules |
复制
3.2VueX使用state值
| 1.this.$store.state.xxx |
| |
| 2.辅助函数 mapState |
| import { mapState } from "vuex"; |
| computed:{ |
| ...mapState(['str']) |
| }, |
| 在页面上直接使用str , 在方法中this.str |
| |
| |
| 以上两种都可以拿到state的值, 那么他们的区别是什么 |
| |
| 使用this.$store.state.xxx 可以直接修改vueX里面的数据 |
| 使用辅助函数的形式是不可以修改的(辅助函数是复制了vuex文件里的内容,所以不能修改) |
复制
3.3VueX的getters值的修改
getters是针对于数据进行二次修改的
组件使用了getters中的内容,组件使用v-model的形式会发生什么
复制
3.4VueX的mutations和actions区别
| 相同点:mutations和actions都是来存放全局方法的 |
| 这个全局方法return的值拿不到 |
| |
| 区别: |
| mutations ==>> 同步 |
| actions =>> 返回的诗一个Promise对象,他可以执行相关异步操作 |
| |
| mutations是来修改state的值的,actions的作用是来提交mutations |
复制
3.5VueX持久化存储
| vuex本身不是持久化存储的数据,vuex是一个状态管理仓库 |
| (state:全局属性)==>>就是存放全局属性的地方 |
复制
| 实现持久化存储: |
| |
| 1.自己写localStorage, |
| 2.使用vuex-persistedstate插件(下方插件使用方式) |
| |
| 下载安装插件进行持久化存储 |
| npm install vuex-persistedstate --save |
| |
| 配置 |
| import createPersistedState from 'vuex-persistedstate'; |
| vue.use(Vuex) |
| |
| // vuex数据持久化配置 |
| plugins:[ |
| createPersistedState({ |
| storage:window.sessionStorage, |
| key:"store", |
| render(state){ |
| return {...state} |
| } |
| }) |
| ] |
复制
四.关于路由
4.1路由的模式和区别
复制
| 区别: |
| 1.关于找不到页面当前页面发送请求的问题 |
| history会给后端发送一次请求 |
| hash不会给后端发送请求 |
| |
| 2.关于项目打包前端自测问题 |
| hash 是可以看到内容的 |
| history 默认情况下是看不到内容的 |
| |
| 3.关于表象不同 |
| hash: # |
| history: / |
复制
4.2.子路由和动态路由
4.3路由传值
| 一.vue路由传值有4种方式 |
| |
| 接收方式 |
| mounted () { |
| this.num = this.$route.params.num |
| } |
| |
| |
| 1.利用router-link路由导航来传递 |
| <router-link to = "/跳转路径/传入的参数"></router-link> |
| |
| |
| 2.调用$router.push实现路由传值 (通过事件触发) |
| deliverParams (id) { |
| this.$router.push({path: `/d/${id}` |
| }) |
| 路由配置:{path: '/d/:id', name: D, component: D} |
| http://localhost:8080/#/d/123 |
| |
| |
| 3.通过路由属性中的name来匹配路由,再根据params传递参数值 |
| this.$router.push({ |
| name: 'B', |
| params: {sometext: '熊出没'} |
| }) |
| 路由配置:{path: '/b', name: 'B', component: B} |
| http://localhost:8080/#/b |
| |
| |
| 4.通过query来传递参数 |
| this.$router.push({ |
| path: '/c', |
| query: {sometext: '我是光头强'} |
| }) |
| 路由配置:{path: '/c', name: 'C', component: C} |
| http://localhost:8080/#/c?sometext=这是小? |
复制
4.4导航故障
官网说明
等待导航结果 | Vue RouterVue.js 的官方路由
https://router.vuejs.org/zh/guide/advanced/navigation-failures.html
| 解决方法: |
| 在跳转的后面加 .catch(error=>error) |
复制
4.5$router和$route的区别
CSDN详细使用介绍https://blog.csdn.net/qq_45838276/article/details/126890883?ops_request_misc=%7B%22request%5Fid%22%3A%22172371411616800225554504%22%2C%22scm%22%3A%2220140713.130102334..%22%7D&request_id=172371411616800225554504&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-1-126890883-null-null.142^v100^control&utm_term=$router和$route的区别&spm=1018.2226.3001.4187
https://blog.csdn.net/qq_45838276/article/details/126890883?ops_request_misc=%7B%22request%5Fid%22%3A%22172371411616800225554504%22%2C%22scm%22%3A%2220140713.130102334..%22%7D&request_id=172371411616800225554504&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-1-126890883-null-null.142^v100^control&utm_term=$router和$route的区别&spm=1018.2226.3001.4187
| 1、$router是用来操作路由,不仅包含路由还包含整个路由的属性和方法 |
| $route是用来获取路由信息,包含当前路由 |
| |
| |
| 2. $router是VueRouter的一个实例,他包含了所有的路由,包括路由的跳转方法, |
| 钩子函数等,也包含一些子对象(例如history) |
| |
| 3.route是一个跳转的路由对象(路由信息对象),每一个路由都会有一个$route对象,是一个局部的对象。 |
复制
4.6.导航守卫
| 1.全局守卫 |
| beforeEach 路由进入之前 |
| afterEach 路由进入之后 |
| |
| 2.路由独享守卫 |
| beforEnter 路由进入之前 |
| |
| 3.组件内守卫 |
| beforeRouteEnter 路由进入之前 |
| beforeRouteUpdate 路由更新之前 |
| beforeRouteleave 路由离开之前 |
复制
五.关于API
5.1$set
| 碰到数据更新,视图没有更新的问题==>>$set |
| |
| $set('需要修改的参数','第几个','修改成什么') |
| this.$set(target,key,'修改后的值') |
复制
5.2$nextTick
| 在vue的生命周期中,beforeCreate或created中如何去获取dom |
| |
| 1.使用异步获取去,定时器 |
| |
| 2.使用vue中自带的API$nextTick |
| $nextTick返回的参数(函数),是一个异步 |
| |
| 源码|原理 |
| $nextTick(callback){ |
| return Promise.resolve().then(()=>{ |
| callback(); |
| }) |
| } |
复制
5.3$refs
| 1.this.$refs 获取dome的 |
| 使用 |
| <子组件 ref='命名'></子组件> |
| this.$refs.命名 获取到子组件信息 |
复制
5.4 $el
复制
5.5$data
复制
5.6$children
| $children 获取当前组件的说有子组件的,返回的是一个数组 |
复制
5.7 $parent
| $parent 找到当前组件的父组件,如果找不到返回自身 |
复制
5.8 $root
复制
5.9data定义数据
| 在data中定义数据, 在return里面和在return外面定义数据的区别 |
| |
| 1.return外: 单纯修改数据是不可以被修改的,因为没有get/set |
| 2.return内: 是可以修改的 |
复制
5.10 computed计算属性
| computed的计算属性的结果值,可以修改吗? |
| |
| 可以的,需要通过get/set写法 |
| |
| 当前组件v-model绑定的值是computed来的,那么可以修改吗?可以的,需要通过get/set写法 |
| |
复制
5.11 watch
| 深入监听 |
| hello: { |
| handler(newval, oldval) { |
| console.log(newval, oldval); |
| }, |
| immediate:true //立即侦听 |
| } |
| |
| hello(newhello,oldhello){ |
| console.log(newhello,oldhello); |
| } |
| |
| 还可以监听路由/路径变化 |
复制
5.12 methods和computed区别
| conputed是有缓存机制的,methods是没有缓存机制的 |
复制
6.关于指令
6.1如何自定义指令
| 全局 main.js |
| |
| Vue.directive('demo',( |
| insetted:function(a,b,c){ |
| console.log(a,b,c) |
| } |
| )) |
| |
| 局部:某一个组件内 |
| export default( |
| directives:{ |
| demo:{ |
| bind:function(el){ |
| console.log(1) |
| } |
| } |
| } |
| ) |
复制
6.2vue单项绑定
| 双向绑定 v-model |
| |
| 单项绑定: v-bind |
复制
6.3v-if和v-for优先级
| vue2 中 v-for > v-if |
| vue3 中 v-if > v-for |
复制
七.关于原理
7.1.$nextTick原理
| $nextTick 获取更新后的dome的 |
| |
| 原理 |
| $nextTick(callback){ |
| return Promise.resolve().then(()=>{ |
| callback(); |
| }) |
| } |
复制
7.2.双向绑定原理
| 1.Object.defineProperty(obj, prop, descriptor) ,这个语法内有三个参数, |
| 分别为 obj (要定义其上属性的对象); prop (要定义或修改的属性); descriptor (具体的改变方法) |
| 2、简单地说,就是用这个方法来定义一个值。当调用时我们使用了它里面的get方法。 |
| 当给这个属性赋值时,就调用了它里面的set方法; |
| |
| var obj = {} |
| Object.defineProperty(obj,'prototypeName',{ |
| get: function() { |
| console.log("调用了get") |
| }, |
| set: function(newValue) { |
| console.log("调用了set,新值是"+newValue) |
| } |
| }) |
| |
| obj.prototypeName |
| obj.prototypeName = 'hello' |
| |
复制
一.Vue框架篇
vue2.x生命周期
| 1.有哪些生命周期 |
| 系统自带 |
| beforeCreate |
| created |
| beforeMount |
| mounted |
| beforeUpdate |
| updated |
| beforeDestroy //销毁 |
| destroyed |
| |
| 2.一旦进入到页面或组件,会执行哪些生命周期,顺序 |
| beforeCreate |
| created |
| beforeMount |
| mounted |
| |
| 3.在哪个阶段有$el(这个组件的根节点),在哪个阶段有$data(data中return数据) |
| beforeCreate |
| created $data |
| beforeMount $data |
| mounted $el $data |
| |
| 4.如果加入了keep-alive会多两个生命周期 |
| activated , deactivated |
| |
| 5.如果加入了keep-alive第一次或第二次进入会执行哪些生命周期 |
| 第一次进入执行5个生命周期 |
| beforeCreate |
| created |
| beforeMount |
| mounted |
| activated |
| 第二次进入执行1个生命周期 |
| activated |
复制
谈谈你对keep-alive的了解
| 1.是什么 |
| vue系统自带的一个组件,功能:是来缓存组件的. >>提升性能 |
| |
| 2.使用场景 |
| 就是来缓存组件的,提升项目的性能,具体实现比如,首页进入到详情页,如果用户在首页每次点击都是相同的, |
| 直接缓存就可以了,当然如果点击的不是同一个,那么直接请求 |
复制
v-if和v-show区别
| 1.展示形式不同 |
| v-if是 创建一个dome节点 |
| v-show 是把dome节点隐藏起来, display:none block |
| |
| 2.使用场景 |
| 初次加载v-if要比v-show好,页不会做加载盒子 |
| 频繁切换, v-show要比v-if好,创建和删除开销太大, 隐藏起来比较好 |
| |
复制
ref是什么
复制
nextTick是什么
复制
scoped原理
复制
vue组件之间如何传值
| 1.父组件 传值 子组件 |
| 2.子组件 传值 父组件 |
| 3.兄弟组件之间传值 |
| 使用bus 建立一个中转js, |
| 引入bus.js文件 |
| |
| 使用bus.$emit('自定义事件',传值) |
| 兄弟组件使用bus.$on('自定义事件',data=>{ |
| |
| })接收 |
复制
computed , methods , watch有什么区别
| 1.computed vs methods有什么区别 |
| computed在dome中使用连续调用只执行一次,有缓存 |
| methods在dome中连续调用,会执行多次,没有缓存 |
| |
| |
| 1.computed vs watch有什么区别 |
| watch是监听,数据或者是路由发生了改变才可以响应(执行) |
| computed计算某一个属性的改变,如果某一个值改变了,计算属性监听到了就会返回 |
复制
23.vue2和vue3的区别