vue面试知识点总结

对于Vue是一套渐进式框架的理解

在我看来,渐进式代表的含义是:主张最少。

每个框架都不可避免会有自己的一些特点,从而会对使用者有一定的要求,这些要求就是主张,主张有强有弱,它的强势程度会影响在业务开发中的使用方式。

比如说,Angular,它两个版本都是强主张的,如果你用它,必须接受以下东西:必须使用它的模块机制- 必须使用它的依赖注入- 必须使用它的特殊形式定义组件(这一点每个视图框架都有,难以避免)
所以Angular是带有比较强的排它性的,如果你的应用不是从头开始,而是要不断考虑是否跟其他东西集成,这些主张会带来一些困扰。

比如React,它也有一定程度的主张,它的主张主要是函数式编程的理念,比如说,你需要知道什么是副作用,什么是纯函数,如何隔离副作用。它的侵入性看似没有Angular那么强,主要因为它是软性侵入。

Vue可能有些方面是不如React,不如Angular,但它是渐进的,没有强主张,你可以在原有大系统的上面,把一两个组件改用它实现,当jQuery用;也可以整个用它全家桶开发,当Angular用;还可以用它的视图,搭配你自己设计的整个下层用。你可以在底层数据逻辑的地方用OO和设计模式的那套理念,也可以函数式,都可以,它只是个轻量视图而已,只做了自己该做的事,没有做不该做的事,仅此而已。

渐进式的含义,我的理解是:没有多做职责之外的事。

vue.js的两个核心是什么
  1. 数据驱动:ViewModel,保证数据和视图的一致性。
  2. 组件系统:应用类UI可以看作全部是由组件树构成的。
    具体参见:https://www.php.cn/js-tutorial-421002.html
请问 v-if 和 v-show 有什么区别
  • v-if在条件切换时,会对标签进行适当的创建和销毁,而v-show则仅在初始化时加载一次,因此v-if的开销相对来说会比v-show大。
  • v-if是惰性的,只有当条件为真时才会真正渲染标签;如果初始条件不为真,则v-if不会去渲染标签。v-show则无论初始条件是否成立,都会渲染标签,它仅仅做的只是简单的CSS切换。
vue常用的修饰符
1.事件修饰符:

.stop 阻止单机事件冒泡

.prevent 阻止默认行为(比如 @submit.prevent 会阻止提交后刷新页面)

.capture 添加事件侦听器时使用捕获模式

.self 只有事件在元素本身(而不是子元素)触发时触发回调

.once 只触发一次(组件也适用)

.key 触发事件的按键

2.v-model 修饰符:

.lazy 在输入框中,默认是在input事件中同步输入框的数据,使用lazy修饰符会转变为在change事件中同步(失去焦点或按回车才更新)。

. number将输入转换为Number类型,默认是String

.trim 自动过滤输入的首尾空格

2.v-bind 修饰符:

.once 数据只响应一次(2.x版本移除)

.sync 对一个 prop 进行“双向绑定” 子组件通过update:propName来触发更新如
this.$emit('update:title', newTitle)(这个是2.x版本用法)

v-on可以监听多个方法吗

可以

<!-- v-on在vue2.x中测试,以下两种均可-->
<input type=“text” :value=“name” @input=“onInput” @focus=“onFocus” @blur=“onBlur” />
<button v-on="{mouseenter: onEnter,mouseleave: onLeave}">鼠标进来1</button>

<!-- 一个事件绑定多个函数,按顺序执行,这里分隔函数可以用逗号也可以用分号-->
<button @click="a(),b()">点我ab</button>
vue中 key 值的作用

key值:用于 管理可复用的元素。因为Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做使 Vue 变得非常快,但是这样也不总是符合实际需求

vue事件中如何使用event对象?

1.事件绑定的函数参数为空时,函数中的第一个参数就是event对像

<button v-on:click="click()">click me</button>

methods: {
        click(event) {
            console.log(typeof event);    // object
        }
    }

2.事件绑定的函数还有其他参数时需要显式的去传入event

<button v-on:click="click($event, 111)">click me</button>

methods: {
        click(event, val) {
            console.log(typeof event);    // object
        }
    }
