在使用vuex中的一些问题

前提,这是一篇笔记,

在使用vue脚手架构建项目后,第一个想到的就是它了——vuex,用来处理非常恶心的组件传值功能,新建的项目还不算是很大,但是一层又一层的组件关系犹如一团乱麻,在vm/vc上不停得找节点也无济于事,后来干脆用vuex来代理。但是不怎么使用的技能又在使用中出了一些问题,所以,写一篇博客来记录相关问题和方法:

这里忽略一些基础配置(路由啊,vuex等的下载问题,一般来说较于vue2版本,只要不装太高版本的插件基本都能用,具体步骤推荐去官网看文档直接复制)

首先就是传值问题:

1. 父子间传值(父组件与子组件)

父传子:使用props:

//子组件内容
<template>
  <div id="app">
    <div>姓名:{{ name }}</div>
    <div>年龄:{{ age }}</div>
  </div>
</template>
<script>
export default {
  props: ["name", "age"],
};
</script>
<template>
    <son1 :name="newname" :age="newage" @son1data="getdata"></son1>
</template>
<script>
export default {
    data(){
       return {
          newname:'李雷',
          newage:15
}
    }
}
</script>

 原理就是通过props设置,绑定父级组件上的两个属性作为子组件的属性进行使用,但是尝试修改后会报错,因此需要使用中间键过渡一下

//子组件
data(){
    return {
    myname:this.name
}
}

子传父:

//子组件
<template>
  <div id="app">
    <div>姓名:{{ name }}</div>
    <div>年龄:{{ age }}</div>
    <div>姓名1:{{ myname }}</div>
    <div>年龄1:{{ myage }}</div>
    <button @click="son1emit">点击发送数据</button>
  </div>
</template>
export default {
  data() {
    return {
      myname: "李四",
      myage: 23,
    };
  },
  props: ["name", "age"],
  methods: {
    son1emit() {
      this.$emit("son1data", { name: this.myname, age: this.myage });
    },
  },
};
</script>
//父组件
//模板
<son1 :name="newname" :age="newage" @son1data="getdata"></son1>
//方法
methods: {
    getdata(val) {
      this.son1_name = val.name;
      this.son1_age = val.age;
    }
  },
//属性
data() {
    return {
      newname: "张三",
      newage: 22,
      son1_name: "",
      son1_age: "",
    };
  },

 该方法原理是通过子组件的$emit,将第二个参数的值传出去,再由父组件的$on事件进行监听,从而获取相关数据。

另外可用的方法还有vc身上的$children,$parent属性,一直点就好了。

祖传孙(中间层断开):

 //provide选项可以定义数据给其他后代组件使用
  provide() {
    return {
      address: this.address,
    };
  },
data() {
    return {
      address: "南京雨花台",
    };
  },

 上面是祖组件的导出内容,下面是孙组件的内容:

<template>
  <div>
    <p>地址:{{ myaddress }}</p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      myaddress: this.address,
    };
  },
  //通过注入的方式拿到主组件的数据
  inject: ["address"],
};
</script>

兄弟组件之间的传值:

//在main.js中往vue的原型上添加一条自定义属性
Vue.prototype.$bus = new Vue()
<template>
  <div class="son3">
    车名:{{ carname }} -- 车价:{{ carprice }} --
    <button @click="pemit">点击发送数据</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      carname: "保时捷",
      carprice: "80W",
    };
  },
  methods: {
    pemit() {
      this.$bus.$emit("cardata", {
        carname: this.carname,
        carprice: this.carprice,
      });
    },
  },
};
</script>
//同时在两个兄弟组件中调用这个原型属性,一个传值,一个接收值
<template>
  <div class="son4">carname: {{ carname4 }} -- carprice:{{ carprice4 }}</div>
</template>

