Vuex仓库模块化数据共享,父传子,子传父,$emit

目录

1.vue基础写法

 2.vuex基础用法

 3.vuex的简写

4.vuex模块化

5.父传子

6.子传父

7.$emit


1.vue基础写法

<template>
  <div class="hello">
    <h1>计算</h1>
    <h3>和为:{
   
   { num }}</h3>
    <select name="1" id="" v-model.number="n">
      <!-- 加上冒号可以转为解析隐私转换为数字类型 或 事件修饰符number -->
      <option :value="1">1</option>
      <option :value="2">2</option>
      <option :value="3">3</option>
    </select>
    <button @click="jian">-</button>
    <button @click="jia">+</button>
    <button @click="odd">和为奇数才加</button>
    <button @click="wait">一秒之后加</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {},
  data() {
    return {
      // 使用了v-model 下拉框的默认值不生效,要自己设置不能为0
      n: 1,
      num: 0,
    };
  },
  methods: {
    jia() {
      this.num += this.n;
    },
    jian() {
      this.num -= this.n;
    },
    odd() {
      if (this.num % 2 != 0) {
        this.num += this.n;
      }
    },
    wait() {
      setTimeout(() => {
        this.num += this.n;
      }, 1000);
    },
  },
};
</script>

 2.vuex基础用法

1.读取数据 this.$store.state.属性名

2.操作数据 this.$store.dispacth("actions的方法名‘,参数)

          或者 this.$store.commit("mutations的方法名",参数)

1.要从其他服务器拿数据要经过actions里面的方法发送请求处理数据之后调用mutations的方法

2.如果不用拿其他服务器的数据可以直接commit调用mutations里面的方法

<template>
  <div class="hello">
    <h1>计算</h1>
    <!-- 使用 $store.state.num 获取state的数据 这里不用this.是因为{
   
   {}}会全局去找这个属性 -->
    <h3>和为:{
   
   { $store.state.num }}</h3>
    <!-- $store.getters.方法名  把计算属性的方法当变量使用 -->
    <h3>和的十倍为:{
   
   { $store.getters.sum }}</h3>
    <select name="1" id="" v-model.number="n">
      <!-- 加上冒号可以转为解析隐私转换为数字类型 或 事件修饰符number -->
      <option :value="1">1</option>
      <option :value="2">2</option>
      <option :value="3">3</option>
    </select>
    <button @click="jian">-</button>
    <button @click="jia">+</button>
    <button @click="jiaodd">和odd为奇数才加</button>
    <button @click="jiawait">一秒之后加</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {},
  data() {
    return {
      // 使用了v-model 下拉框的默认值不生效,要自己设置不能为0
      n: 1,
      num: 0,
    };
  },
  methods: {
    jia() {
      // this.num += this.n;
      // dispatch 调用actions的方法和传递参数
      // this.$store.dispatch("jia", this.n);
      // commit直接联系mutations的计算属性
      this.$store.commit("JIA", this.n);
    },
    jian() {
      // this.num -= this.n;
      // 调用actions的方法
      // this.$store.dispatch("jian", this.n);
      // 调用mutations的方法
      this.$store.commit("JIAN", this.n);
    },
    jiaodd() {
      // if (this.num % 2 != 0) {
      //   this.num += this.n;
      // }
      // 使用 this.$store.state.num 获取state的数据
      // if (this.$store.state.num % 2 != 0) {
      //   this.$store.dispatch("jia", this.n);
      // }
      this.$store.dispatch("jiaodd", this.n);
    },
    jiawait() {
      // setTimeout(() => {
      //   // this.num += this.n;
      //   this.$store.dispatch("jia", this.n);
      // }, 1000);
      this.$store.dispatch("jiawait", this.n);
    },
  },
};
</script>

在vuex文件夹里写

import Vue from "vue";
import Vuex from "vuex";
//使用vuex插件
Vue.use(Vuex);

