vue(四):vuex

目录

  • 1 引入 vuex
  • 2 state 访问状态对象
  • 3 mutations(同步) 模板获取方法
  • 4 getters 计算过滤操作
  • 5 actions 异步修改状态
  • 6 modules 模块

1 引入 vuex

前提是已经用 Vue 脚手架工具构建好项目:

vue init webpack vue-test

1:安装

cnpm i vuex --save-dev

2:编写 store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const state = {
  count: 10
}

const mutations = {
  increment(state) {
    state.count++
  },
  reduce(state) {
    state.count--
  }
}

export default new Vuex.Store({
  state,
  mutations
})


3:主入口 main.js,引入 store.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/store'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})


4:使用

<template>
  <div class="hello">
    <h1>home</h1>
    <div>
      {{$store.state.count}} <!-- 页面获取对应的 state -->
      <button @click="increment">新增</button>
      <button @click="reduce">减少</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App'
    };
  },
  methods: {
    increment: function() {
      this.$store.commit('increment'); // commit 触发调用 store 中的方法;
    },
    reduce: function() {
      this.$store.commit('reduce');
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>


2 访问状态对象 state

store 中的 state,即为访问状态对象,它就是我们 SPA(单页应用程序)中的共享值。

状态对象赋值给内部对象,也就是把 stroe.js 中的值,赋值给我们模板里 data 中的值。有三种赋值方式

一、 通过 computed 的计算属性直接赋值
computed 属性可以在输出前,对 data 中的值进行改变,我们就利用这种特性把 store.js 中的 state 值赋值给我们模板中的 data 值。

<template>
  <div class="hello">
    <h1>home</h1>
    <div>
      {{$store.state.count}} -- {{count}}
      <button @click="increment">新增</button>
      <button @click="reduce">减少</button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // count: 0
    };
  },
  computed: {
    count() {
      return this.$store.state.count;
    }
  },
  methods: {
    increment: function() {
      this.$store.commit('increment');
    },
    reduce: function() {
      this.$store.commit('reduce');
    }
  }
};
</script>


这里需要注意的是 return this.$store.state.count 这一句,一定要写 this,要不你会找不到 $store 的。这种写法很好理解,但是写起来是比较麻烦的,那我们来看看第二种写法。

二、通过 mapState 的对象来赋值

我们首先要用 import 引入 mapState。

import { mapState } from 'vuex';

<template>
  <div class="hello">
    <h1>home</h1>
    <div>
      {{$store.state.count}} -- {{count}}
      <button @click="increment">新增</button>
      <button @click="reduce">减少</button>
    </div>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  data() {
    return {
      // count: 0
    };
  },
  computed: mapState({  // !!!
    count: state => state.count, // 理解为传入 state 对象,修改 state.count 属性
  }),
  methods: {
    increment: function() {
      this.$store.commit('increment');
    },
    reduce: function() {
      this.$store.commit('reduce');
    }
  }
};
</script>

三、通过 mapState 的数组来赋值

<template>
  <div class="hello">
    <h1>home</h1>
    <div>
      {{$store.state.count}} -- {{count}}
      <button @click="increment">新增</button>
      <button @click="reduce">减少</button>
    </div>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  data() {
    return {
      // count: 0
    };
  },
  computed: mapState(['count']), // !!!
  methods: {
    increment: function() {
      this.$store.commit('increment');
    },
    reduce: function() {
      this.$store.commit('reduce');
    }
  }
};
</script>

这个算是最简单的写法了,在实际项目开发当中也经常这样使用。

3 模板获取 Mutations(同步) 方法

方式一:$store.commit 触发

<template>
  <div class="hello">
    <h1>home</h1>
    <div>
      {{$store.state.count}} -- {{count}}
      <button @click="increment({n: 111})">新增</button>
      <button @click="reduce">减少</button>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex';

export default {
  name: 'HelloWorld',
  data() {
    return {
      // count: 0
    };
  },
  computed: mapState(['count']),
  methods: {
    increment: function() {
      this.$store.commit('increment', { n: 100 }); // 参数
    },
    reduce: function() {
      this.$store.commit('reduce');
    }
  }
};
</script>


方式二:mapMutations 数组