$nextTick的使用

Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。

$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM。

vue响应式的改变一个值以后,此时的dom并不会立即更新,如果需要在数据改变以后立即通过dom做一些操作,可以使用$nextTick获得更新后的dom。

Vue 组件中 data 为什么必须是函数

在 new Vue() 中,data 是可以作为一个对象进行操作的,然而在 component 中,data 只能以函数的形式存在,不能直接将对象赋值给它。这并非是 Vue 自身如此设计,而是跟 JavaScript 特性相关。组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果。

v-for 与 v-if 的优先级

v-for 比 v-if 的优先级高,所以永远不要把这两个放在同一个元素上

vue中子组件调用父组件的方法
1.通过$parent
this.$parent.fatherMethod('hello');
2.通过$emit
this.$emit('fatherMethod', 'hello');
3.通过props

父组件

<template>
  <div>
    <child :fatherMethod="fatherMethodOther"></child>
  </div>
</template>
<script>
  import child from './child';
  export default {
    components: {
      child
    },
    methods: {
      fatherMethodOther(str) {
        console.log(str);
      }
    }
  };
</script>

子组件

<template>
  <div>
    <button @click="childMethod">点击</button>
  </div>
</template>
<script>
  export default {
    props: {
      fatherMethod: {
        type: Function,
        default: null
      }
    },
    methods: {
      childMethod() {
        if (this.fatherMethod) {
          this.fatherMethod('hello');
        }
      }
    }
  };
</script>
vue中 keep-alive 组件的作用以及生命周期
  • 是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM;
  • 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们
  • 与 相似,只是一个抽象组件,它不会在DOM树中渲染(真实或者虚拟都不会),也不在父组件链中存在,比如:你永远在 this.$parent 中找不到 keep-alive
keep-alive生命周期钩子函数:activated、deactivated

activated:在组件被激活时调用,在组件第一次渲染时也会被调用,之后每次keep-alive激活时被调用。

deactivated:在组件被停用时调用。

注意:

  • 只有组件被 keep-alive 包裹时,这两个生命周期才会被调用,如果作为正常组件使用,是不会被调用,以及在 2.1.0 版本之后,使用 exclude 排除之后,就算被包裹在 keep-alive 中,这两个钩子依然不会被调用!另外在服务端渲染时此钩子也不会被调用的。
  • 使用了keep-alive就不会调用beforeDestroy(组件销毁前钩子)和destroyed(组件销毁),因为组件没被销毁,被缓存起来了。
vue中如何编写可复用的组件

可复用组件具有高内聚、低耦合的特性。

在 Vue 组件中,状态称为 props,事件称为 events,片段称为 slots。组件的构成部分也可以理解为组件对外的接口。良好的可复用组件应当定义一个清晰的公开接口。

  • Props 允许外部环境传递数据给组件
  • Events 允许组件触发外部环境的副作用
  • Slots 允许外部环境将额外的内容组合在组件中
    开发可复用性的组件应遵循以下原则:

1.规范化命名:组件的命名应该跟业务无关,而是依据组件的功能命名。

2.数据扁平化:定义组件接口时,尽量不要将整个对象作为一个 prop 传进来。每个 prop应该是一个简单类型的数据。
这样做有下列几点好处:
(1) 组件接口清晰。
(2) props 校验方便。
(3) 当服务端返回的对象中的 key 名称与组件接口不一样时,不需要重新构造一个对象。扁平化的 props 能让我们更直观地理解组件的接口。

3.可复用组件只实现 UI 相关的功能,即展示、交互、动画,如何获取数据跟它无关,因此不要在组件内部去获取数据。

4.可复用组件应尽量减少对外部条件的依赖。

5.组件在功能独立的前提下应该尽量简单,越简单的组件可复用性越强。

6.组件应具有一定的容错性。

什么是vue生命周期和生命周期钩子函数?

image

