29.vue 实例的 属性
a、vm.$el:类型(HTMLElement)挂载元素,Vue实例的DOM根元素;
b、vm.$data:类型(Object),Vue实例观察的数据对象
c、vm.$props:类型(Object)
d、vm. o p t i o n s : 类 型 ( O b j e c t ) , 用 于 当 前 V u e 实 例 的 初 始 化 选 项 , 在 选 项 中 需 要 包 含 自 定 义 属 性 的 时 候 很 有 用 。 v m . options:类型(Object),用于当前Vue实例的初始化选项,在选项中需要包含自定义属性的时候很有用。vm. options:类型(Object),用于当前Vue实例的初始化选项,在选项中需要包含自定义属性的时候很有用。vm.options 读取实例中所有自定义属性
e、vm.$parent:类型(Vue实例),父实例。
f、vm.$root:类型(Vue实例),当前组件树的根Vue实例,如果没有父实例,就是实例本身。
h、vm.$children:类型(Array(Vue实例)),当前实例的直接子组件
需要注意 $children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 $children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源。
i、vm. s l o t s : 类 型 ( [ n a m e : s t r i n g ] : ? A r r a y < V N o d e > ) , 用 来 访 问 被 s l o t 分 发 的 内 容 。 每 个 具 名 s l o t 有 其 相 应 的 属 性 ( 例 如 : s l o t = " f o o " 中 的 内 容 将 会 在 v m . slots:类型({ [name: string]: ?Array<VNode> }),用来访问被 slot 分发的内容。每个具名 slot 有其相应的属性(例如:slot="foo" 中的内容将会在 vm. slots:类型([name:string]:?Array<VNode>),用来访问被slot分发的内容。每个具名slot有其相应的属性(例如:slot="foo"中的内容将会在vm.slots.foo 中被找到)。default 属性包括了所有没有被包含在具名 slot 中的节点。
j、vm.$scopedSlots:;
k、vm.$refs:类型(Object),一个对象,其中包含了所有拥有 ref 注册的子组件;
l、vm.$isServer:类型(boolean),当前Vue实例是否运行于服务器;
30. vue 指令 分别说明什么意思
v-if指令:v-if是条件渲染指令,它根据表达式的真假来删除和插入元素
v-show指令:v-show和v-if区别=>v-show不管条件是否成立,都会渲染html,而v-if只有条件成立才会渲染
v-else指令:v-else指令与v-if或者v-show同时使用,v-if条件不成立则会显示v-else内容
v-for指令:v-for指令基于一个数组渲染一个列表,它和JavaScript的遍历语法相似,v-for=“item in list”,list是一个数组,item是当前遍历的数组元素=>v-for=”(item,index) in list"其中index是当前循环的索引,下标从0开始
·注意:处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 )上。
v-bind指令(简写“:”):v-bind动态地绑定一个或多个特性,可以在其名称后面带一个参数,中间放一个冒号隔开,这个参数通常是HTML元素的特性(attribute),如v-bind: class,class可以和v-bind:class同时存在 ,也就是说有class了,再添加v-bind:class并不会覆盖原来的样式类,而是在原来基础上添加新的类名
v-on指令(简写“@”):v-on用于监听DOM事件,用法和v-bind类似,例如给button添加点击事件<button v-on:click="show”>也可用@符号代替,修改代码:<button @click=“show”>
31.说一下vue 如何实现数据双向绑定 底层原理
双向绑定原理
vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。
我们已经知道实现数据的双向绑定,首先要对数据进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。如果属性发生变化了,就需要告诉订阅者Watcher看是否需要更新。因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的。接着,我们还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析,将相关指令(如v-model,v-on)对应初始化成一个订阅者Watcher,并替换模板数据或者绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,就会执行对应的更新函数,从而更新视图。因此接下去我们执行以下3个步骤,实现数据的双向绑定:
1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。
2.实现一个订阅者Watcher,每一个Watcher都绑定一个更新函数,watcher可以收到属性的变化通知并执行相应的函数,从而更新视图。
3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令(v-model,v-on等指令),如果节点存在v-model,v-on等指令,则解析器Compile初始化这类节点的模板数据,使之可以显示在视图上,然后初始化相应的订阅者(Watcher)。
32. vue 属性 methods computed watch 这三个属性的区别
methods(方法):
只要进行调用就会执行,不管依赖的值有没有改变。无缓存。
computed(计算属性):
监听其所有依赖的变化,如果有变化会执行,没有变化不执行。有缓存,不用每次重新算。不支持异步。
详解=》在vue的 模板内({{}})是可以写一些简单的js表达式的 ,很便利。但是如果在页面中使用大量或是复杂的表达式去处理数据,对页面的维护会有很大的影响。这个时候就需要用到computed 计算属性来处理复杂的逻辑运算。
1.优点:
在数据未发生变化时,优先读取缓存。computed 计算属性只有在相关的数据发生变化时才会改变要计算的属性,当相关数据没有变化是,它会读取缓存。而不必想 motheds方法 和 watch 方法是否每次都去执行函数。
2.setter 和 getter方法:(注意在vue中书写时用set 和 get)
setter 方法在设置值是触发。
getter 方法在获取值时触发。
watch(侦听属性):
观察某一个变量,发生变化会执行。支持异步。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。
一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。
小结:
1.主动调用的方法写在methods里,依据某些变量的更新进行某种操作用computed或者watch。
2.computed和watch:如果要异步,只能用watch。如果是计算某个值推荐用computed,比如购物车全选单选功能,购物车计算总价小计功能。
33.说一下 什么 变异数组和非变异数组 以及 可变对象 和 不可变对象
变异数组的方法
- 变异数组方法 触发vue 视图更新 改变原数组
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
join()
- 非变异数组方法 不会改变原数组 无法触发Vue视图更新 返回新的数组
filter()
concat()
slice()
find()
- 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
- 当你修改数组的长度时,例如:vm.items.length = newLength
可变对象:把对象a赋值给对象b,更改对象b的属性值,被引用的对象a也随之改变。
不可变对象:对象可能会被其他拥有同样引用地址的对象同步改变,如深拷贝。
.但是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:
对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套对象添加响应式属性。
你可以添加一个新的 age 属性到嵌套的 userProfile 对象:
Vue.set(vm.userProfile, 'age', 27)
有时你可能需要为已有对象赋予多个新属性,比如使用 Object.assign() 或 _.extend()。在这种情况下,你应该用两个对象的属性创建一个新的对象。所以,如果你想添加新的响应式属性,
vm.userProfile = Object.assign({}, vm.userProfile, { age: 27, favoriteColor: 'Vue Green'})
34.vue 如何实现 深度监听 以及什么时候需要用到深度监听
深度监听需要用到的情况:
watch:{} 可监听数据,数据发生变化, 处理函数,watch虽可监听,但只是浅监听,只监听数据第一层或者第二层,例如对象里面套对象data: {obj: {a: 123} }
深度监听使用方法:
重点:handler方法,deep属性,immediate属性
watch: {
obj : {
handler:function() { //特别注意,不能用箭头函数,箭头函数,this指向全局,处理函数
},
deep: true //深度监听
}
}
handler方法,之前我们写的 watch 方法其实默认写的就是这个handler,Vue.js会去处理这个逻辑,最终编译出来其实就是这个handler。
deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。
优化:直接监听到对象中的属性
watch: {
'obj.a': {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
// deep: true
}
}
immediate:true代表如果在 wacth 里声明了需要做监听的数据之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行。
35. vue 组件生命周期 分为几个阶段 有哪些生命周期钩子函数
https://blog.csdn.net/HarryHY/article/details/99311838
36. vue 如何绑定事件 绑定变量 绑定属性
事件绑定:v-on @
属性绑定 v-bind :
变量:双大括号
<h1>{{ greet("night") }}</h1>
<p>{{ message }}</p>
<a v-bind:href="website">百度</a>
<button v-on:click="add(1)">单击加一岁</button>
<button @click="sub(1)">单击减一岁</button>
37.vue slot 具体用法 你项目怎么使用slot
slot用于封装组件中,写在子组件 接收父组件动态传递子组件内容片断
slot插槽的使用方法其实就是类似于一个子组件或者标签的引用的过程,在父组件里面定义一个slot,给她起个name,然后组件引入到子组件,子组件里面有个元素的属性slot值等于name,然后父组件里面没有值的时候就可以显示子组件里面的信息了(切记:插槽slot要写在父组件里面!!!)
vue slot用法1:
slot主要是让组件的可扩展性更强
1.匿名slot使用
//定义组件
<div class="Component>
<slot></slot>
</div>
//使用方法
<component>
<p>slot内容,可以放任何标签</p>
</component>
2.具名slot使用
//定义组件
<div class="Component>
<slot name="Slot"></slot>
</div>
//使用方法
<component>
<p slot="Slot>可以放任何标签,但必须加上slot="Slot",不然会报错</p>
</component>
如果不在slot里加入任何标签,slot什么都不会显示。
38.vue 如何动态切换组件 说出所有的具体实现方法 保存数据 缓存组件模块 keep-alive
通过 Vue 的 <component> 元素加一个特殊的 is 特性来实现。currentComponent 可以包括
* 已注册组件的名字
* 一个组件的选项对象
<div id="app">
<select v-model="currentCpt">
<option value="table-cpt">表格</option>
<option value="list-cpt">列表</option>
</select>
<!-- 失活的组件将会被缓存!-->
<keep-alive>
<component :is="currentCpt" :cars="cars"></component>
</keep-alive>
</div>
V-if v-show 路由切换…...
39.data 和 vm. d a t a w a t c h 和 v m . data watch 和 vm. datawatch和vm.watch 的 区别 以及如何校验 props
带有 $ 符号vm.$data ,读取实例属性对象:(包含多个键值对)
vm.$ 读取实例中属性列表(第一层)
vm.data 直接读取实例 data 数据属性中的数据值(第二层)。等价于 vm.$data.data
40.vue如何自定义指令 如何自定义过滤器 自定义指令意义和自定义过滤器的意义
自定义组件创建
new Vue({
directives:{
change:{
bind:function(){},
update:function(){},
unbind:function(){}
}
}
})
过滤器创建
过滤器的本质 是一个有参数 有返回值的方法
new Vue({
filters:{
myCurrency:function(myInput){
return 处理后的数据
}
}
})
自定义指令是用来操作DOM的。尽管Vue推崇数据驱动视图的理念,但并非所有情况都适合数据驱动。自定义指令就是一种有效的补充和扩展,不仅可用于定义任何的DOM操作,并且是可复用的。
过滤器的作用:实现数据的筛选、过滤、格式化。
41.vue定义创建路由的步骤
0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
1. 定义 (路由) 组件。 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数
const router = new VueRouter({
routes // (缩写) 相当于 routes: routes
})
4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
router
}).$mount('#app')
5.<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
// 现在,应用已经启动了!
42.vue如何定义嵌套路由 以及vue 路由如何去#号 ,还有vue.use (VueRouter) 中Vue.use 作用
嵌套路由就是在router中在使用router,首先需要在父路由中写children属性,并且父路由中一定要用router-view来接收子路由模板
vue路由去#号,需要在router实例中添加 mode: ‘history’
Vue.use的作用:全局声明使用插件的方法
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
children: [
{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的 <router-view> 中
path: 'profile',
component: UserProfile
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 会被渲染在 User 的 <router-view> 中
path: 'posts',
component: UserPosts
}
]
}
]
})
43.vue 父组件 去访问 通信 作用 子组件 方式有哪些 ?
1、ref 加在子组件上,用this.ref.name 获取到的是组件实例,可以使用组件的所有方法。
2.父组件通过 props 向下传递数据给子组件,子组件在props中创建一个属性,用以接收父组件传过来的值
3 空的vue实例
4 vuex
44.vue子组件 去通信 父组件的方式有哪些?
1.通过this.
e
m
i
t
(
)
来
触
发
父
组
件
的
方
法
。
具
体
就
是
子
组
件
触
发
emit()来触发父组件的方法。具体就是子组件触发
emit()来触发父组件的方法。具体就是子组件触发emit绑定的事件watchChild,然后父组件监听watchChild,一旦watchChild被触发便会触发父组件的parentReceive方法.
2.在子组件props中定义属性onOK,类型为function,然后在父组件中把要触发的方法名传递给onOK属性,最后在子组件中判断onOk是否存在,是的话直接执行这个方法。
3.this.$parent方法
45.vue如何实现自定义事件
我们知道,父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,应该怎样做?那就是自定义事件!
使用 v-on 绑定自定义事件
每个 Vue 实例都实现了事件接口(Events interface),即:
使用 $on(eventName) 监听事件
使用
e
m
i
t
(
e
v
e
n
t
N
a
m
e
)
触
发
事
件
V
u
e
的
事
件
系
统
分
离
自
浏
览
器
的
E
v
e
n
t
T
a
r
g
e
t
A
P
I
。
尽
管
它
们
的
运
行
类
似
,
但
是
emit(eventName) 触发事件 Vue的事件系统分离自浏览器的EventTarget API。尽管它们的运行类似,但是
emit(eventName)触发事件Vue的事件系统分离自浏览器的EventTargetAPI。尽管它们的运行类似,但是on 和 $emit 不是addEventListener 和 dispatchEvent 的别名。
另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
46.vue数据管理架构 vuex的原理
更改vuex的store中的状态的唯一方法是提交mutation.
修改数据 可以不dispatch action 但是必须commit mutations
getters===>用来处理一些比较复杂的数据
变量全部存在计算属性中,计算属性会监听 重新刷新页面 显示动态修改
HTML页面上,负责接收用户操作等交互行为,执行dispatch方法触发对应action进行回应。
dispatch:操作行为触发方法,是唯一能执行action的方法。
actions:操作行为处理模块。负责处理Vue Components接收到的所有交互行为。包含同步/异步操作,支持多个同名方法,按照注册的顺序依次触发。向后台API请求的操作就在这个模块中进行,包括触发其他action以及提交mutation的操作。
该模块提供了Promise的封装,以支持action的链式触发。
commit:状态改变提交操作方法。对mutation进行提交,是唯一能执行mutation的方法。
mutations:状态改变操作方法。是Vuex修改state的唯一推荐方法,其他修改方式在严格模式下将会报错。该方法只能进行同步操作,且方法名只能全局唯一。操作之中会有一些hook暴露出来,以进行state的监控等。
state:页面状态管理容器对象。集中存储Vue components中data对象的零散数据,全局唯一,以进行统一的状态管理。页面显示所需的数据从该对象中进行读取,利用Vue的细粒度数据响应机制来进行高效的状态更新。
getters:state对象读取方法。图中没有单独列出该模块,应该被包含在了render中,Vue Components通过该方法读取全局state对象。Vue组件接收交互行为,调用dispatch方法触发action相关处理,若页面状态需要改变,则调用commit方法提交mutation修改state,通过getters获取到state新值,重新渲染Vue Components,界面随之更新。
47.vuex 里面 四个 辅助 函数 ( )
mapState 3种用法 :
1 对象 如果使用箭头函数,当vuex的state和当前组件的state,含有相同的变量名称时,
this获取的是vuex中的变量,而不是局部变量
2 数组 当映射的计算属性的名称与state的子节点名称相同时,我们也可以给mapState传一个字符串数组。
3 对象展开运算符 mapState函数返回的是一个对象。如果需要将它与局部计算属性混合使用,
通常我们需要一个工具函数将多个对象合并为一个,以使我们可以将最终对象传给computed属性。
mapGetter mapGetters将store中的getter映射到局部计算属性
mapMutation 使用mapMutations辅助函数将组件中的methods映射为store.commit调用。
mapAction 使用mapActions辅助函数将组件的methods映射成store.dispatch调用
简记:
mapState 映射 this.$store.state.xxx
mapActions this.$store.dispatch(action)
mapGetters this.$store.getters.xxxx ==> 进一步处理 state
mapMutations this.$store.commit(mutattion)
48.vue路由 里面路由守卫 哪三种路由守卫?什么作用
监听路由切换 各写以一个路由守卫函数
1全局守卫 ① 全局
router.beforeEach((to, from, next) => {})
② 后置
router.afterEach((to, from) => {})
③ 全局解析守卫
router.beforeResolve((to, from, next) => {})
2组件内守卫
router.beforeRouteEnter((to, from, next) => {})
router.beforeRouteUpdate((to, from, next) => {})
router.beforeRouteLeave((to, from, next) => {})
3路由独享守卫
router.beforeEnter((to, from, next) => {})
作用 :对每一次页面的跳转或刷新进行判断
49.比较说明 vue 设计模式 MVC MVVM MVP 三种设计模式 的理解
MVC是Model-View-Controller的缩写,它将应用程序划分为三个部分:
Model: 模型(用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法)
View: 视图(渲染页面)
Controller: 控制器(M和V之间的连接器,用于控制应用程序的流程,及页面的业务逻辑
MVC特点:
MVC模式的特点在于实现关注点分离,即应用程序中的数据模型与业务和展示逻辑解耦。在客户端web开发中,就是将模型(M-数据、操作数据)、视图(V-显示数据的HTML元素)之间实现代码分离,松散耦合,使之成为一个更容易开发、维护和测试的客户端应用程序。
View 传送指令到 Controller ;
Controller 完成业务逻辑后,要求 Model 改变状态 ;
Model 将新的数据发送到 View,用户得到反馈。
MVC优点:
耦合性低,视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码。
重用性高
生命周期成本低
MVC使开发和维护用户接口的技术含量降低
可维护性高,分离视图层和业务逻辑层也使得WEB应用更易于维护和修改
部署快
MVC缺点:
不适合小型,中等规模的应用程序,花费大量时间将MVC应用到规模并不是很大的应用程序通常会得不偿失。
视图与控制器间过于紧密连接,视图与控制器是相互分离,但却是联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。
视图对模型数据的低效率访问,依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。
MVP(Model-View-Presenter)是MVC的改良模式,由IBM的子公司Taligent提出。和MVC的相同之处在于:Controller/Presenter负责业务逻辑,Model管理数据,View负责显示只不过是将 Controller 改名为 Presenter,同时改变了通信方向。
MVP特点:
M、V、P之间双向通信。
View 与 Model 不通信,都通过 Presenter 传递。Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现。
View 非常薄,不部署任何业务逻辑,称为”被动视图”(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。
Presenter与具体的View是没有直接关联的,而是通过定义好的接口进行交互,从而使得在变更View时候可以保持Presenter的不变,这样就可以重用。不仅如此,还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试–从而不需要使用自动化的测试工具。
在MVP中,View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部
在MVC中,View会直接从Model中读取数据而不是通过 Controller。
MVP优点:
模型与视图完全分离,我们可以修改视图而不影响模型;
可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部;
我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁;
如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)。
MVP缺点:
视图和Presenter的交互会过于频繁,使得他们的联系过于紧密。也就是说,一旦视图变更了,presenter也要变更。
MVVM
MVVM是Model-View-ViewModel的简写。微软的WPF(Windows Presentation Foundation–微软推出的基于Windows 的用户界面框架)带来了新的技术体验, 使得软件UI层更加细节化、可定制化。与此同时,在技术层面,WPF也带来了 诸如Binding(绑定)、Dependency Property(依赖属性)、Routed Events(路由事件)、Command(命令)、DataTemplate(数据模板)、ControlTemplate(控制模板)等新特性。MVVM模式其实是MV模式与WPF结合的应用方式时发展演变过来的一种新型架构模式。它立足于原有MVP框架并且把WPF的新特性糅合进去,以应对客户日益复杂的需求变化。
MVVM优点:
MVVM模式和MVC模式类似,主要目的是分离视图(View)和模型(Model),有几大优点:
1 低耦合,视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的”View”上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
2 可重用性,可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
3 独立开发,开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xml代码。
4 可测试,界面向来是比较难于测试的,而现在测试可以针对ViewModel来写。
50.你选vue框架的出发点是什么?vue开发中遇到过哪些棘手的问题?
vue的优势:
1.是一个轻巧、高性能、可组件化的MVVM库,同时拥有非常容易上手的API
2.响应式编程、组件化
3.轻量级框架、简单易学、双向数据绑定、组件化、视图、数据和结构的分离、虚拟DOM、运行速度快
遇到的坑:
- 路由变化页面数据不刷新问题
出现这种情况是因为依赖路由的params参数获取写在created生命周期里面,因为相同路由二次甚至多次加载的关系 没有达到监听,退出页面再进入另一个文章页面并不会运行created组件生命周期,导致文章数据还是第一次进入的数据解决方法:watch监听路由是否变化
watch: {
// 方法1
'$route' (to, from) { //监听路由是否变化
if(this.$route.params.articleId){// 判断条件1 判断传递值的变化
//获取文章数据
}
}
//方法2
'$route'(to, from) {
if (to.path == "/page") { /// 判断条件2 监听路由名 监听你从什么路由跳转过来的
this.message = this.$route.query.msg
}
}
}
- 异步回调函数中使用this无法指向vue实例对象
//setTimeout/setInterval ajax Promise等等
data(){
return{
...
}
},
methods (){
setTimeout(function () { //其它几种情况相同
console.log(this);//此时this指向并不是vue实例 导致操作的一些ma'f
},1000);
}
解决方案 变量赋值和箭头函数
var和let的区别
//使用变量访问this实例
let self=this;
setTimeout(function () {
console.log(self);//使用self变量访问this实例
},1000);
//箭头函数访问this实例 因为箭头函数本身没有绑定this
setTimeout(() => {
console.log(this);
}, 500);
- setInterval路由跳转继续运行并没有及时进行销毁
比如一些弹幕,走马灯文字,这类需要定时调用的,路由跳转之后,因为组件已经销毁了,但是setInterval还没有销毁,还在继续后台调用,控制台会不断报错,如果运算量大的话,无法及时清除,会导致严重的页面卡顿。
解决办法:在组件生命周期beforeDestroy停止setInterval
//组件销毁前执行的钩子函数,跟其他生命周期钩子函数的用法相同。
beforeDestroy(){
//我通常是把setInterval()定时器赋值给this实例,然后就可以像下面这么停止。
clearInterval(this.intervalId);
}
51.this.$nextTick 使用过没? 具体用于什么场景
定义:将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。(当data中的某个属性改变的时候,这个值并不是立即渲染到页面上,而是先放到watcher队列上(异步),只有当前任务空闲的时候才会去执行watcher队列上的任务。)
优点:想对未来更新后的视图进行操作,我们只需要把要执行的函数传递给this.$nextTick方法,vue就会给我们做这个工作。