<template>
  <div class="hello">
    <h1>home</h1>
    <div>
      {{$store.state.count}} -- {{count}}
      <button @click="increment({n: 111})">新增</button>
      <button @click="reduce">减少</button>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex';

export default {
  data() {
    return {
      // count: 0
    };
  },
  computed: mapState(['count']),
  methods: mapMutations(['increment', 'reduce'])
};
</script>


方式三:mapMutations 解构

<template>
  <div class="hello">
    <h1>home</h1>
    <div>
      {{$store.state.count}} -- {{count}}
      <button @click="add({n: 12})">新增add</button>
      <button @click="increment({n: 111})">新增</button>
      <button @click="reduce">减少</button>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex';

export default {
  data() {
    return {
      // count: 0
    };
  },
  computed: mapState(['count']),
  methods: {
    ...mapMutations(['increment', 'reduce']),
    ...mapMutations({ add: 'increment' }) // 映射 this.add() 为 this.$store.commit('increment')
  }
};
</script>


store.js:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const state = {
  count: 10
}

const mutations = {
  increment(state, obj) {
    state.count += obj.n
  },
  reduce(state) {
    state.count--
  }
}

export default new Vuex.Store({
  state,
  mutations
})


4 getters 计算过滤操作

getters 从表面是获得的意思,可以把他看作在获取数据之前进行的一种再编辑,相当于对数据的一个过滤和加工。你可以把它看作 store.js 的计算属性。

比如我们现在要对 store.js 文件中的 count 进行一个计算属性的操作,就是在它输出前,给它加上 100。我们首先要在 store.js 里用 const 声明我们的 getters 属性。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const state = {
  count: 10
}

const mutations = {
  increment(state, obj) {
    state.count += obj.n
  },
  reduce(state) {
    state.count--
  }
}

const getters = {
  handleCount: function (state) {
    return (state.count += 100);
  }
}

export default new Vuex.Store({
  state,
  mutations,
  getters
})


在 store.js 里的配置算是完成了,我们需要到模板页对 computed 进行配置。

<template>
  <div class="hello">
    <h1>home</h1>
    <div>
      {{$store.state.count}} -- {{count}}
      <button @click="add({n: 12})">新增add</button>
      <button @click="increment({n: 111})">新增</button>
      <button @click="reduce">减少</button>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex';

export default {
  name: 'HelloWorld',
  data() {
    return {
      // count: 0
    };
  },
  computed: {
    ...mapState(['count']),
    handleCount() {
      return this.$store.getters.count;
    },
  },
  methods: {
    ...mapMutations(['increment', 'reduce']),
    ...mapMutations({ add: 'increment' }) // 映射 this.add() 为 this.$store.commit('increment')
  }
};
</script>


另一个方式使用 mapGetters:

<template>
  <div class="hello">
    <h1>home</h1>
    <div>
      {{$store.state.count}} -- {{count}}
      <button @click="add({n: 12})">新增add</button>
      <button @click="increment({n: 111})">新增</button>
      <button @click="reduce">减少</button>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations, mapGetters } from 'vuex';

export default {
  name: 'HelloWorld',
  data() {
    return {
      // count: 0
    };
  },
  computed: {
    ...mapState(['count']),
    ...mapGetters(['handleCount'])
  },
  methods: {
    ...mapMutations(['increment', 'reduce']),
    ...mapMutations({ add: 'increment' }) // 映射 this.add() 为 this.$store.commit('increment')
  }
};
</script>


!!!需要注意的是,你写了这个配置后,在每次 count 的值发生变化的时候,都会进行加 1100 的操作。

5 actions 异步修改状态

actions 和之前讲的 Mutations 功能基本一样,不同点是,actions 是异步的改变 state 状态,而 Mutations 是同步改变状态。

store 中声明 actions

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const state = {
  count: 10
}

const mutations = {
  increment(state, obj) {
    state.count += obj.n
  },
  reduce(state) {
    state.count--
  }
}

const getters = {
  handleCount: function (state) {
    return (state.count += 100);
  }
}

const actions = {
  incrementAsync(context) {
    context.commit('increment', { n: 11 });
  },
  reduceAsync(context) {
    context.commit('reduce');
  }
}