<script>
export default {
  data() {
    return {
      carname4: "",
      carprice4: "",
    };
  },
  mounted() {
    //这里用方法时this指向会发生改变,尝试修改this指向
    let that = this;
    this.$bus.$on("cardata", function (e) {
      that.carname4 = e.carname;
      that.carprice4 = e.carprice;
    });
  },
};
</script>

 因为组件一旦切换,this就会发生变化,所以为了this的指向同一,所以在原型上做做手脚,同理可以将axios设置在原型上,就不用一直引入调用了。

vuex:

首先,如上,具体安装导入推荐去官网看API,里面有详细的内容可以复制,vue2就别装vuex3以上的版本了,防止报错。

基本的5个钩子:

state:状态,通俗的讲就是数据的掌管,你可以放所有你想要在全局使用的数据,后面直接调用即可,调用方法:$store.state.value.key,后面value.key就是存在state里的数据内容,

getters:相当于计算属性computed钩子:里面用于存放计算相关的数据使用,方法类似计算属性,通过形参state拿到全局状态state并计算返回

mutations:定义操作状态的方法,用于接收commit传来的方法名和值的并单纯地进行赋值操作,比如:

//子组件
methods:{
   send(){
     this.$store.commit('changename','王二蛋')
}
}
//vuex里面的store里面的index.js
mutations:{
changename(state,val){
    state.name = val
}

 官方推荐mutations里面最好只做一些简单的赋值操作,不要有太多计算相关的内容,所以这里按照官方来,

actions: 就是一系列动作,刚刚上文描述的关于解决传值后要经过计算,值才能被使用的问题,在组件中由组件发出dispatch请求后,actions里设置监听事件,在actions里对数据进行处理(计算啊,异步请求啊啥的),然后再由actions发出commit,由mutations监听,这就是官方推荐的一系列流程,就像:

//组件
methods:{
    send(){
    this.$store.dispatch("updataname", "lisa");
    }
}

//actions
    updataname(context,val){
    setTimeOut(()=>{
        context.commit('updatatname', val)
    },1000)
}

//mutations
 updataname(state, val) {
      state.name = val
    },


//最后这个val就是我们传过来的lisa了!

 ,最后还有个modules:是用来管理分支模块的,一个主模块下可能会有几十上百条state甚至更多,用起来极不方便,为此,可以单独的将某些用法功能相似的内容打包作为index.js的模块分离出去,使用方法大致相同:分离出去的模块结构一致,也有state getters mutations actions modules这5块,内容用法和index.js大致相同:

避坑点:

分离出去的模块在使用的时候,其state下的内容会被打包成一个以模块名为名的对象,因此在调用该模块下的state数据时需按名使用

//比如现在store下有一个主代理index.js和一个代理模块hotel.js
//第一步,在index.js里导入hotel,js
export default{
import hotel from './hotel.js';
//...
modules:{
hotel,
}

//第二步,在hotel.js模块里写入一份数据
...
state:{
name:'张三'
...
}

//第三步,在组件中使用这份数据

<div>
{{$store.state.hotel.name}}
</div>

其次就是,模块代理后会将所有模块(包括主代理和各个模块代理)的commit和dispatch事件都会合并在一起,因此,在为这些事件起名的时候最好不要起重复的名,当整个项目中有重名事件后,将会抛出错误,因此,起名需谨慎(可以尝试死亡数组递增命名,事件a,事件b,事件c...),另外一个就是在监听这些事件时,需要在事件名前加上组件名/

比如我有个组件代理叫hotel(迷hotel),那么我在commit或dispatch的时候第一个参数就是 

“ hotel/updataname ",依次类推。


好了,总结一下,

组件间传值:

父传子:props,

子传父:$emit ,

祖传孙:provide==>inject,

孙传祖:$parent,或者provide里传递一个方法(function),直接传递,

兄弟间互传:设置中间键或给Vue原型上加公共属性,

什么是VUEX

Vuex的相关钩子,

Vuex的模块化代理,

一些Vuex模块化代理的误区

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值