33.谈谈Vuex,每个属性,如何使用
-
Vuex是集中式管理项目公共数据的,有action、mutations、state、getters、module属性。
-
state属性用来存储公共管理的数据,mutations属性定义改变state中数据的方法,action属性类似于mutation,但action提交的mutation,不是直接变更状态。getter属性相当于store中数据的计算属性,module属性是将store分割成模块,每个模块都包括自己的action、mutations、state、getter,甚至嵌套子模块
不要在mutations中的方法中写异步方法ajax,会造成数据不可跟踪
action中的方法可以书写任意的异步操作
-
使用方法:
- state:直接以对象方式添加属性
- mutations:通过store.commit方法调用其中的方法
- action:通过store.dispatch方法调用其中的方法
- getters:直接通过store.getters.计算属性获取
- mapState、mapMutations、mapAction、mapGetters四个方法可以一次性获取多个属性,或一次性调用对应属性下多个方法
-
适用场景:在大型项目中比较常用,非关系组件传递数据比较方便
34.Vue2的双向绑定的原理和缺陷
-
原理:Vue2采用数据劫持+发布者-订阅者模式的方式实现数据的响应式,通过Object.defineProperty来劫持数据的setter、getter,在数据变动时发布信息给订阅者,订阅者收到信息后进行相应的处理
-
缺陷:
-
不能响应对象的动态新增属性,需要使用Vue.set()新增属性才能响应
-
不能响应通过下标改变数组的对应数据,需要使用数组中的push等方法操作的数据才能响应
-
35.Vue中$nextTick的作用与原理
- 明确:Vue在更新DOM时是异步执行的,在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。所以修改完数据,立即再方法中获取DOM,获取的仍是未修改的DOM
- 作用:该方法中的代码会在当前DOM渲染完成后执行,这样就解决了异步渲染获取不到更新后的DOM的问题了
- 原理:本质是返回一个Promise
36.HashRouter和HistoryRouter的区别和原理
-
区别:
- history和hash都是利用浏览器的两种特性实现路由,history是利用浏览记录栈的API实现,hash是监听location对象的hash值变化事件来实现
- history的url没有’#‘号,hash有
- 相同的url,history会触发添加到浏览器历史记录栈中,hash则不会,history需要后端配合,如果后端不配合刷新页面会出现404,hash则不需要
-
原理:
-
HistoryRouter的原理:通过history.pushState做页面跳转不会触发页面刷新,使用window.onpopstate监听浏览器的前进和后退,再做其他处理
-
HashRouter的原理:通过window.onhashchange方法获取新的url中的hash值,再做进一步处理
-
-
适用场景:
- 需要url更优雅美观时,可以使用history模式
- 需要添加任意类型数据到记录时,可以使用history模式
- 需要兼容低版本的浏览器时,可以使用hash模式
36. v-if和v-show的区别
-
都是控制元素显示和隐藏的指令
-
区别:
- v-show:控制的元素无论是true还是false,都被渲染出来了,通过display:none控制元素隐藏
- v-if:控制的元素时true,则进行渲染,若时false,则不渲染,在dom树结构中不显示
-
适用场景:
-
v-show:元素切换显示/隐藏频繁时
-
v-if:元素切换显示/隐藏不频繁,元素内容很多,渲染一次性能消耗很大的元素上
-
37.Vue中的keep-alive
-
作用:缓存组件,提升性能,避免重复加载一些经常变动且内容较多的组件
-
使用方法:使用
<keep-alive>
标签对需要缓存的组件进行包裹,默认情况下被包裹的组件都会进行缓存 -
区分被包裹的组件是否缓存的两种方法:
-
给keepalive添加属性,组件名称指的是具体组件添加的name,不是路由里面的name。include包含的组件(可以为字符串、数组、正则表达式,只有匹配的组件会被缓存),exclude排除的组件(可以是字符串、数组、正则表达式,任何匹配的组件都不会被缓存)
注: 只能用在只有一个子组件的情况,否则不生效
<keep-alive include="home"> <router-view /> </keep-alive>
-
和路由配合(常用):在路由中添加meta属性
export default[ { path:'/', name:'home', components:Home, meta:{ keepAlive:true //需要被缓存的组件 }, { path:'/book', name:'book', components:Book, meta:{ keepAlive:false //不需要被缓存的组件 } ]
-
-
使用keepalive导致组件不重新加载,也就不会重新执行生命周期的函数,那么怎么获取数据。解决办法:组件钩子函数:进入时触发:activated;退出时触发:deactivated
-
适用场景:首页展示固定数据的组件
38. Vue列表为什么加key
-
为了优化性能。因为vue使用虚拟DOM,更新DOM时用diff算法对新旧Vnode进行一一比较,比如有很多li元素,要在某个位置插入一个li元素,但没有给li加key,那么在进行插入的时候,就会将所有的li元素重新渲染一遍,如果有key的话,那么就会根据key进行新旧Vnode一一比对,只要创建新的li元素,插入即可,不需要对其他元素进行修改和重新渲染
-
注:key的选择不能是index,当对数据进行逆序添加、逆序删除等破坏操作时,会产生没有必要的真是DOM更新,此时也没有达到性能优化的效果
39. vue-router实现懒加载的方法
-
ES6新增的import方法:
// 下面2行代码,没有指定webpackChunkName,每个组件打包成一个js文件。 /* const Home = () => import('@/components/home') const Index = () => import('@/components/index') const About = () => import('@/components/about') */ // 下面2行代码,指定了相同的webpackChunkName,会合并打包成一个js文件。 把组件按组分块 const Home = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/home') const Index = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/index') const About = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/about')
-
vue中的异步组件懒加载方式:
/* vue异步组件技术 */ { path: '/home', name: 'home', component: resolve => require(['@/components/home'],resolve) },{ path: '/index', name: 'Index', component: resolve => require(['@/components/index'],resolve) },{ path: '/about', name: 'about', component: resolve => require(['@/components/about'],resolve) }
-
webpack提供的require.ensure
/* 组件懒加载方案三: webpack提供的require.ensure() */ /*多个路由指定相同的chunkName,会合并打包成一个js文件*/ { path: '/home', name: 'home', component: r => require.ensure([], () => r(require('@/components/home')), 'demo') }, { path: '/index', name: 'Index', component: r => require.ensure([], () => r(require('@/components/index')), 'demo') }, { path: '/about', name: 'about', component: r => require.ensure([], () => r(require('@/components/about')), 'demo-01') }
40.float浮动
- 浮动的作用:设置了浮动的块级元素可以排列在同一行,设置了浮动的行内元素可以设置宽高,同时可以按照浮动设置的方向对齐排列盒子,可以设置浮动的照片,可以实现文字环绕图片效果
- 浮动元素的特点:设置了浮动的元素不占位置,即脱标,拥有行内块元素的特性
- 浮动造成的影响:使盒子脱离文档流,如果父盒子没有设置高度,需要被子盒子撑开,这时父盒子的高度会塌陷,同时父盒子后面的兄弟盒子布局受到影响。如果浮动元素后面还有其他兄弟元素,其他兄弟元素的布局也会受到影响
- 清除浮动的方法:
- 额外标签法(隔墙法):给最后一个浮动盒子后面加一个块级标签,同时设置它的样式为clear:both
- 给父元素添加overflow属性:hidden(常用)、auto或scroll
- 给父元素添加::after伪元素法
- 给父元素添加::before、::after双伪元素法
41.HTML语义化
- html语义化指在使用html标签构建页面时,避免大篇幅的使用无语义的标签,比如‘div’,尽可能的使用具有语义的标签,比如header、footer、aside、main、h1-h6、input、textarea、video、aduio等
- 作用:
- 易于用户阅读,样式文件未加载时,页面结构清晰
- 有利于SEO,搜索引擎根据标签来确定上下文和各个关键字的权重
- 方便屏幕阅读器解析,如盲人阅读器根据语义渲染网页
- 有利于开发和维护,代码更具可读性,代码更好维护
注:html5语义化标签并没有广泛使用,例如京东、淘宝等,还是使用div元素,设置id是header或者footer,可能是因为html5新增的语义化标签作用不是特别大,网站没有必要重写
42. 样式优先级的规则
- !important:无论引入方式是什么选择器是什么,它的优先级始终是最高的
- 引入方式:行内样式>嵌入、外链,嵌入和外链如果使用的选择器相同看他们在页面中插入的顺序,后面插入的会覆盖前面插入的
- 选择器:选择器优先级:id选择器>(类选择器、伪类选择器、属性选择器)>(元素选择器、伪元素选择器、后代选择器)>(子选择器、并集选择器)>通配符选择器
- 继承样式:所有样式中优先级比较低的
- 浏览器默认样式:优先级最低