export default new Vuex.Store({
  state,
  mutations,
  getters,
  actions
})


模板中使用 actions:

<template>
  <div class="hello">
    <h1>home</h1>
    <div>
      {{$store.state.count}} -- {{count}}
      <button @click="add({n: 12})">新增add</button>
      <button @click="increment({n: 111})">新增</button>
      <button @click="reduce">减少</button>

      <button @click="incrementAsync({n: 2})">新增</button>
      <button @click="reduceAsync">减少</button>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations, mapGetters, mapActions } from 'vuex';

export default {
  data() {
    return {
      msg: 'Welcome to Your Vue.js App'
      // count: 0
    };
  },
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapMutations(['increment', 'reduce']),
    ...mapMutations({ add: 'increment' }), // 映射 this.add() 为 this.$store.commit('increment')
    ...mapActions({
      incrementAsync: 'incrementAsync',
      reduceAsync: 'reduceAsync'
    })
  }
};
</script>


6 modules

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

如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。

moduleA.js

const state = {
  count: 10,
  count2: 1
}

const mutations = {
  increment(state, obj) {
    state.count += obj.n
  },
  reduce(state) {
    state.count--
  }
}

const getters = {
  handleCount: function (state) {
    return (state.count += 100);
  },
  handleCount2: function (state) {
    return (state.count2 += 10);
  }
}

const actions = {
  incrementAsync(context) {
    context.commit('increment', { n: 11 });
  },
  reduceAsync(context) {
    context.commit('reduce');
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  getters,
  actions
}


store.js,配置 modules,引入 moduleA。

import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './moduleA'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    aa: moduleA
  }
})


组件引用,如果模块有 namespaced 为 true,则需要带上命名空间,如果模块没有 namespaced,则模块默认为全局;
注意跟全局 store 区别。

<template>
  <div class="hello">
    <h1>home</h1>
    <div>
      {{$store.state.aa.count}} --- {{count}} --- {{count2}}
      <button @click="add({n: 12})">新增add</button>
      <button @click="increment({n: 111})">新增increment</button>
      <button @click="reduce">减少reduce</button>

      <button @click="incrementAsync({n: 2})">新增incrementAsync</button>
      <button @click="reduceAsync">减少reduceAsync</button>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations, mapGetters, mapActions } from 'vuex';

export default {
  data() {
    return {
      msg: 'Welcome to Your Vue.js App'
    };
  },
  computed: {
    ...mapState({
      count: state => state.aa.count
    }),
    count2() {
      return this.$store.state.aa.count2;
    }
  },
  methods: {
    // ...mapMutations(['aa/increment', 'aa/reduce']), // !!!不能这样写,报错,应该使用下面对象的写法
    ...mapMutations({
      increment: 'aa/increment',
      reduce: 'aa/reduce'
    }),
    ...mapMutations({ add: 'aa/increment' }), // 映射 this.add() 为 this.$store.commit('increment')
    ...mapActions({
      incrementAsync: 'aa/incrementAsync',
      reduceAsync: 'aa/reduceAsync'
    })
  }
};
</script>


7 补充

7.1 export 方法创建路由

路由使用函数方式在入口文件引入:

import createRouter from './config/router'

const router = createRouter();

new Vue({
  router,
  ...
})

7.2 export 方法创建 Store

创建 store.js,通过函数创建 Store

import Vuex from 'vuex'

export default () => {
  return new Vuex.Store({
    state: {
      ...
    },
    mutations: {
      ...
    }
  })
}

入口引入 Vuex

import createStore from './store/store'

const store = createStore();

new Vue({
  store,
  ...
})

说明:为什么路由和 store 都是 export 一个方法
因为使用服务端渲染,每一次服务端渲染的时候,都应该生成一个新的store,不能使用同一 store,这样会有内存溢出问题 。

7.3 在组件中使用不同的方式获取 store 中的 state:

computed: {
  count() {
    return this.$store.state.count
  }
}

computed: {
  ...mapState({
    counter: 'count'
  })
}

computed: {
  ...mapState({
    counter: (state) => state.count
  })
}

7.4 通过配置 strict,规范 vuex 修改数据