生命周期钩子详细
beforeCreate在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。(此时data和el均未初始化,值为undefined)
created实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。(此时data的值可以拿到,el还未初始化)
beforeMount在挂载开始之前被调用:相关的 render 函数首次被调用。(此时data和el均已经初始化,但是dom上绑定的数据{{}}没有渲染)
mountedel 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。(此时el已经渲染完成并挂载到实例上)
beforeUpdate数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
updated由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。
activatedkeep-alive 组件激活时调用。
deactivatedkeep-alive 组件停用时调用。
beforeDestroy实例销毁之前调用。在这一步,实例仍然完全可用。
destroyedVue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
父子组件生命周期执行顺序

image

Vue父子组件生命周期钩子的执行顺序遵循:从外到内,然后再从内到外,不管嵌套几层深,也遵循这个规律。

vue如何监听键盘事件中的按键

vue为几个常用按键提供了别名

<input @keyup.enter="function">
别名实际键值
.deletedelete(删除)/BackSpace(退格)
.tabTab
.enterEnter(回车)
.escEsc(退出)
.spaceSpace(空格键)
.leftLeft(左箭头)
.upUp(上箭头)
.rightRight(右箭头)
.downDown(下箭头)
.ctrlCtrl
.altAlt
.shiftShift
.meta(window系统下是window键,mac下是command键)
组合写法
组合写法按键组合
@keyup.alt.67=”function”Alt + C
@click.ctrl=”function”Ctrl + Click

注意:
如果是在自己封装的组件或者是使用一些第三方的UI库时,会发现并不起效果,这时就需要用到.native修饰符了

<el-input v-model="name" @keyup.enter.native="search()" ></el-input>
vue更新数组时触发视图更新的方法
1. Vue.set
this.$set(array, indexOfItem, newValue)
this.array.$set(indexOfItem, newValue)
2. Vue.delete
this.$delete(array, indexOfItem)
this.array.$delete(indexOfItem)
3. 数组对象直接修改属性
this.array[0].show = true;
4. splice方法修改数组
this.array.splice(indexOfItem, 1, newElement)
5.数组整体修改
let tempArray = this.array;
tempArray[0].show = true;
this.array = tempArray;
6.用Object.assign或lodash.assign可以为对象添加响应式属性
//Object.assign的单层的覆盖前面的属性,不会递归的合并属性
this.obj = Object.assign({},this.obj,{a:1, b:2})

//assign与Object.assign一样
this.obj = _.assign({},this.obj,{a:1, b:2})

//merge会递归的合并属性
this.obj = _.merge({},this.obj,{a:1, b:2})
7.Vue提供了如下的数组的变异方法
push()
pop()
shift()
unshift()
splice()  
sort()
reverse()
vue中对象更改检测的注意事项

受现代 JavaScript 的限制 (而且 Object.observe 也已经被废弃),Vue 无法检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化,所以属性必须在 data 对象上存在才能让 Vue 将它转换为响应式的。
对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性。

有时你可能需要为已有对象赋值多个新属性,比如使用 Object.assign() 或 _.extend()。但是,这样添加到对象上的新属性不会触发更新。在这种情况下,你应该用原对象与要混合进去的对象的属性一起创建一个新的对象。

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
解决非工程化项目初始化页面闪动问题

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

v-for产生的列表,实现active的切换
<ul class="nav-tab">
        <li v-for="(nav,index) in navs" @click="currentIndex = index" :class="{active: index === currentIndex}">
            <p>{{ nav.label }}</p>
        </li>
</ul>

v-model语法糖的组件中的使用

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value 特性用于不同的目的。model 选项可以用来避免这样的冲突

自定义表单组件例子

<base-checkbox v-model="lovingVue"></base-checkbox>

<!--base-checkbox组件-->
<template>
    <input
          type="checkbox"
          v-bind:checked="checked"
          v-on:change="$emit('change', $event.target.checked)"
    >
</template>
<script>

export default {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  }
}
</script>
vue等单页面应用及其优缺点
优点:
  • 用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小
  • 分离前后端关注点,前端负责界面显示,后端只负责给前端提供接口
  • 页面切换可以加上动效
缺点
  • 不利于seo
  • 导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理)
  • 初次加载时耗时多
  • 页面复杂度提高很多
