如何在vuex的store中调用vue父组件调用子组件方法

为了账号安全,请及时绑定邮箱和手机
点击这里,将文章分享到自己的动态
vuex 基本入门和使用(二)
vuex 基本入门和使用(二)
vuex 版本为^2.3.1,按照我自己的理解来整理vuex。
关于 state
每个vuex 应用只有一个 store 实例,所以使用起来不会太复杂,对于定位错误状态和操作会很方便。
简单用法:在vuex 的计算属性中返回vuex 的状态
最基本的使用方式,通过在vue文件里面初始化 vuex 的 store 来进行操作 vuex 的数据:如下例子:
// 在组件里面使用 vuex
// 初始化 vuex 实例
const store = new Vuex.Store({
mutations: {
increment: state =& state.count++,
decrement: state =& state.count--
// 创建一个 Counter 组件
const Counter = {
template: `&div&{{ count }}&/div&`,
computed: {
count () {
// 直接返回 state
return store.state.count
// 初始化 vue 实例
const app = new Vue({
el: '#app',
components: { Counter },
template: `
&div class="app"&
&button @click="increment"&+&/button&
&button @click="decrement"&-&/button&
&counter&&/counter&
methods: {
increment () {
store.commit('increment')
decrement () {
store.commit('decrement')
每当 store.state.count 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM。
然而,这种模式导致组件依赖全局状态单例。在模块化的构建系统中,在每个需要使用 state 的组件中需要频繁地导入,并且在测试组件时需要模拟状态。
我以为,当项目发展到多个模块,多个组件和子组件混合的时候,在这种场合,单纯的值传递方式会很麻烦,因为组件或者模块之间的变量是独立的,对于一些全局使用的属性类似 token,cookie 之类的东西,或者是一些多个模块之间共享的属性。
所以 vuex 提供一个新的方式来将 vuex 的 store 存放到根组件下,通过 store 选项,将store从根组件“注入”到每一个子组件中(需调用 Vue.use(Vuex)):
// 初始化 vuex的 store(可以将这个放到其他文件里面去)
const store = new Vuex.Store({
mutations: {
increment: state =& state.count++,
decrement: state =& state.count--
// 在初始化 vue的时候注册 store(store 即是 vuex 的 store)
const app = new Vue({
el: '#app',
// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
components: { Counter }, // 子组件
template: `
&div class="app"&
&counter&&/counter&
通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到。让我们更新下 Counter 的实现:
// 这是子组件 Counter
const Counter = {
template: `&div&{{ count }}&/div&`,
computed: {
count () {
通过this.$store能够访问到 store 并且获取到 state
return this.$store.state.count
通过这种方式可以在实际应用中,将 vuex 的初始化分离出去其他模块化文件,然后在 vue初始化的引用相关 vuex 的文件即可,然后通过this.$store全局调用 vuex 的 store 来实现数据存储。
我整理了一下完整的例子,这是 jsrun的例子:
高级用法:mapState 辅助函数
当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键。(其实就是自动转换了一些语法输出)
import { mapState } from 'vuex'需要先引入才可以使用
mapState使用前后对比:
// 不使用mapState时:
computed: {
count () {
return this.$store.state.count
// 使用mapState时:
computed: mapState({
count: state =& state.count,
如果在大批量的类似这种的计算属性的话,使用 mapState 会更加便捷,而且不只是普通字符串,函数也可以转换,确实是比较方便的。
这里会有一个疑问,mapState到底做了什么事情,怎么将代码转为 vue 能识别的代码?所以需要参考 vuex 源代码中关于mapState的部分:(我找了当前 vuex 版本3.01的源代码:)
这是normalizeMap的代码:
function normalizeMap (map) {
// 判断是否数组,并且最终返回也是一个数组
return Array.isArray(map)
// 是数组就直接 map 循环
? map.map(key =& ({ key, val: key }))
// 是对象就将 key拿出来,然后再进行 map 循环
: Object.keys(map).map(key =& ({ key, val: map[key] }))
这是mapState的代码:
var mapState = normalizeNamespace(function (namespace, states) {
var res = {}; // 这是一个对象类型
// 将 state 通过normalizeMap格式化变成一个数组,数组元素是一个对象
normalizeMap(states).forEach(function (ref) {
var key = ref.// 将数组元素对象解出来,先保存起来被后面使用
var val = ref.
// 组成一个新数组,以 key 为 key,值是一个函数mappedState
res[key] = function mappedState () {
var state = this.$store. // 将本身 vuex 的 store 的 state 和 getters 保存
var getters = this.$store.
// 先不看 namespace 部分
// 这个函数里面会判断真正的值 ref.val 是函数还是普通值
return typeof val === 'function'
? val.call(this, state, getters) // 函数会被直接执行,并且传入 vuex 的state 和 getters
: state[val] // 值会直接放到
vuex 的state 里面
return res
states参数在这里只有2种,一种是对象{},一种是数组[]。因为normalizeMap只做了这2个判断。
states 会先通过normalizeMap进行序列化,转换为一个数组,数组元素是{ key, val: key } 这种结构的。
这里需要注意一下:如果传入的是对象里面只有函数,如下例的countPlusLocalState,那么被 object.keys获取的 key 是函数的名字。
// 例如传入的state 是一个数组,如下:
count: state =& state.count,
// 那么被normalizeMap转换后:
// 即转换为{ key, val: key })
key, // key 是对象{count: state =& state.count}
val: key // val是对象{count: state =& state.count}
//------------------------
// 例如传入的state 是一个对象,如下:
count: state =& state.count,
// 那么被normalizeMap转换后:
// 即被Object.keys(map).map(key =& ({ key, val: map[key] }))处理后
key, // key 是count,因为被Object.keys提取出来
val: map[key] //
val 是state =& state.count,这里以 key 为键找对象的值
normalizeMap(states)格式化之后会使用 forEach 遍历这个数组:
如果 val 是一个函数,则直接调用这个 val 函数,把当前 store 上的 state 和 getters 作为参数,返回值作为 mappedState 的返回值。
否则直接把 this.$store.state[val]作为 mappedState 的返回值。
// 被 foreach 遍历,继续用上面的例子的state来举例,因为不是函数,所以被直接返回:
res["count"] = this.$store.state['state =& state.count']
// 虽然这里是以数组的写法,但是在 js 里面数组的写法也可以用在对象上。
//如果是函数的话,会被执行val.call,并且传入了几个参数(this, this.$store.state, this.$store.getters)
res["countPlusLocalState"] = this.$store.state['state =& state.count']
最终能够形成一个新的数组对象结构,并返回。
因为最终生成的数据就是 computed 的数据格式,所以直接将这个对象传给 computed 就可以直接使用了。
这是mapState经过源代码解析前和后的对比:
// states 为对象时候,mapState转换前
computed: mapState({
count: state =& state.count,
// 传字符串参数 'count' 等同于 `state =& state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
// states 为对象时候,mapState转换后
computed: {
// 直接转换为一般的计算属性的使用方式
return this.$store.state.count
countAlias() {
// 也是转为一般的计算属性的使用方式,只不过有指定名字的会使用中括号括起来
return this.$store.state['count']
countPlusLocalState() {
// 因为是函数,所以会被直接执行,并且传入了当前 store 上的 state 和 getters作为参数
//(但这里没使用 getters)
return this.$store.state.count + this.localCount
组件仍然保有局部状态
使用 Vuex 并不意味着你需要将所有的状态放入 Vuex。虽然将所有的状态放到 Vuex 会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。
关于 getter
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性),就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
// 初始化 getter
const store = new Vuex.Store({
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
getters: { // 这就是 getters
doneTodos: state =& {
return state.todos.filter(todo =& todo.done)
// 使用getter
store.getters.doneTodos // -& [{ id: 1, text: '...', done: true }]
// 或者可以this.$store.getters.xxxx 这样使用。
// 可以在第二个参数里面传一个 getter 作为参数
getters: {
doneTodosCount: (state, getters) =& {
// 传入了之前设置的doneTodos的 getters,所以直接使用了doneTodos
return getters.doneTodos.length
store.getters.doneTodosCount // -& 1
// 让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组进行查询时非常有用。
getters: {
getTodoById: (state) =& (id) =& { // 返回一个函数
return state.todos.find(todo =& todo.id === id)
// 对返回的函数传入参数来使用
store.getters.getTodoById(2) // -& { id: 2, text: '...', done: false }
mapGetters 辅助函数
mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
参考 vuex 源代码,类似的处理也是跟...mapState类似:
export function mapGetters(getters) {
const res = {}
// 先格式化,然后再处理
normalizeMap(getters).forEach(({key, val}) =& {
res[key] = function mappedGetter() {
if (!(val in this.$store.getters)) {
console.error(`[vuex] unknown getter: ${val}`)
return this.$store.getters[val]
return res
相比 mapState 来说,他简单一点。
唯一的区别就是它的 val 不能是函数,只能是一个字符串,而且会检查 val in this.$store.getters的值,如果为 false 会输出一条错误日志。
关于三个点...mapstate 处理
其实三个点就是es6的扩展运算符。
可以将一个数组转为用逗号分隔的参数序列,也可以将,如果应用到 mapstate 身上就是:
需要注意:vue的 computed 是对象,里面的属性是对象属性。
computed: {
// 一般 computed 对象属性
now: function () {
return Date.now()
// 使用对象展开运算符将此对象混入到外部对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// 转换后是这样,跟一般 computed 对象属性差不多
doneTodosCount:function(){},
anotherGetter:function(){}
这篇文章描述更为清楚,可以先看这篇:
本文原创发布于慕课网 ,转载请注明出处,谢谢合作
若觉得本文不错,就分享一下吧!
评论加载中...
相关文章推荐
正在加载中
Web前端工程师
作者相关文章Vuex 组件之间的数据传递
时间: 19:17:57
&&&& 阅读:1454
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&在 Vue.js 的项目中,如果项目结构简单, 父子组件之间的数据传递可以使用& props 或者 $emit 等方式
但是如果是大型项目,很多时候都需要在子组件之间传递数据,使用之前的方式就不太方便。Vue 的状态管理工具
完美的解决了这个问题。
一、安装并引入 Vuex
项目结构:
首先使用 npm 安装 Vuex
cnpm install vuex -S
然后在 main.js 中引入
import Vue from ‘vue‘
import App from ‘./App‘
import Vuex from ‘vuex‘
import store from ‘./vuex/store‘
Vue.use(Vuex)
/* eslint-disable no-new */new Vue({
el: ‘#app‘,
render: h =& h(App)
二、构建核心仓库 store.js
Vuex 应用的状态 state 都应当存放在 store.js 里面,Vue 组件可以从 store.js 里面获取状态,可以把 store 通俗的理解为一个全局变量的仓库。
但是和单纯的全局变量又有一些区别,主要体现在当 store 中的状态发生改变时,相应的 vue 组件也会得到高效更新。
在 src 目录下创建一个 vuex 目录,将 store.js 放到 vuex 目录下
import Vue from ‘vue‘
import Vuex from ‘vuex‘
Vue.use(Vuex)
const store = new Vuex.Store({
// 定义状态
author: ‘Wise Wrong‘
export default store
这是一个最简单的 store.js,里面只存放一个状态 author
虽然在 main.js 中已经引入了 Vue 和 Vuex,但是这里还得再引入一次
三、将状态映射到组件
&template&
&footer class="footer"&
&li v-for="lis in ul"&{{lis.li}}&/li&
Copyright&&&{{author}} - 2016 All rights reserved
&/template&
export default {
name: ‘footerDiv‘,
{ li: ‘琉璃之金‘ },
{ li: ‘朦胧之森‘ },
{ li: ‘缥缈之滔‘ },
{ li: ‘逍遥之火‘ },
{ li: ‘璀璨之沙‘ }
computed: {
author () {
return this.$store.state.author
这是 footer.vue 的 html 和 script 部分
主要在 computed 中,将 this.$store.state.author 的值返回给 html 中的 author
页面渲染之后,就能获取到 author 的值
四、在组件中修改状态
然后在 header.vue 中添加一个输入框,将输入框的值传给 store.js 中的 author
这里我使用了 Element-UI 作为样式框架
上面将输入框 input 的值绑定为 inputTxt,然后在后面的按钮 button 上绑定 click 事件,触发 setAuthor 方法
methods: {
 setAuthor: function () {
   this.$store.state.author = this.inpuTxt
在 setAuthor 方法中,将输入框的值 inputTxt 赋给 Vuex 中的状态 author,从而实现子组件之间的数据传递
五、官方推荐的修改状态的方式
上面的示例是在 setAuthor 直接使用赋值的方式修改状态 author,但是 vue 官方推荐使用下面的方法:
首先在 store.js 中定义一个方法 newAuthor,其中第一个参数 state 就是 $store.state,第二个参数 msg 需要另外传入
然后修改 header.vue 中的 setAuthor 方法
这里使用 $store.commit 提交 newAuthor,并将 this.inputTxt 传给 msg,从而修改 author
这样显式地提交(commit) mutations,可以让我们更好的跟踪每一个状态的变化,所以在大型项目中,更推荐使用第二种方法。标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:http://www.cnblogs.com/cpqwebfe/p/7019541.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!当前位置:
(javascript)关于vuex,已知的是在组件中调用 dispatch 方法,返回值是 undefined,不知是哪里出了问题
猜你喜欢的文章
(javascript)关于vuex,已知的是在组件中调用 dispatch 方法,返回值是 undefined,不知是哪里出了问题(2/2)
来源:网络整理&&&&&时间: 23:23:10&&&&&关键词:
关于网友提出的“ (javascript)关于vuex,已知的是在组件中调用 dispatch 方法,返回值是 undefined,不知是哪里出了问题”问题疑问,本网通过在网上对“ (javascript)关于vuex,已知的是在组件中调用 dispatch 方法,返回值是 undefined,不知是哪里出了问题”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:
问题: (javascript)关于vuex,已知的是在组件中调用 dispatch 方法,返回值是 undefined,不知是哪里出了问题
computed: {
...mapGetters([
'getTabGrade'
created() {
this.$store.dispatch('getTabGrade')
.then(res =& {
console.log(res) // undefined
return res
.catch(err =& {
console.log(err)
},各个模块的引用应该是没有问题得,毕竟组件内可以通过 this.$store 来访问 state但是不知道为何 dispatch 会返回 undefined组件内可以获得正确的数据的,请问我该如何去使用,就像通过{{}}来展示一个grade1_name解决方案1:已解决,我最后在模块的getter中做了一下处理:const getters = {
getTabGrade: state =& {
console.log('getter',state.tabGrade)
let tabGradeName = []
for(var i =0; i&state.tabGrade.list. i++){
tabGradeName.push(state.tabGrade.list[i].grade1_name)
return tabGradeName
}最终组件中使用模板语法将计算属性写了上去,html:&span&{{getTabGrade[0]}}&/span&
computed: {
...mapGetters([
'getTabGrade'
])解决方案2:加了return和resolve,不然this.$store.dispatch('getTabGrade')触发调用可能没有返回带有正确值的promise,你试试看。const actions = {
// 调用api
getTabGrade({ commit }) {
console.log('actions')
return baseApi.findGrade1()
//添加return
.then(res =& {
commit(types.GET_TABGRADE, res)
resolve(res);
//添加resolve
}).catch(err =& {
console.log(err)
以上介绍了“ (javascript)关于vuex,已知的是在组件中调用 dispatch 方法,返回值是 undefined,不知是哪里出了问题”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/.html
上一篇: 下一篇:404 Not Found
The requested URL /q/5855/ was not found on this server.Vuex在组件中使用或者重命名状态
Vuex 入门的文章都是照着文档来个最简单的例子而已,至于核心概念中的 Mutations 和 State 也就给个简单的实例说明一下怎么去用。在 Vuex 状态管理中, mapState 和 mapMutations 辅助函数对于在组件里面重命名状态和状态变更函数有很大的帮助。一、最直接的使用方式一般来说,最直接的使用方法就是直接在组件中将状态注入到每一个组件中这样子就能够直接使用
$store.state.count 进行使用PS:(如果不知道为什么用 $store.state.count ,应该先看看文档 )const app = new Vue({
el: '#app',
// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
})因此,如果需要 template 中不直接使用 {{$srore.state.count}} 的做法中可以这么使用:data(){
// 进行组件注入后,就可以直接使用 this.$store 调用 vuex 的状态实例
newCount:this.$store.state.count
}二、使用 mapState 和 mapMutations 辅助函数使用 mapState 和 mapMutations 的前提是要引入:
import store from '@/vuex/store';
import {mapState , mapMutations } from 'vuex'一般来说我们都是避免直接使用 $store.state.count 或者是 $store.mutations.add因此在组件中,methods 把状态变更的函数进行重命名:// 这种方法是最简单的,但是缺点就是映射出来的 count() 方法 名称必须和 mutations 中的函数一样
// computed:mapState(['count']),
// 下面是集中不同的方式 一种是直接使用state,然后通过state的参数进行使用
// 在这个过程中,是可以使用this.num 来操作
computed:mapState({
count(state){
return state.count + this.num
countPlusLocalState(state){
return state.count + this.num
count2:'count'
// 在使用mapmutations的时候,如果只是重命名,则直接下面的方式即可,即使需要传递参数
// 比如我在 store 中的 mutations里面定义的add函数是
add(state,num){return state.count + num}
// 我重命名之后
newAdd 在使用的时候 还是直接传参即可
&button @click=&newAdd(10)&&&/button&
methods:mapMutations({
newAdd:'add',
newReduce:'reduce'
}),如果需要对状态变更方法或者某个状态进行重命名,则使用 mapState 和 mapMutations 是最简单的方案。三 完整示例vuex/store.js/**
* Created by Postbird on .
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const state={
const mutations={
add(state,n){
state.count+=n;
reduce:function (state) {
state.count--;
export default new Vuex.Store({
组件&template&
&h2&{{message}}&/h2&
&h3&【 {{count}} 】- 【 {{newCount}} 】 - 【 {{countPlusLocalState}} 】 - 【 {{count2}} 】&/h3&
&button @click=&newAdd(10)&&+&/button&
&button @click=&newReduce&&-&/button&
&/template&
import store from '@/vuex/store';
import {mapState , mapMutations } from 'vuex'
export default{
name:'Count',
message:'使用vuex计算Count',
newCount:this.$store.state.count,
// computed:mapState(['count']),
computed:mapState({
count(state){
return state.count + this.num
countPlusLocalState(state){
return state.count + this.num
count2:'count'
methods:mapMutations({
newAdd:'add',
newReduce:'reduce'
四、展开运算符ES6里面的展开运算符能够更好的辅助去操作.比如除了 mapGetters / mapMutations 之外还有组件内部的 computed 其他操作,就可以使用展开运算符。 // computed:mapState(['count']),
computed:{
...mapState({
count(state){
return state.count + this.num
countPlusLocalState(state){
return state.count + this.num
count2:'count',
...mapGetters({
count3:'count',
newMessage:function(){
return this.message.toUpperCase();
文章版权:
本文链接:
转载请注明文章原始出处 !
扫描二维码,在手机阅读!
添加新评论

我要回帖

更多关于 vuex调用组件方法 的文章

 

随机推荐