由于在组件中也是能直接修改 state 数据,不用通过 mutation,为了修改数据的规范,尽量规范通过 mutation 来修改 store,可以在 new Vuex.Stroe 的时候,进行配置:开发使用,正式生产环境应该关掉

import Vuex from 'vuex'

const isDev = process.env.NODE_ENV === 'development'; // 判断是否是开发环境

export default () => {
  return new Vuex.Store({
    strict: isDev
    state: {
      ...
    },
    mutations: {
      ...
    }
  })
}

7.5 actions 方法参数说明

对于 actions,传入方法的第一个参数是 store,不是 state,传参多个的时候,第二个参数是对象(可以理解为 payload 对象),只有两个参数,actions 的方法是通过 dispatch 来触发的;

7.6 modules 模块扩展说明

1:对于模块,配置 namespaced, 如果没有配置 namespaced,则 mutations、actions、getters 等会被默认放到全局 store;

2:getters 中的方法,通过配置 rootState,可以获取默认全局 state,或者其他模块的 state;

3:默认情况下,对于 mutations 方法获取的 state,为该模块下的 state;

4:actions 方法参数,context 可以拿到 state、commit、rootState 等参数,而 commit 默认触发的是该模块下的 mutations 方法;

actions: {
   addText({ state, commit, rootState }) { // 该模块的 context 可以拿到 state、commit、rootState 等参数
      commit('changeText', { text: rootState.count }) // commit 默认就是该模块的 mutations
    }
 }

如果想触发全局 mutations, 可以配置 root,则 commit 会去找全局模块的 mutations

actions: {
  addText({ state, commit, rootState }) { // 该模块的 context 可以拿到 state、commit、rootState 等参数
    context.commit('changeText', {text: 33}, { root: true }) // 配置 root,则 commit 会去找全局模块的 mutations
  }
}

如果想触发其他模块 mutations, 可以配置 root,再加上在 commit 中对应模块的前缀

actions: {
  addText({ state, commit, rootState }) { // 该模块的 context 可以拿到 state、commit、rootState 等参数
    commit('b/bChangeText', { text: 3 }, { root: true }) // 调用其他模块的 mutations,配置 root,注意 b 模块需要配置 namespaced
  }
}

import Vue from 'vue'
import Vuex from 'vuex'
// import moduleA from './moduleA'
import defalutState from './state/state'
import mutations from './mutations/mutations'
import getters from './getters/getters'
import actions from './actions/actions'

Vue.use(Vuex)

const store = new Vuex.Store({ // 热更新 的功能
  state: defalutState,
  mutations,
  getters,
  actions,
  modules: {
    a: {
      namespaced: true, // 如果没有加 namespaced,则 mutations、actions、getters 等会被默认放到全局 store
      state: {
        text: 0
      },
      mutations: {
        changeText(state, { text }) { // mutations 方法获取的 state 为该模块下的 state
          state.text = text;
        }
      },
      getters: {
        getText(state, getters, rootState) { // 获取全局 state
          return state.text + rootState.count
          // return state.text + rootState.b.text
        }
      },
      // getters: {
      //   getText(state) {
      //     return state.text + 5
      //   }
      // }
      actions: {
        addText({ state, commit, rootState }) { // 该模块的 context 可以拿到 state、commit、rootState 等参数
          commit('changeText', { text: rootState.count }) // commit 默认就是该模块的 mutations
          // context.commit('changeText', {text: 33}, { root: true }) // 配置 root,则 commit 会去找全局模块的 mutations
          // context.commit('increment', { n: 3 }, { root: true }) // 配置 root,则 commit 会去找全局模块的 mutations
          commit('b/bChangeText', { text: 3 }, { root: true }) // 调用其他模块的 mutations,配置 root,注意 b 模块需要配置 namespaced
        }
      }
    },
    b: {
      namespaced: true,
      state: {
        text: 22
      },
      mutations: {
        bChangeText(state, { text }) { // mutations 方法获取的 state 为该模块下的 state
          state.text = text;
        }
      }
    }
  }
})

export default store;


7.7 动态新增模块 registerModule

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/store'

// 动态新增模块
store.registerModule('c', {
   state: {
     text: '232w3'
   }
 })