export default new Vuex.Store({
  // 数据
  state: {
    num: 0,
  },
  // 计算属性
  getters: {
    sum(state) {
      // 必须使用return 把方法名当变量使用
      return state.num*10
    }
  },
  // 响应组件的动作 响应其他服务器
  actions: {
    // jia(context, val) {
    //   context.commit("JIA", val);
    // },
    // jian(context, val) {
    //   context.commit("JIAN", val);
    // },
    jiaodd(context, val) {
      if (context.state.num % 2 != 0) {
        context.commit("JIA", val);
      }
      // 其他的处理程序
      // context.dispatch("demo1",val)
    },
    // demo1(context, val) {
    //   console.log("处理程序1");
    //   context.dispatch("demo2", val);
    // },
    // demo2(context, val) {
    //    console.log("处理程序2");
    //   // context.dispatch("demo3", val);
    // },
    jiawait(context, val) {
      setTimeout(() => {
        context.commit("JIA", val);
      }, 1000);
    },
  },
  // 方法 开发者工具捕获这里的变化
  mutations: {
    JIA(state, val) {
      state.num += val;
    },
    JIAN(state, val) {
      state.num -= val;
    },
  },
});

如果你同一个事件要处理多步程序可以分开连续触发(同步执行)

 

 3.vuex的简写

属性和方法的简写

1.建议使用数组写法当前页面的方法名和state里面的属性名相同可以省略为一个值

 2.对象写法当前页面的方法名和state里面的属性名相同不能省略为一个值

自动引入 

import { mapActions, mapGetters, mapMutations, mapState } from "vuex";

计算属性 

computed: {
    // num() {
    //   return this.$store.state.num;
    // },
    // sum() {
    //   return this.$store.getters.sum;
    // },
    // name() {
    //   return this.$store.state.name;
    // },
    // age() {
    //   return this.$store.state.age;
    // },
    // gender() {
    //   return this.$store.state.gender;
    // },
    // 简写
    // 在state里面找该属性名 当前页面使用的方法名:"state的属性名"  相同的方法名和属性名不能简写为一个name
    // 对象写法
    // ...mapState({num:"num" ,name: "name", age: "age", gender: "gender" })
    // 数组写法
    ...mapState(["num", "name", "age", "gender"]),
    // 在getters里面找方法名
    // ...mapGetters({ sum: "sum" }),
    ...mapGetters( ["sum"] ),
  },
// 数据
  state: {
    num: 0,
    name: "小白",
    age: 18,
    gender:"女"
  },
  // 计算属性
  getters: {
    sum(state) {
      // 必须使用return 把方法名当变量使用
      return state.num*10
    }
  },
 <h2>{
   
   { name }}是个{
   
   { age }}岁的小{
   
   { gender }}孩</h2>

 写方法methods里面

注意设置(参数)不设置参数 默认参数是event 会报错!!!

    <button @click="jian(n)">-</button>
    <button @click="jia(n)">+</button>
    <button @click="jiaodd(n)">和odd为奇数才加</button>
    <button @click="jiawait(n)">一秒之后加</button>

 mutations

// 对象 当前页面方法名:mutations的方法名 默认参数event 在调用方法的时候要主动传参(n)
    ...mapMutations({ jia: "JIA", jian: "JIAN" }),
    // 数组 这边方法名和那边的方法名相同数组才可以这样简写
    // ...mapMutations(["JIA", "JIAN"]),

actions 

// 对象
    // ...mapActions({ jiaodd: "jiaodd", jiawait: "jiawait" }),
    // 数组
    ...mapActions(["jiaodd", "jiawait"]),

4.vuex模块化

给不同的数据类型做分类,方便管理数据

再多加一个列表组件

<template>
  <div class="about">
    <h1>人员列表</h1>
    <h3 style="color:pink">计算求和为:{
   
   { num }}</h3>
    <input type="text" placeholder="请输入要添加的名字" v-model="val" />
    <button @click="add(val)">添加</button>
    <ul>
      <li v-for="(item, index) in preson" :key="index">{
   
   { item }}</li>
    </ul>
  </div>