如何优化SPA应用的首屏加载速度慢的问题
  • 将公用的JS库通过script标签外部引入,减小app.bundel的大小,让浏览器并行下载资源文件,提高下载速度;
  • 在配置 路由时,页面和组件使用懒加载的方式引入,进一步缩小 app.bundel 的体积,在调用某个组件时再加载对应的js文件;
  • 加一个首屏 loading 图,提升用户体验;
什么是vue的计算属性

当模板中双向绑定的表达式(这个表达式使用data里的属性计算的)很复杂,代码就会变得雕肿甚至难以阅读和维护
这时便可用计算属性代替这个表达式

所有的计算属性都以函数的形式写在 Vue 实例内的 computed 选项内,最终返回计算后的结果。

计算属性的缓存和方法调用的区别

1、我们可以将同一函数定义为一个方法或是一个计算属性。两种方式的最终结果确实是完全相同的。不同的是计算属性是基于它们的依赖进行缓存的。只在相关依赖发生改变时它们才会重新求值。相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

2、使用计算属性还是methods取决于是否需要缓存,当遍历大数组和做大量计算时,应当使用计算属性,除非你不希望得到缓存。

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

3、计算属性是根据依赖自动执行的,methods需要事件调用

vue父组件如何向子组件中传递数据
  1. 父组件通过v-bind将数据传给子组件,子组件通过props接收
  2. 父子间在provide选项中加入子组件所需要的属性,子组件中通过inject 接收所需的属性。注意: provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的
vue-router如何响应 路由参数 的变化

一般情况下从/user/foo 导航到 /user/bar,原来的组件实例会被复用,这也意味着组件的生命周期钩子不会再被调用。
如果要响应路由参数的变化可以采用以下方式:

  • watch (监测变化) $route 对象
  • 就在父组件的router-view上加个key <router-view :key="$route.fullPath"></router-view>
完整的 vue-router 导航解析流程
  1. 导航被触发
  2. 在失活的组件里调用离开守卫
  3. 调用全局的beforeEach守卫
  4. 在重用的组件里调用
  5. beforeRouterUpdate守卫
  6. 在路由配置里调用beforEnter守卫
  7. 解析异步路由组件
  8. 在被激活的组件里调用beforeRouterEnter守卫
  9. 调用全局的BeforeRouterResolve守卫
  10. 导航被确认
  11. 调用全局的afterEach守卫
  12. 触发DOM更新
  13. 用创建好的实例调用beforeRouterEnter守卫中传给next的回调函数
vue-router有哪几种导航钩子( 导航守卫 )
  • 组件实例的导航守卫:beforeRouteLeave、beforeRouteEnter、beforeRouteUpdate
  • 全局守卫:beforeEach、beforeResolve、afterEach
  • 路由配置守卫:beforeEnter
vue-router的几种实例方法以及参数传递
  • router.beforeEach
  • router.beforeResolve
  • router.afterEach
router.beforeEach((to, from, next) => {
  /* must call `next` */
})

router.beforeResolve((to, from, next) => {
  /* must call `next` */
})

router.afterEach((to, from) => {})
  • router.push
  • router.replace
  • router.go
  • router.back
  • router.forward
router.push(location, onComplete?, onAbort?)
router.replace(location, onComplete?, onAbort?)
router.go(n)
router.back()
router.forward()
vue-router的动态路由匹配以及使用

vue-router的动态路由主要是指路由params,query,hash动态改变

params: 一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params

模式匹配路径$route.params
/user/:username/user/evan{ username: 'evan' }
/user/:username/post/:post_id/user/evan/post/123{ username: 'evan', post_id: '123' }
<router-link :to="{ path: 'user', params: { userId: 123 }}">User</router-link>
router.push({ path: 'user', params: { userId: 123 }})

query:

<router-link :to="{ path: 'user', query: { userId: 123 }}">User</router-link>
router.push({ path: 'user', query: { userId: 123 }})

hash:

<router-link :to="{ path: 'user', hash: 'home'}">User</router-link>
router.push({ path: 'user', hash: 'home')
vue-router如何定义嵌套路由

1.定义子路由

 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
        }
      ]
    }
  ]

父组件:

<div id="app">
  <router-view></router-view>
</div>

子组件:

<div class="user">
      <h2>User {{ $route.params.id }}</h2>
      <router-view></router-view>
