Vuejs技术栈知识点小结

前言

上家公司的项目主要是使用jQuery和Angular1,而后本身学了React,没想到来到这家公司忽然开始作vue,不过vue仍是挺容易上手的。下面是vue技术栈的一些总结,都是来自官网,主要是本身对vue技术栈知识点的一些整理,所以此文很水,建议阅读个人上一篇文章Vuejs技术栈从CLI到打包上线实战全解析javascript

Vue

独立构建和运行时构建

有两种构建方式,独立构建和运行构建。它们的区别在于前者包含模板编译器然后者不包含。php

模板编译器的职责是将模板字符串编译为纯JavaScript的渲染函数。若是你想要在组件中使用template选项,你就须要编译器。css

生命周期

具体查看官网的流程图,要注意的是created和mounted区别,created是vm实例已建立但未挂载,所以一些DOM操做应该放在mounted中。异步请求放在created或者mounted暂时没发现什么区别,如您知道有什么区别,请评论指出。html

计算(computed)属性

模板内的表达式不该该包含太多的逻辑,对于任何复杂逻辑,都应当使用计算属性vue

computed属性和methods不一样的是计算属性是基于它们的依赖进行缓存的。java

computed属性和computed属性,一般更好的想法是使用computed属性而不是命令式的watch回调。虽然计算属性在大多数状况下更合适,但有时也须要一个自定义的watcher。当你想要在数据变化响应时,执行异步操做或开销较大的操做,这是颇有用的。node

数组更新检测

数组的变异方法(mutation method,会改变被这些方法调用的原始数组)会触发视图更新,有如下七个:vue-router

push() pop() shift() unshift() splice() sort() reverse()

当使用非变异方法时,能够用新数组替换旧数组,或者使用Vue.set方法。vuex

对象更新

能够用新对象替换旧对象,或者使用Vue.set方法django

Vue.set(vm.someObject, 'foo', 'bar') this.someObject = Object.assign({}, this.someObject, { a:1, b:2 })

事件处理器

Vue.js为v-on提供了事件修饰符和按键修饰符

表单控件绑定

能够用v-model指令在表单控件元素上建立双向数据绑定。常见修饰符有.lazy、.number、.trim。

也可使用自定义事件的表单输入组件。

组件

Vue组件的API来自三部分:props,events和slots:

  • Props容许外部环境传递数据给组件
  • Events容许组件触发外部环境的反作用
  • Slots容许外部环境将额外的内容组合在组件中。

1)组件的data属性必须是函数

2)父子组件

在Vue.js中,父子组件的关系能够总结为 props down, events up 。父组件经过props向下传递数据给子组件,子组件经过events给父组件发送消息。

prop是单向绑定的:当父组件的属性变化时,将传导给子组件,可是不会反过来。这是为了防止子组件无心修改了父组件的状态——这会让应用的数据流难以理解。

另外,每次父组件更新时,子组件的全部prop都会更新为最新值。这意味着你不该该在子组件内部改变prop。若是你这么作了,Vue会在控制台给出警告。

为何咱们会有修改prop中数据的冲动呢?一般是这两种缘由:

1.prop做为初始值传入后,子组件想把它看成局部数据来用;

2.prop做为初始值传入,由子组件处理成其它数据输出。

对这两种缘由,正确的应对方式是:

1.定义一个局部变量,并用prop的值初始化它:

props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }

2.定义一个计算属性,处理prop的值并返回。

props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }

注意在JavaScript中对象和数组是引用类型,指向同一个内存空间,若是prop是一个对象或数组,在子组件内部改变它会影响父组件的状态。

3)非父子组件

有时候两个组件也须要通讯(非父子关系)。在简单的场景下,可使用一个空的Vue实例做为中央事件总线。在复杂的状况下,咱们应该考虑使用专门的状态管理模式。

4).sync修饰符

在一些状况下,咱们可能会须要对一个prop进行『双向绑定』。

2.0中移除了.sync,Vue2.3.0+又将其添加回来了,可是此次它只是做为一个编译时的语法糖存在,它会被扩展为一个自动更新父组件属性的v-on侦听器。以下代码

<comp :foo.sync="bar"></comp>

会被扩展为:

<comp :foo="bar" @update:foo="val => bar = val"></comp>

当子组件须要更新foo的值时,它须要显式地触发一个更新事件:

this.$emit('update:foo', newValue)

5)使用slot进行内容分发

做用域插槽:接收从子组件中传递的prop对象。做用域插槽更具表明性的用例是列表组件,容许组件自定义应该如何渲染列表每一项

6)动态组件、is特性和keep-alive指令

7)子组件索引

尽管有props和events,可是有时仍然须要JavaScript中直接访问子组件。为此可使用ref为子组件指定一个索引ID。

异步更新队列

虽然 Vue.js 一般鼓励开发人员沿着“数据驱动”的方式思考,避免直接接触 DOM,可是有时咱们确实要这么作。为了在数据变化以后等待 Vue 完成更新 DOM ,能够在数据变化以后当即使用 Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。

