vue

VUE

vue的实例属性

$data

Vue 实例观察的数据对象。Vue 实例代理了对其 data 对象属性的访问。

console.log(this.text === this.$data.text); //true

$props

当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象属性的访问,在子组件上使用

$el

Vue 实例使用的根 DOM 元素。在子组件上就是子组件的根DOM元素

$options

用于当前 Vue 实例的初始化选项。需要在选项中包含自定义属性时会有用处,直接修改$options.data的值不会更改数据,也不会触发视图渲染

$parent

父实例,如果当前实例有的话。

$root

当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。

const app = new Vue({})
this.$root === this.$root.$children[0].$root  // true
this.$root === app  //true

$children

当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 $children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源。

$slots

用来访问被插槽分发的内容。每个具名插槽 有其相应的属性 (例如:slot="foo"中的内容将会在 vm.$slots.foo 中被找到)。default 属性包括了所有没有被包含在具名插槽中的节点。

在使用渲染函数书写一个组件时,访问 vm.$slots 最有帮助。

$scopedSlots

用来访问作用域插槽。对于包括 默认 slot 在内的每一个插槽,该对象都包含一个返回相应 VNode 的函数。

vm.$scopedSlots 在使用渲染函数开发一个组件时特别有用。

$refs

一个对象,持有注册过 ref特性的所有 DOM 元素和组件实例。

$isServer

当前 Vue 实例是否运行于服务器。用于服务端渲染

$attrs