</template>
<script>
import { mapState,mapMutations } from "vuex";

export default {
  data() {
    return {
      val: "",
    };
  },
  methods: {
    // add(val) {
    //   this.$store.commit("ADD", val);
    //   this.val = "";
    // },
    ...mapMutations({add:'ADD'}),
  },
  computed: {
    // num() {
    //   return this.$store.state.num
    // },
    // preson() {
    //   return this.$store.state.preson
    // },
    ...mapState(["num", "preson"]),
  },
};
</script>

两边数据有共用的地方,都在一个地方拿

 state: {
    num: 0,
    name: "小白",
    age: 18,
    gender: "女",
    preson:["小白","小黑"]
  },
...mapState(["num", "name", "age", "gender", "preson"]),

所有数据混合在一起不方便管理,进行区分类型模块化

核心:使用命名空间  不然使用的时候要 .那个分类

 namespaced: true
import Vue from "vue";
import Vuex from "vuex";
import numder from "./numder.js"
import preson from "./preson.js";
//使用vuex插件
Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
 // 命名
    numder,
    preson,
  },
});

分类创建文件夹 引入到同一个文件夹 使用命名空间区分 

 

方法   ...mapGetters('命名',["sum"]),

// 模块化命名区分
    ...mapState("numder", ["num", "name", "age", "gender", "preson"]),
    ...mapState("preson", ["preson"]),
    // 在getters里面找方法名
    // ...mapGetters({ sum: "sum" }),
    ...mapGetters('numder',["sum"]),
...mapMutations('numder',{ jia: "JIA", jian: "JIAN" }),
...mapActions('numder',["jiaodd", "jiawait"]),

自己创建方法的写法 命名/方法

methods: {
    add(val) {
      this.$store.commit("preson/ADD", val);
      this.val = "";
    },

5.父传子

1.在父组件data中定义一个数据 a:10

2.在父组件的子组件标签上定义一个自定义属性传入父组件的数据  :a1="a"

3.在子组件的props中接收属性 props["a1"]

4.在子组件中使用这个属性相当于data里面的属性值使用 { {a1}}

5.可以在接收的时候定义数据类型和初始值

props:{

        a1:{

             type:Number,

             default:100

           }

}

6.子传父

1.在父组件的methods里面定义一个方法 fun(){ console.log("父组件的方法")}

2.在父组件的子组件标签上定义一个自定义事件,把定义的方法绑定在这个事件上

<com @k="fun"/>

3.在子组件里面创建一个需要的事件@click="fun2"

4.在子组件的方法里面使用

fun2(){

   this.$emit("k",参数,参数2)

}

5.在父组件的fun(){}方法里面接收参数处理数据,实现通过子组件触发父组件的方法

总结:

1.数据在多个组件中使用就放在vuex仓库里面注意分类存放,

2.数据只在当前组件使用就直接在当前组件中存储数据,

3.子组件需要父组件的数据就使用父传子,

4.父组件需要子组件的数据就使用子传父,

5.子组件与子组件需要共享数据就放在vuex仓库

7.$emit

通过自定义事件传递参数给其他组件

1.创建一个bus.js文件夹

//内容:

import Vue from "vue"

export default new Vue()

 2.在要传递的组件使用$emit自定义事件传值

//引入

import bus from "@/components/bus.js";

//通过事件触发使用

<button @click="send">传值给c组件</button>

methods: {

    send() {

      bus.$emit("sendarr", this.arr);

    },

  },

 3.在需要接收数据的组件监听自定义事件接收参数

created() {

    // 监听sendarr自定义事件

    bus.$on("sendarr", (data) => {

      console.log(data);

      this.arr = data;

    });

  },

 

 4.通过触发事件直接传值到c组件

 

 

 5.想在那个组件使用数据就在那个组件监听那个自定义事件就可以了

猜你喜欢

转载自blog.csdn.net/weixin_70563937/article/details/126671728