过渡效果

Vue在插入、更新或者移除DOM时,提供多种不一样方式的应用过渡效果。包括如下工具:

  • 在CSS过渡和动画中自动应用class
  • 能够配合使用第三方CSS动画库,如Animate.css
  • 在过渡钩子函数中使用JavaScript直接操做DOM
  • 能够配合使用第三方JavaScript动画库,如Velocity.js

1)单元素/组件的过渡

Vue提供了transition的封装组件,在下列情形中,能够给任何元素和组件添加过渡

  • 条件渲染(使用v-if)
  • 条件展现(使用v-show)
  • 动态组件
  • 组件根节点

2)多个元素的过渡

对于原生标签可使用 v-if/v-else

3)多个组件的过渡

多个组件的过渡咱们可使用动态组件。

4)列表过渡

Render函数和JSX

自定义指令

和Angular的指令相似,主要操做DOM,下面是一个滚动加载的指令,holder暂时没想到什么更好的处理方法:

let scrollCallback = function (callback) { let windowH = window.innerHeight let getDocumentHeight = function () { var body = document.body var html = document.documentElement return Math.max( body.offsetHeight, body.scrollHeight, html.clientHeight, html.offsetHeight, html.scrollHeight ) } let scrollH = document.documentElement.scrollTop || document.body.scrollTop if (windowH + scrollH >= getDocumentHeight() - (this.holder || 20)) { callback() } } let callBackWarpped export default { bind (el, binding, vnode) { let holder if (vnode.data && vnode.data.attrs && vnode.data.attrs['scroll-placeholder']) { holder = parseInt(vnode.data.attrs['scroll-placeholder']) } else { holder = 20 } callBackWarpped = scrollCallback.bind({el, holder}, binding.value) window.addEventListener('scroll', callBackWarpped, false) }, unbind: function () { window.removeEventListener('scroll', callBackWarpped, false) } }

混合

混合是一种灵活的分布式复用Vue组件的方式。混合对象能够包含任意组件选项。以组件使用混合对象时,全部混合对象的选项将被混入该组件自己的选项。

插件

1)建立插件

Vue.js的插件应当有一个公开方法install。这个方法的第一个参数是Vue构造器 , 第二个参数是一个可选的选项对象。

2)使用插件

经过全局方法Vue.use()使用插件:

// 调用 `MyPlugin.install(Vue)` Vue.use(MyPlugin)

也能够传入一个选项对象:

Vue.use(MyPlugin, { someOption: true })

vue-router

两种导航方式

1)router-link声明式导航

<router-link to="/foo">Go to Foo</router-link>

router-link对应的路由匹配成功,将自动设置class属性值.router-link-active。

2)编程式导航

// 字符串 router.push('home') // 对象 router.push({ path: 'home' }) // 命名的路由 router.push({ name: 'user', params: { userId: 123 }}) // 带查询参数,变成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }})

重命名(redirect)和别名(alias)

两种路由模式

vue-router默认hash模式,也能够设置为路由的history模式。

导航钩子

vue-router提供的导航钩子主要用来拦截导航,让它完成跳转或取消。有多种方式能够在路由导航发生时执行钩子:全局的, 单个路由独享的, 或者组件级的。

路由meta

一个路由匹配到的全部路由记录会暴露为$route对象(还有在导航钩子中的route对象)的$route.matched数组。所以,咱们须要遍历$route.matched来检查路由记录中的meta字段。

过渡动效

router-view是基本的动态组件,因此咱们能够用transition组件给它添加一些过渡效果。

数据获取

有时候,进入某个路由后,须要从服务器获取数据。例如,在渲染用户信息时,你须要从服务器获取用户的数据。咱们能够经过两种方式来实现:

导航完成以后获取:先完成导航,而后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示『加载中』之类的指示。

导航完成以前获取:导航完成前,在路由的enter钩子中获取数据,在数据获取成功后执行导航。

滚动行为(scrollBehavior)

注意: 这个功能只在HTML5 history模式下可用。

路由懒加载

当打包构建应用时,Javascript包会变得很是大,影响页面加载。若是咱们能把不一样路由对应的组件分割成不一样的代码块,而后当路由被访问的时候才加载对应组件,这样就更加高效了。

结合Vue的异步组件和Webpack的code splitting功能,轻松实现路由组件的懒加载。

const Foo = resolve => require(['./Foo.vue'], resolve) const router = new VueRouter({ routes: [ { path: '/foo', component: Foo } ] })

能够设置tag、append、active-class、exact等属性

有时候咱们要让 "激活时的CSS类名" 应用在外层元素,而不是a标签自己,那么能够用router-link渲染外层元素,包裹着内层的原生a标签:

<router-link tag="li" to="/foo"> <a>/foo</a> </router-link>

在这种状况下,a将做为真实的连接(它会得到正确的 href 的),而"激活时的CSS类名"则设置到外层的li。