包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (classstyle 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (classstyle 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。

$listeners

包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

Vue实例方法

$watch( expOrFn, callback, [options] )

观察 Vue 实例变化的一个表达式或计算属性函数。回调函数得到的参数为新值和旧值

$on( event, callback )

监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数。

$emit( eventName, […args] )

触发当前实例上的事件。附加参数都会传给监听器回调。

$once( event, callback )

监听一个自定义事件,但是只触发一次,在第一次触发之后移除监听器。

$forceUpdate()

不建议使用,频度控制不好容易造成内存溢出

迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。

如果更改在data中未声明的值,则不会触发视图更新,可以通过这个方法强制渲染,也可以通过$set避免这种情况

$off( [event, callback] )

移除自定义事件监听器。

$set( target, key, value )

Vue.set的别名

向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = 'hi')

注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。

$delete( target, key, value)

Vue.delete的别名

删除对象的属性。如果对象是响应式的,确保删除能触发更新视图。这个方法主要用于避开 Vue 不能检测到属性被删除的限制,但是你应该很少会使用它。

$nextTick([callback])

Vue的渲染是异步的

将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。

Vue对象的生命周期

Vue数据绑定

vue可以访问绑定在this上的变量,无法访问定义在实例外的全局变量

computed

计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。

计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。注意,如果某个依赖 (比如非响应式属性) 在该实例范畴之外,则计算属性是不会被更新的。

如果不指定set,那么默认提供的函数将被用作属性的getter函数

var vm = new Vue({
  data: { a: 1 },
  computed: {
    // 仅读取
    aDouble: function () {
      return this.a * 2
    },
    // 读取和设置
    aPlus: {
      get: function () {
        return this.a + 1
      },
      set: function (v) {
        this.a = v - 1
      }
    }
  }
})
vm.aPlus   // => 2
vm.aPlus = 3
vm.a       // => 2
vm.aDouble // => 4

watch

观察 Vue 实例变化的一个表达式或计算属性函数。回调函数得到的参数为新值和旧值。表达式只接受监督的键路径。对于更复杂的表达式,用一个函数取代。

 watch: {
    a: function (val, oldVal) {
      console.log( val, oldVal)
    }
 }

选项:deep

为了发现对象内部值的变化,可以在选项参数中指定 deep: true 。注意监听数组的变动不需要这么做。

当更改对象内部值时,vue的watch如果设置在整个对象上,那么将不会监听到变化,这时可以指定deep:true,但是这么做性能开销较大,因为每次对象中的任意一个值变化都会触发监听,可以在watch中直接监听内部值而不是整个对象

watch:{
    'obj.a':{
        get:function(){
     		//do something       
        }
    }
}

选项:immediate

在选项参数中指定 immediate: true 将立即以表达式的当前值触发回调

只有在vue第一次触发数据更新后,监听函数才会执行,制定了immediatetrue后,会在页面mouted后直接触发监听函数

Vue原生指令

v-show

根据表达式之真假值,切换元素的 display CSS 属性。

v-if

根据表达式的值的真假条件渲染元素。在切换时元素及它的数据绑定 / 组件被销毁并重建。如果元素是 <template> ,将提出它的内容作为条件块。

v-else v-else-if

限制:前一兄弟元素必须有 v-ifv-else-if

v-for

基于源数据多次渲染元素或模板块。此指令之值,必须使用特定语法 alias in expression ,为当前遍历的元素提供别名

v-for="(item, index) in items" //item:元素,index:索引
如果遍历Object
v-for="(value, key, index) in object" //value:键值,key:键名,index:索引

key

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

<li v-for="(item,index)in items" :key="item.id">
</li>

v-on

修饰符

如果使用内联语句,语句可以访问一个 $event 属性:v-on:click="handle('ok', $event)"

<!-- 阻止默认行为,没有表达式 -->
<form @submit.prevent></form>

v-bind

动态地绑定一个或多个特性

v-model

在表单控件或者组件上创建双向绑定

修饰符

可以用于<input> <select> <textarea> components

<input type="radio" value="one" v-model="choose"/>
<input type="radio" value="two" v-model="choose"/>

data(){
    return{
        choose:''
    }
}

v-once

只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。也不会进行虚拟DOM的对比,这可以用于优化更新性能。

v-pre

跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。

    <h2 v-pre></h2>
    html
    

v-text

<span v-text="msg"></span>
<!-- 和下面的一样 -->
<span></span>

v-html

内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译

易导致XSS攻击,不建议使用

组件

定义组件

Vue.component( id, [definition] )

为了使每个重复生命的组件有独立的数据,在组件中定义data要使用return一个对象的形式定义

data(){
    return {
 		//do something       
    }
}

props

props: ['size', 'myMessage']
 props: {
    // 检测类型
    height: Number,
    // 检测类型 + 其他验证
    age: {
      type: Number,
      //不传递属性值时的默认值,一般与required不同时使用
      default: 0,
      //规定属性为必须传递的
      required: true,
      //自定义的验证,如果不通过vue会在控制台报告错误
      validator: function (value) {
        return value >= 0
      }
    }

传递数据需要通过v-bind的形式传递,否则默认传递String类型

//传递Boolean
<com :size="true"  />
//传递String
<com size="true" />

如果需要在子组件上更改父组件的数据时,可以通过$emit的形式触发事件

const com = {
    template: `
    <div>
    <h1 @click="sonchange">
    THIS IS COM COMPONENT
    </h1>
    </div>
    `,
    methods: {
        sonchange() {
            this.$emit('change')
        }
    }
}
const app = new Vue({
    data() {
        return {
            text: 0
        }
    },
    components: {
        com
    },
    template: `
    <div>
    <h1>
    
    </h1>
    <com @change="handlechange"/>
    </div>
    `,
    methods: {
        handlechange() {
            this.text += 1;
        }
    }
}).$mount('#root')

extend

使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。

data 选项是特例,需要注意 - 在 Vue.extend() 中它必须是函数

// 创建构造器
var Profile = Vue.extend({
  template: '<p></p>',
  data: function () {
    return {
      firstName: 'Walter'
    }
  }
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#root')

也可以创建一个组件的子类,子类拥有对父类的属性和方法的访问权限,如果子类声明了父类中已经声明过的数据,那么子类将会覆盖父类

如果父类定义了必须传递的参数,也就是required:true时,直接传递props父组件将不会接收到数据,可以使用propsData传递数据,一般用于测试

const ComVue = Vue.extend('com');
new Comvue({
    propsData:{
        text:'111'
    }
}).$mount('#root')

组件的扩展

const com = {
    extends:comvue,
    data(){
        return{
            
        }
    }
}

parent

const com = {
    parent:comvue,
    methods:{
        log(){
            console.log(this.$parent.$options.name)
        }
    }
}

节制地使用 $parent$children - 它们的主要目的是作为访问组件的应急方法。更推荐用 props 和 events 实现父子组件通信

extends不同,parent只会在子组件和父组件之间建立一层联系,可以通过$parent读写父组件的数据

组件之间实现v-model

const com = {
    template: `
    <div>
        <input type="text" @input="handleinput">
        <slot/>
    </div>
    `, 
    methods: {
        handleinput(e) {
            this.$emit('input', e.target.value)
        }
    }
}
new Vue({
    components: {
        com
    },
    data() {
        return {
            value: 0
        }
    },
    template: `
    <com v-model="value">
    
    </com>`
}).$mount('#root')

组件高级属性

slot

<div class="container">
  <header>
    <!-- 我们希望把页头放这里 -->
  </header>
  <main>
    <!-- 我们希望把主要内容放这里 -->
  </main>
  <footer>
    <!-- 我们希望把页脚放这里 -->
  </footer>
</div>

对于这样的情况,<slot> 元素有一个特殊的特性:name。这个特性可以用来定义额外的插槽:

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

在向具名插槽提供内容的时候,我们可以在一个父组件的 <template> 元素上使用 slot 特性:

<base-layout>
  <template slot="header">
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template slot="footer">
    <p>Here's some contact info</p>
  </template>
</base-layout>

如果想要在实例的插槽中使用子组件中定义的数据,可以通过slot-scope

const com = {
template:`<div>
<slot value="111">
</slot>
</div>
`
}

new Vue({
	data(){
        return{
            value:'222'
        }
	}
    template:`
    <div>
    <com> 
    <span slot-scop="props" >
    +  //111  222
    </span>
    </com>
    </div>`
}).$mount('#root')

provide/inject

provideinject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。

在子组件上使用父组件,或者祖先组件上的数据

new Vue({
  data(){
      return{
          value:0
      }
  },
  provide(){
      reutrn{
          value:this.value
      }
  },
})
const com = {
    components:{
        childcom
    },
    template:`<childcom />`
}
const childcom = {
    template:``,
    inject:['value'],
    mouted(){
        console.log(this.value);  //0
    }
}

provideinject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。

render Function

如果需要javascript的完全编程的能力,可以用render函数

Vue Render Document

new Vue({
    //     template: `
    //  <comp-one ref="comp"><span ref="span"></span></comp-one>
    //     `
    render(createElement) {
        return createElement(
            'comp-one', {
                ref: 'comp'
            }, [
                createElement('span', {
                    ref: 'span'
                }, this.value)
            ]
        )
    }
    
})

VueRouter

Router构建选项

routes

接收一个路由配置的数组,类似这样

routes: [{
            path: '/',
            redirect: '/home'
        },
        {
            path: '/home',
            name: 'home',
            component: Home
        },
        {
            path: '/about',
            name: 'about',
            component: () =>
                import ('./views/About.vue')
        }
    ]

mode

接收一个字符串,用于配置路由的模式,简单来说就是hash会在url和路由之间加入#,不利于seoabstract路由的切换不会反映在url上

base

接受一个字符串,配置应用的基路径。例如,如果整个单页应用服务在 /app/ 下,然后 base 就应该设为 "/app/"

linkActiveClass

全局配置 <router-link> 的默认“激活 class 类名”。只要URL路径中包含路由链接,都会添加这个类,也就是路径配置为/router-link会一直存在这个类

linkExactActiveClass

全局配置 <router-link> 精确激活的默认的 class。

scrollBehavior

当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置

scrollBehavior 方法接收 tofrom 路由对象。第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。

to表示跳转到哪个路由页面

form表示从哪个路由页面跳转来

这个方法返回滚动位置的对象信息

scrollBehavior (to, from, savedPosition) {
  if (savedPosition) {
    return savedPosition
  } else {
    return { x: 0, y: 0 }
  }
}

parseQuery / stringifyQuery

提供自定义查询字符串的解析/反解析函数。覆盖默认行为。

?连接的数据叫做Query

fallback

当浏览器不支持 history.pushState 控制路由是否应该回退到 hash 模式。默认值为 true

路由配置项

name

命名路由,通过一个名称来标识一个路由显得更方便一些

routes:[
    {
        path:'/home',
        name:'hame',
        component:Home
    }
]
<router-link :to="{name:'home'}">Home</router-link>

meta

用于配置路由一些额外的自定义信息

routes:[
    {
        path:'/home',
        name:'hame',
        component:Home,
        meta:{
            title:'this is home'
        }
    }
]

children

用于配置嵌套路由,在路由页面新增自路由,这个子路由会在路由页面的router-view中显示

routes:[
    {
        path:'/home',
        name:'hame',
        component:Home,
        children:{
            path:'/app',
            component:app
        }
    }
]

路由传参

routes:[
    {
        path:'/home:id',
        component:Home,
    }
]
//通过全局的$route访问
mouted(){
    console.log(this.$route.params)
}

而且,参数一旦指定,必须传递,否则vue将无法匹配到路由页面

$route还有一个叫做query的对象,它包含了URL?后连接的键值对

props

解耦

当设置了props,就可以不需要使用$route,直接作为props传递到组件内,在子组件上直接指定props

{
    path:'/app:id',
    props:true,
}


{
    path:'/app:id',
    props:{
        id:456
    },
}

{
    path:'/app:id',
    props:()=>({id:route.query.b})
}

具名路由

如果页面中存在多个router-view,可以通过设置名字来区别显示不同的组件

<router-view />
<router-view name="app"/>


routes:[
    {
        path:'/home',
        components:{
            default:home,
            app:app
        }
    }
]

导航守卫

全局前置守卫
router.beforeEach((to, from, next) => {
  // ...
  next();
})

每个守卫方法接收三个参数:

next()一定要被调用,否则钩子将不会被resolved

next也可以传递一个对象

next({
    path:'/app',
    replace:''
})
设置了replace后路由页面就会替换当前的路由页面,也就是使用浏览器的back会返回到上一个的上一个路由页面
全局解析守卫
router.beforeResolve((to, from, next) => {
  // ...
  next();
})

在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用

全局后置守卫
router.afterEach((to, from) => {
  // ...
})

后置守卫不接收next()

路由独享守卫
const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

组件内守卫

const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}
beforeEach
beforeEnter
beforeRouteEnter
beforeResolve
afterEach
beforeRouteLeave

beforeRouteUpdate会在路由的传参变化时触发,这时如果组件是复用的,那么生命周期钩子将不会被再次触发,此时需要监听beforeRouteUpdate
完整的导航解析流程
  1. 导航被触发。
  2. 在失活的组件里调用离开守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

路由的异步加载

这种形式会使用按需加载,也就是只加载当前路由的组件,提高首屏加载速度

{
	path: '/about',
	name: 'about',
	component: () =>import ('./views/About.vue')
},

VueX

export default new Vuex.Store({
    state: {
        count: 0
    },
    mutations: {
        updateCount(state, num) {
            state.count = num
        }
    },
    actions: {

    }
})

state

接收一个对象,存储全局的数据

this.$store.state.count

mutations

接收一个对象,用于存放一些改变数据的方法,他接受两个参数,第一个是所要调用的方法名,第二个被vue称为载荷(payload),也就是一些额外的数据

this.$store.commit("updateCount",i)


mutations只接收两个参数,如果需要传递多个多个值,第二个参数为一个对象

mutations:{
    updateCount(state,{num,num1}){
        
    }
}

getters

如果需要对数据进行过滤处理,可以在getters中定义,getters接收state作为第一个参数,mutationsgetters的区别在于,mutations是对store中状态的改变操作,而getters更类似于vue中的computed

export default new Vuex.Store({
getters:{
    changestate:(state)=>{
        return //do something
    }
}
})
this.$store.getters.changestate

actions

Action 类似于 mutation,不同在于:

    this.$store.dispatch("updateCountSync", {
      num: 10,
      time: 2000
    });
actions: {
        updateCountSync(store, data) {
            setTimeout(() => {
                store.commit('updateCount', data.num)
            }, data.time);
        }
    }
辅助函数

当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。

import {
    mapState,
    mapGetters
} from 'vuex'

当映射的计算属性的名称与 state 的子节点名称相同时,可以简单的传递一个数组

<template>
<div>
8
</div>
</template>
<script>
export default{
	computed:{
    	...mapState(['count'])
	}
}
</script>

如果需要给传递进来的数据设置一个别名,可以传递一个对象

<template>
<div>

</div>
</template>
<script>
export default{
	computed:{
    	...mapState({
            counter:'count'
    	})
	}
}
</script>

还可以接收一个参数,用于对数据的处理

<template>
<div>

</div>
</template>
<script>
export default{
	computed:{
    	...mapState({
            counter:(state)=>state.count++;
    	})
	}
}
</script>

mapGetters与mapState的用法相同,这两种方法都是求值,所以放在computed中,mapActions和mapMutations是对数据的操作,需要放在methods中methods

mutations: {
        updateCount(state,num) {
            state.count = num
        },
        changeString(state, {
            firstname,
            lastname
        }) {
state.name = `${firstname}-${lastname}`
        }
    },
    actions: {
        updateCountSync(store, data) {
            setTimeout(() => {
                store.commit('updateCount', data.num)}, data.time);}
    }




mounted(){
    this.updateCountSync({
        num:50,
        time:2000
    })
    this.updateCount(100);
}

methods:{
    ...mapActions(['updateCountSync']),
    ...mapMutations(['updateCount'])
}
严格模式
const store = new Vuex.Store({
  // ...
  strict: true
})

在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

不可以在生产环境中启用严格模式

const store = new Vuex.Store({
  // ...
  strict: process.env.NODE_ENV !== 'production'
})

Module

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,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 的状态

namespaced

默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。

如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名

modules:{
    account:{
        namespaced:true,
        state:{
            
        },
        actions:{
            changeString(store,state){
                
            }
        }
    }
}

methods:{
    ...mapAction(['account/changeString'])
}
computed:{
    this['account/changeString']('123')
}

如果希望在模块中访问全局的gettersactions,rootState都将作为第三个参数被传入。

const moduleA = {
  // ...
  getters: {
    sumWithRootCount (state, getters, rootState) {
      return state.count + rootState.count
    }
  }
}
const moduleA = {
  // ...
  actions: {
    incrementIfOddOnRootSum ({ state, commit, rootState }) {
      if ((state.count + rootState.count) % 2 === 1) {
        commit('increment')
      }
    }
  }
}

如果希望在一个模块中访问另一个模块的内容,也可以通过rootState进行操作

在模块内部调用全局mutations

//模块内访问全局mutations
const a = {
namespaced:true,
actions:{
    add({state,commit,rootState}){
        commit('updateState',{num:123},{root:true})
    }
}
}
//一个模块访问另一个模块的mutations
const a = {
namespaced:true,
actions:{
    add({state,commit,rootState}){
        commit('a/updateState',{num:123},{root:true})
    }
}
}

动态模块注册

store.registerModule('com', {
    state:{
        a:1
    }
})
computed:{
	...mapState({
		text:state=>state.com.a
	})
} 
//卸载模块
unregisterModule

VueX热重载

使用 webpack 的 Hot Module Replacement API,Vuex 支持在开发过程中热重载 mutation、module、action 和 getter。你也可以在 Browserify 中使用 browserify-hmr 插件。

对于 mutation 和模块,你需要使用 store.hotUpdate() 方法:

// store.js
import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import moduleA from './modules/a'

Vue.use(Vuex)

const state = { ... }

const store = new Vuex.Store({
  state,
  mutations,
  modules: {
    a: moduleA
  }
})

if (module.hot) {
  // 使 action 和 mutation 成为可热重载模块
  module.hot.accept(['./mutations', './modules/a'], () => {
    // 获取更新后的模块
    // 因为 babel 6 的模块编译格式问题,这里需要加上 `.default`
    const newMutations = require('./mutations').default
    const newModuleA = require('./modules/a').default
    // 加载新模块
    store.hotUpdate({
      mutations: newMutations,
      modules: {
        a: newModuleA
      }
    })
  })
}

watch

store.watch((state) => state.count, (count) => {
    console.log(`state has changed:${count}`);

})

响应式地侦听第一个函数参数的返回值,当值改变时调用回调函数,也就是第二个参数。fn 接收 store 的 state 作为第一个参数,其 getter 作为第二个参数。最后接收一个可选的对象参数表示 Vue 的 vm.$watch 方法的参数。

要停止侦听,调用此方法返回的函数即可停止侦听。

subscribe

订阅 store 的 mutation。handler 会在每个 mutation 完成后调用,接收 mutation 和经过 mutation 后的状态作为参数

store.subscribe((mutation, state) => {
    console.log(mutation.type);
    console.log(mutation.payload);
})

当每次mutations被调用时触发,返回两个参数,第一个参数是一个对象,包含mutation的名字,和传递的参数,第二个参数是经过mutation的```state``

subscribeAction

store.subscribeAction((action, state) => {
  console.log(action.type)
  console.log(action.payload)
})

订阅 store 的 action。handler 会在每个 action 分发的时候调用并接收 action 描述和当前的 store 的 state 这两个参数,与上一个订阅用法相同