</div>
<router-link></router-link>组件及其属性

<router-link>组件支持用户在具有路由功能的应用中(点击)导航。 通过 to 属性指定目标地址,默认渲染成带有正确链接的 标签,可以通过配置 tag 属性生成别的标签.。另外,当目标路由成功激活时,链接元素自动设置一个表示激活的 CSS 类名。

<router-link> 比起写死的 <a href="...">会好一些,理由如下:

  • 无论是 HTML5 history 模式还是 hash 模式,它的表现行为一致,所以,当你要切换路由模式,或者在 IE9 降级使用 hash 模式,无须作任何变动。
  • 在 HTML5 history 模式下,router-link 会拦截点击事件,让浏览器不在重新加载页面。
  • 当你在 HTML5 history 模式下使用 base 选项之后,所有的 to 属性都不需要写(基路径)了。

属性:

  • to:表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象
<router-link :to="'home'">Home</router-link>
<router-link :to="{ path: 'home' }">Home</router-link>
<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>
  • replace:设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),于是导航后不会留下 history 记录。

  • append: 设置 append 属性后,则在当前(相对)路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b

  • tag: 有时候想要 渲染成某种标签,例如 <li>于是我们使用 tag prop类指定何种标签,同样它还是会监听点击,触发导航。

  • active-class :设置 链接激活时使用的 CSS 类名。默认值可以通过路由的构造选项 linkActiveClass 来全局配置

  • exact: 是否激活" 默认类名的依据是 inclusive match (全包含匹配)。 举个例子,如果当前的路径是 /a 开头的,那么<router-link to="/a">也会被设置 CSS 类名。按照这个规则,<router-link to="/"> 将会点亮各个路由!想要链接使用 “exact 匹配模式”,则使用 exact 属性:

  <!-- 这个链接只会在地址为 / 的时候被激活 -->

  <router-link to="/" exact>
vue-router实现路由懒加载( 动态加载路由 )

1 . vue异步组件技术 ==== 异步加载
vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 .
但是,这种情况下一个组件生成一个js文件

/* 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)
} 

2.使用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')

{
  path: '/about',
  component: About
}, {
  path: '/index',
  component: Index
}, {
  path: '/home',
  component: Home
}

3.使用webpack的require.ensure技术,也可以实现按需加载。
这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件

/* 组件懒加载方案三: webpack提供的require.ensure() */
{
  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')
}
vue-router路由的两种模式

router 默认 hash 模式,还有一种是history模式

  • hash 模式:hash模式背后的原理是onhashchange事件,可以在window对象上监听这个事件

  • history模式: 这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面,如果不想要很丑的 hash,我们可以用路由的 history 模式,不过这种模式要玩好,还需要后台配置支持。

history路由模式与后台的配合

不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看。所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。

具体配置参见:https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90

什么是vuex
  • 专业版:Vuex是一个专为Vue开发的应用程序的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
  • 通俗版:Vuex采用类似全局对象的形式来管理所有组件的公用数据,如果你想想修改这个全局对象的数据?是可以的,但没那么简单,你得按照Vuex提供的方式来修改,不能自己随意用自己的方式来修改。
vuex的核心概念

State:Vuex 使用单一状态树,用一个对象State包含了整个应用层级的所有状态,你可以理解为这些状态就是一堆全局变量和数据。

Getters:当我们需要从 state 中派生出一些状态的时候,就会使用到getters ,你可以将 getters 理解 state 的计算属性

Mutations: Vuex给我们提供修改仓库 store 中的状态的唯一办法就是通过提交mutation。它和上面的 getters ,会接受 state 作为第一个参数
Vuex要求我们要想通过 mutations 更改内容,就必须提交mutation:

//提交一个名为increment的mutation
 store.commit('increment');

action:Action 类似于 mutation,不同在于

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。
  • Action 通过 store.dispatch 方法触发
vuex使用的场景:

vuex一般用于比较大型的项目中,比如保存用户的登录状态,导航的状态等

vuex数据页面刷新后状态丢失解决方法:
  • 利用storage缓存来实现vuex数据的刷新问题
  • 利用已有的插件来进行保存新状态 如vuex-along插件
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值