一、Vue 中 computed 和 watch 的区别
计算属性 computed :
1. 支持缓存,只有依赖数据发生改变,才会重新进行计算
2. 不支持异步,当 computed 内有异步操作时无效,无法监听数据的变化
3.computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于 data 中声明过或者父组件传递的 props 中的数据通过计算得到的值
4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用 computed
5. 如果 computed 属性属性值是函数,那么默认会走 get 方法;函数的返回值就是属性的属性值;在 computed 中的,属性都有一个 get 和一个 set 方法,当数据变化时,调用 set 方法。
侦听属性 watch:
1. 不支持缓存,数据变,直接会触发相应的操作;
2.watch 支持异步;
3. 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
4. 当一个属性发生变化时,需要执行对应的操作;一对多;
5. 监听数据必须是 data 中声明过或者父组件传递过来的 props 中的数据,当数据变化时,触发其他操作,函数有两个参数,
immediate:组件加载立即触发回调函数执行,
deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep 无法监听到数组的变动和对象的新增,参考 vue 数组变异, 只有以响应式的方式触发才会被监听到。
监听的对象也可以写成字符串的形式
二、vue-router 路由钩子
路由钩子主要用来拦截导航,在钩子里可以跳转到指定的页面或取消跳转。
- 路由参数或者查询的改变不会触发导航守卫!。* 可以通过 watch 观察 $route 对象来应对这些变化,或用 beforeRouteUpdate 的组件内守卫。
1. 全局前置守卫
1.1 beforeEach
router.beforeEach((to, from, next) => {})
当一个导航触发时,全局前置守卫按照创建的顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 * 等待中 *。
每个守卫方法接收三个参数:
- to:到哪去(正要进入的路由);
- from: 从哪来(正要离开的路由);
- next: 如果是 next()就完成跳转到 to 指示的路由;如果参数为 false 则取消此次导航;如果参数是地址或路由对象则调到指定的地址或对象。
- 确保一定要调用 next 方法,否则钩子就不会被 resolve。*
2. 独享路由钩子
2.1 beforeEnter
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {}}
]
})
3. 组件路由钩子
3.1 beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
data () {return {}
},
beforeRouteEnter (to, from, next) {// 在渲染该组件的对应路由被确认前调用,不能获取组件示例 this,因为当守卫执行前,组件的实例还没被创建。},
beforeRouteUpdate (to, from, next) {
// 当路由发生改变,但是该组件被复用时调用。也就是路由参数或者查询改变时。// 举例:对于一个动态参数的路径 /foo/:id,当从 /foo/1 跳转到 /foo/2 时被调用。由于会渲染同一个组件,因此组件实例会被复用。所以这个钩子会在这个情况下被调用。// 可以访问组件 this
},
beforeRouteLeave (to, from, next) {
// 离开该组件的对应路由时调用。// 可以访问组件 this
}
- beforeRouteEnter 不能访问 this,但是可以通过传给 next 一个回调函数来访问组件实例,在导航被确认的时候会执行回调。并且把组件实例作为回调方法的参数。
beforeRouteEnter (to, from, next) {
next(vm => {// 通过 vm 访问组件实例})
}
- beforeRouteLeave 通常用來禁止用戶在还未保存修改前突然离开。该导航可以通过 next(false)来取消跳转。
三、vue-router 实现路由懒加载
当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载.
1、定义
也叫延迟加载,即在需要的时候进行加载,随用随载
2、为什么需要
像 vue 这种单页面应用,如果没有应用懒加载,运用 webpack 打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,时间过长,会出啊先长时间的白屏,即使做了 loading 也是不利于用户体验,而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时,进入首页不用一次加载过多资源造成用时过长。
3、如何实现?
(1)第一种写法:使用 AMD 风格的 require,于是就更简单了:
例:const Foo = resolve => require([‘./Foo.vue’], resolve)
const routers = [
{
path: '/',
name: 'index',
component: (resolve) =>require(['./views/index.vue'], resolve)
}
]
(2)第二种写法:(使用 import)
例:component: () => import(‘@/components/Two’)
const Index = () => import(/* webpackChunkName: "group-home" */ '@/views/index')
const routers = [
{
path: '/',
name: 'index',
component: Index
}
]
(3)第三种写法:使用 webpack 特有的 require.ensure()。注:require.ensure 是 Webpack 的特殊语法,用来设置 code-split point
例:components: r => require.ensure([], () => r(require(‘@/components/Three’)), ‘group-home’)
const Index = r => require.ensure([], () => r(require('./views/index')), 'group-home');
const routers = [
{
path: '/',
name: 'index',
component: Index
}
]
4、把组件按组分块
有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。
const Foo = r => require.ensure([], () => r(require('./Foo.vue')), 'group-foo')
const Bar = r => require.ensure([], () => r(require('./Bar.vue')), 'group-foo')
const Baz = r => require.ensure([], () => r(require('./Baz.vue')), 'group-foo')
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
Webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。
5、注
- 一般常用第二种简写
- 第三种中,’group-home’是把组件按组分块打包, 可以将多个组件放入这个组中,在打包的时候 Webpack 会将相同 chunk 下的所有异步模块打包到一个异步块里面。
Vuex 总结 – 是什么? 有什么? 怎么用?
=====================================================================
四、Vuex 总结 – 是什么? 有什么? 怎么用?
首先 Vuex 是状态管理器
一、为什么用;
首先 我们的 vue 是单向数据流;
1、当我们处理大量数据的时候,传参的方法对于多层嵌套的组件来说是非常繁琐的,而且兄弟间的状态传递是无能为力的;
2、我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝;而以上模式都非常脆弱,会造成 无法维护的代码;
所以 我们将组件的共享状态拿出来以一个全局单例模式管理。
二、有哪些东西;
state : 数据源存放地,对应于一般 Vue 对象里的 data;
getter : 相当于是计算属性;所以,getter 的 返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算;
mutation : 只是用来修改数据的;
action : 大多数用来处理异步操作;
module : 有时候我们的应用的所有状态可能会集中到一个比较大的对象。当应用复杂时,store 会很臃肿 所以我们将 store 分割成模块 就像我们在文件夹中建立子文件夹一样;目的都是为了便于管理
三、数据传递过程:
当组件进行数据修改的时候我们需要调用 Dispatch 来触发 actions 里边的方法,actions 里边的每个方法都会有一个 commit 方法,当方法执行的时候通过 commit 来触发 mutations 里边的方法进行数据的修改,mutations 里边的每个函数都会有一个 state 参数,这样就可以在 mutations 里边进行 state 的数据修改,当数据修改完毕之后,会渲染到页面 页面的数据也会发生改变
流程图(来自官网):
四、什么时候用?
对于一些大型的 SPA 应用 我们在用到大量的数据处理,考虑到如何更好的在组件外部管理状态时,就可以考虑使用 Vuex;