// store.unregisterModule(c)
// store.unregisterModule(moduleName) 解绑
// https://vuex.vuejs.org/zh/guide/modules.html#%E6%A8%A1%E5%9D%97%E5%8A%A8%E6%80%81%E6%B3%A8%E5%86%8C


Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App />'
})


7.8 使用 vuex 后,配置热重载

官网:https://vuex.vuejs.org/zh/guide/hot-reload.html

import Vue from 'vue'
import Vuex from 'vuex'
import defalutState from './state/state'
import mutations from './mutations/mutations'
import getters from './getters/getters'
import actions from './actions/actions'

Vue.use(Vuex)
export default () => {
  const store = new Vuex.Store({ // 热更新 的功能
    state: defalutState,
    mutations,
    getters,
    actions
  })

  if (module.hot) {
    module.hot.accept([
      './state/state',
      './mutations/mutations',
      './getters/getters',
      './actions/actions'
    ], () => {
      // 1.获取更新后的模块
      // 因为 babel6 的模块编译格式问题,这里需要加上.default
      const newState = require('./state/state').default;
      const newMutations = require('./mutations/mutations').default;
      const newGetters = require('./getters/getters').default;
      const newActions = require('./actions/actions').default;
      // 2.加载新模块
      store.hotUpdate({
        state: newState,
        mutations: newMutations,
        getters: newGetters,
        actions: newActions
      })
    })
  }
  return store;
}


7.9 store 方法 watch

store.watch((state) => state.count + 500, (newCount) => {
  console.log('newCount', newCount);
})

第一个参数为函数,需要返回对哪个 store 中哪个 state
进行监听,第二个参数也为方法,参数为新的 state,为回调方法。

7.10 store 方法 subscribe

每次触发 mutation 就会触发 subscribe

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

7.11 store 方法 subscribeAction

每次触发 action 就会触发 subscribeAction

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

7.12 vuex 自定义插件

import Vue from 'vue'
import Vuex from 'vuex'
import defalutState from './state/state'
import mutations from './mutations/mutations'
import getters from './getters/getters'
import actions from './actions/actions'

Vue.use(Vuex)
export default () => {
  const store = new Vuex.Store({ // 热更新 的功能
    state: defalutState,
    mutations,
    getters,
    actions,
    plugins: [ // vuex 定义插件
      (store) => {
        console.log(store);
      }
    ]
  })

  if (module.hot) {
    module.hot.accept([
      './state/state',
      './mutations/mutations',
      './getters/getters',
      './actions/actions'
    ], () => {
      // 1.获取更新后的模块
      // 因为 babel6 的模块编译格式问题,这里需要加上.default
      const newState = require('./state/state').default;
      const newMutations = require('./mutations/mutations').default;
      const newGetters = require('./getters/getters').default;
      const newActions = require('./actions/actions').default;
      // 2.加载新模块
      store.hotUpdate({
        state: newState,
        mutations: newMutations,
        getters: newGetters,
        actions: newActions
      })
    })
  }
  return store;
}

7.13 加入 vuex 后,项目的架构

说明:
1:整个 vue 应用其实就是一个节点树,从 root 节点开始,一层一层往下渲染我们的节点;

2:store 是独立的,通过注入到整个组件树,所以,其他各个组件可以通过 $store,获取 store 对象,而组价可以通过 commit 或者 dispatch 触发 store,而真正更改 store 中 state 的数据,是在 store 里面。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容

  • ### store 1. Vue 组件中获得 Vuex 状态 ```js //方式一 全局引入单例类 // 创建一...
    芸豆_6a86阅读 730评论 0 3
  • ### store 1. Vue 组件中获得 Vuex 状态 ```js //方式一 全局引入单例类 // 创建一...
    芸豆_6a86阅读 343评论 0 0
  • vuex 场景重现:一个用户在注册页面注册了手机号码,跳转到登录页面也想拿到这个手机号码,你可以通过vue的组件化...
    sunny519111阅读 8,014评论 4 111
  • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应...
    白水螺丝阅读 4,666评论 7 61
  • 安装 npm npm install vuex --save 在一个模块化的打包系统中,您必须显式地通过Vue.u...
    萧玄辞阅读 2,934评论 0 7