Router构造配置

routes、mode、base、linkActiveClass、scrollBehavior

对组件注入

1)注入的属性

经过在Vue根实例的router配置传入router实例,下面两个属性成员会被注入到每一个子组件。

$router:router实例

$route:当前激活的路由信息对象。这个属性是只读的,里面的属性是immutable(不可变)的,不过你能够watch(监测变化)它。

2)容许的额外配置:beforeRouteEnter、beforeRouteLeave

vuex

state

1)单一状态树

Vuex使用单一状态树--是的,用一个对象就包含了所有的应用层级状态。至此它便做为一个『惟一数据源(SSOT)』而存在。这也意味着,每一个应用将仅仅包含一个store实例。单一状态树让咱们可以直接地定位任一特定的状态片断,在调试的过程当中也能轻易地取得整个当前应用状态的快照。

2)在Vue组件中得到Vuex状态

最好在根实例中注册store选项,该store实例会注入到根组件下的全部子组件中,且子组件能经过this.$store访问到。而不是在每一个须要使用state的组件中须要频繁地导入。

3)mapState辅助函数

当一个组件须要获取多个状态时候,可使用mapState辅助函数帮助咱们生成计算属性,这样能够简化代码书写。mapState函数会返回一个对象,而后可使用对象展开运算符将它与局部计算属性混合使用。

4)不要滥用vuex

使用Vuex并不意味着你须要将全部的状态放入Vuex。虽然将全部的状态放到Vuex会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。若是有些状态严格属于单个组件,最好仍是做为组件的局部状态。你应该根据你的应用开发须要进行权衡和肯定。

getters

getters用来从store中的state中派生出一些状态,例如对列表进行过滤并计数:

computed: {
  doneTodosCount () {
    return this.$store.state.todos.filter(todo => todo.done).length } }

getters能够认为是store的计算属性。和state相似,有mapGetters辅助函数。

mutations

更改Vuex的store中的状态的惟一方法是提交mutation。Vuex中的mutations很是相似于事件:每一个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)。这个回调函数就是咱们实际进行状态更改的地方,而且它会接受state做为第一个参数

1)提交载荷(Payload)

你能够向store.commit传入额外的参数,即mutation的载荷(payload):

// ...
mutations: {
  increment (state, n) { state.count += n } } store.commit('increment', 10)

2)Mutations需遵照Vue的响应规则

3)使用常量替代Mutation事件类型

4)mutation必须是同步函数

5)在组件中提交Mutations

你能够在组件中使用this.$store.commit('xxx')提交mutation,或者使用mapMutations辅助函数将组件中的methods映射为store.commit调用(须要在根节点注入store)。

actions

actions相似于mutation,不一样在于:

  • actions提交的是mutation,而不是直接变动状态。
  • actions能够包含任意异步操做。

1)在组件中分发Action

你在组件中使用this.$store.dispatch('xxx')分发action,或者使用mapActions辅助函数将组件的methods映射为store.dispatch调用(须要先在根节点注入store)

2)组合Actions

Action一般是异步的,那么如何知道action何时结束呢?更重要的是,咱们如何才能组合多个action,以处理更加复杂的异步流程?

首先,你须要明白store.dispatch能够处理被触发的action的回调函数返回的Promise,而且store.dispatch仍旧返回Promise。

使用async/await会更加简单:

// 假设 getData() 和 getOtherData() 返回的是 Promise actions: { async actionA ({ commit }) { commit('gotData', await getData()) }, async actionB ({ dispatch, commit }) { await dispatch('actionA') // 等待 actionA 完成 commit('gotOtherData', await getOtherData()) } }

Modules

因为使用单一状态树,应用的全部状态会集中到一个比较大的对象。当应用变得很是复杂时,store对象就有可能变得至关臃肿。

为了解决以上问题,Vuex容许咱们将store分割成模块(module)。每一个模块拥有本身的state、mutation、action、getter、甚至是嵌套子模块——从上至下进行一样方式的分割:

const moduleA = {
 state: { ... },  mutations: { ... },  actions: { ... },  getters: { ... } } const moduleB = {  state: { ... },  mutations: { ... },  actions: { ... } } const store = new Vuex.Store({  modules: {  a: moduleA,  b: moduleB } }) store.state.a // -> moduleA 的状态 store.state.b // -> moduleB 的状态

插件

Vuex的store接受plugins选项,这个选项暴露出每次mutation的钩子。Vuex插件就是一个函数,它接收store做为惟一参数。

严格模式

开启严格模式,仅需在建立store的时候传入strict:true

在严格模式下,不管什么时候发生了状态变动且不是由mutation函数引发的,将会抛出错误。这能保证全部的状态变动都能被调试工具跟踪到。

不要在发布环境下启用严格模式!严格模式会深度监测状态树来检测不合规的状态变动--请确保在发布环境下关闭严格模式,以免性能损失。

表单处理

测试

热重载

相关文章
相关标签/搜索