vue 父子,子父,兄弟,vuex传值

577 阅读2分钟

父子组件传值

父传子的实现方式就是通过props属性,子组件通过props属性接收从父组件传过来的值 通过props传值,接收时规定传来的变量的数据类型(type)和默认值(default)以及是否必填(require)

父组件,可以在引用子组件的时候, 通过 属性绑定(v-bind:) 的形式, 把 需要传递给 子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用

注意:经过演示,发现,子组件中,默认无法访问到 父组件中的 data 上的数据 和 methods 中的方法。

子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的,比如: 子组件通过 Ajax ,请求回来的数据,都可以放到 data 身上,data 上的数据,都是可读可写的。

组件中的 所有 props 中的数据,都是通过 父组件传递给子组件的

props 中的数据,都是只读的,无法重新赋值

父组件

<template>
 <div>
   <Son :fatherlist="list"></Son>
   <!-- 传给子组件数据 -->
 </div>
</template>
<script>
import Son from "../son/index.vue"; //引入子组件    引入进来的组件都属于子组件
export default {
 data() {
   return {
     list: [
       {
         name: "李四",
         age: "15",
         id: 1,
       },
       {
         name: "张三",
         age: "120",
         id: 2,
       },
     ],
   };
 },
 components: {
   //注册子组件
   Son,
 },
};
</script>

子组件

<template>
 <div class="hello">
   <ul>
     <li v-for="item in fatherlist" :key="item.id">
       <span>{{ item.name }}</span>
       <span>{{ item.age }}</span>
     </li>
   </ul>
 
 </div>
</template>
 <script>
export default {
 data() {
   return {
     name: "",
   };
 },
 //props接受父组件数据
 props: {
   fatherlist: {
     type: Array, //接收过来的数据给他一个类型
   },
 },
};
</script>

子父组件传值

首先,我们需要明确的是,子父组件之间通讯,子组件是不能直接改变父组件的值的。(父组件是大佬,小弟不能改变大佬的值,但是父组件可以改变子组件的

子组件向父组件传值:父组件向子组件传递方法的同时,把要发送给父组件的数据,在调用方法的时候当作参数传递进去; 在子组件的标签上自定义一个事件,通过this.$emit()传递,有俩个参数,第一个参数是定义的方法,第二个参数是要传给父亲的值,然后在父组件中通过事件接收。

注意:子组件向父组件传值时,父组件中@toAdd="add"中,方法名不要加括号!!!!@toAdd="add()"

子组件

<template>
  <div class="hello">
    <ul>
      <li v-for="item in fatherlist" :key="item.id">
        <span>{{ item.name }}</span>
        <span>{{ item.age }}</span>
      </li>
    </ul>
    <input type="text" v-model="name" />
    <button @click="add">添加到子组件里面</button>
  </div>
</template>
  <script>
export default {
  data() {
    return {
      name: "",
    };
  },
  //接收子组件
  props: {
    fatherlist: {
      type: Array, //接收过来的数据给他一个类型
    },
  },
  //子传父方法
  methods: {
    // 一个add的方法
    add() {
      //子传父通过$emit  toAdd是传给子组件的方法,this.name是传给父组件的数据
      this.$emit("toAdd", this.name);
    },
  },
};
</script>

父组件

<template>
  <div>
    <!-- 父组件接受子组件 toAdd事件不能带括号()-->
    <div></div>
    <Son :fatherlist="list" @toAdd="add"></Son>
    
    <!-- 传给子组件数据 -->
  </div>
</template>
  <script>
import Son from "../../components/son/index.vue"; //引入子组件    引入进来的组件都属于子组件
export default {
  data() {
    return {
      list: [
        {
          name: "李四",
          age: "15",
          id: 1,
        },
        {
          name: "张三",
          age: "120",
          id: 2,
        },
      ],
    };
  },
  components: {
    //注册子组件
    Son,
  },
  methods: {
    // add这个事件就可以获取到从子组件穿过来的name数据
    add(name) {
      this.list.push({
        name,
      });
    },
  },
};
</script>

兄弟组件传参

可以说是中间介

bus.js文件

import Vue from 'vue'
const bus = new Vue()
export default bus

兄弟1


<template>
  <div>
    <div>
      <h3>a组件:{{ age }}</h3>
      <button @click="sendData">将数组发送给b组件</button>
    </div>
  </div>
</template>
  
    <script>
import bus from "../../views/utils/bus";
export default {
  data() {
    return {
      age: 20,
    };
  },

  methods: {
    sendData() {
      bus.$emit("sendAge", this.age);
    },
  },
};
</script>

兄弟2

<template>
  <div>
    <div>
      <h3>b组件:{{ ages }}</h3>
    </div>
  </div>
</template>
    <script>
import bus from "../../views/utils/bus";
export default {
  data() {
    return {
      ages: "",
    };
  },
  watch: {
    ages: {},
  },
  mounted() {
    bus.$on("sendAge", (e) => {
      console.log(e);
      this.ages = e;
    });
  },
};
</script>

vuex传参

含义:vuex是一个应用程序开发的状态管理+库 他采用了集中式存储管理应用的所有组件的状态(数据)以相应的规则保证状态以一种可预测的方式发生变化也就是说vuex时实现组件全局炸uu哪个台(数据)管理的一种机制,可以方便的事件组件之间的数据的共享

什么时候用vuex

  1. 能够在vuex中集中管理共享的数据,易于开发和后期维护
  2. 能够高效的实现组件之间的数据共享,提高开发效率
  3. 存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步

什么数据适合存储到vuex中

一般情况下只有组件之间的共享的数据,才有必要方法在vuex中,对于组件中的数据还是存放在组件自身的data中就可以

注意: 如果使用辅助函数

  • state.getter必须在computed里面使用
  • mutation,actions必须在methods中使用

store.js文件

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

Vue.use(Vuex)

export default new Vuex.Store({
  //唯一的公共数据源,所有共享的数据统一放在state里面存储类似data
  //在vuex中state中定义的数据可以在任何组件里面使用
  // 存储数据
  state: {
    name: '柯基',
    age: '10',
    count: 0,
    arr: ['one', 'two', 'there']
  },
  //过滤state中的数据
  // 类似于vue中的commputed的属性 计算缓存,对于store的数据进行加工处理形成新的数据
  getters: {
    filterArr(state) {
      return state.arr.filter(item => item.includes("o"))
      // 过滤数据查找数据中包含o的数据
    }
  },
  //更改vuex中store中的状态唯一的方法就是提交mutations只能修改同步的代码
  // mutations事件:每个mustation都有一个字符串的事件类型和一个回调函数
  //这个回调函数就是我们实际进行状态更改的地方,并且他会接受state作为第一个参数必须接受一个state数据


  // 注意是commit触发mutation操作
  // 也就是想使用mutaion,就需要commit来触发mutaion的操作
  //同步在mutation里面使用


  mutations: {
    // 把state中的count加加
    // 第一种方法没有使用mapMutations辅助函数
    // addCount(state, num) {
    //   state.count += num
    // },
    // jjCount(state) {
    //   state.count--
    // },


    // 第二种方法
    // addCounts(state, num) {
    //   state.count += num
    // },
    // jjCounts(state) {
    //   state.count--
    // },


    // 使用actions   
    addcountA(state, num) {
      // 这里的um就是actions里面的一个方法传过来的参数
      state.count += num
    },
    addcountB(state) {
      // 这里的um就是actions里面的一个方法传过来的参数
      state.count--
    }
  },
  // 进行异步操作
  // action里面不能直接获取state里面的数据
  // 其实就是把异步的方法提交给mutation  

  //使用actions 写一个方法asyncAdd  在这个方法里面在提交一个方法(addcountA)给mutations 
  // 组件里面使用actions里面的方法就需要this.$store.dispatch(第一个参数时调用actions里面的方法,
  // 第二个参数传的参数)来调用
  actions: {
    // context可以理解为state的上一级,
    asyncAdd(context, num) {
      // 这里传的参数一般都是context固定 

      setTimeout(() => {
        context.commit("addcountA", num)
        // commit就是把addcountA提交给mutation里面 num就是组件里面传的参数
      }, 1000)
    },

    asyncjj(context) {
      // 这里传的参数一般都是context固定 
      setTimeout(() => {
        context.commit("addcountB")
        // commit就是把addcountA提交给mutation里面
      }, 1000)
    }
  },
  //模块
  modules: {
  }
})

使用vuex里面的数据的组件

<template>
  <div>
    <!-- 使用辅助函数...mapstate -->
    {{ this.$store.state.name }}

    <!-- 不适用辅助函数...mapstate -->
    {{ name }}

    <!-- 没有使用辅助函数...getters -->
    {{ filterArr }}

    <!-- 使用...getters -->
    {{ this.$store.getters.filterArr }}

    {{ count }}

    <button @click="btnAdd">加加</button>
    <button @click="btnjj">减减</button>
  </div>
</template>
  
  <script>
// 使用vuex必须使用vuex
// 前面全是加map的都是辅助函数
//使用辅助函数必须在vuex结构出来
import { mapState, mapMutations, mapActions, mapGetters } from "vuex";
export default {
  // mapState必须在coputed里面使用
  computed: {
    ...mapState(["name", "count"]),
    ...mapGetters(["filterArr"]),
    // 用了辅助函数就可以直接使用数据name
  },
  created() {
    // 第一种使用没有使用辅助函数getters
    console.log("====================================");
    console.log(this.$store.getters.filterArr);
    //打印出one two两个数据包含o
    console.log("====================================");
  },

  methods: {
    // 第一种方法没有使用mutaion辅助函数
    // 加加count
    // btnAdd() {
    //   this.$store.commit("addCount", 10);
    //   // 也就是你想使用mutaion,就需要使用commit来触发mutaion的操作
    //   // 第一个参数是mutation定义的方法 第二个参数是传的参数没加10
    // },
    // btnjj() {
    //   this.$store.commit("jjCount");
    //   // 也就是你想使用mutaion,就需要使用commit来触发mutaion的操作
    //   // 第一个参数是mutation定义的方法 第二个参数没传默认是1
    // },
    // 第二种方法使用...mutation辅助函数
    // ...mapMutations(["addCounts", "jjCounts"]),
    // btnAdd() {
    //   this.addCounts(10);
    //   // this直接指向addCounts在vuex中mutations直接使用方法 括号里面是传的参数10
    // },
    // btnjj() {
    //   this.jjCounts();
    //   // this直接指向addCounts在vuex中mutations直接使用方法 括号里面是传的参数不传默认是一
    // },

    // 第一种方法没有使用actions

    // btnAdd() {
    //   this.$store.dispatch("asyncAdd", 100);
    //   // 也就是你想使用actions就需要使用dispatch来触发actions的操作
    // },
    // btnjj() {
    //   this.$store.dispatch("asyncjj");
    //   // 也就是你想使用actions就需要使用dispatch来触发actions的操作
    // },
    // 第二种方法使用...mapactions辅助函数
    ...mapActions(["asyncAdd", "asyncjj"]),
    btnAdd() {
      this.asyncAdd(100);
    },
    btnjj() {
      this.asyncjj();
    },
  },
};
</script>

使用state辅助函数

code4.png

code2.png

code3.png 使用getters辅助函数 code4.png

code1.png

code2.png

code3.png

使用mutations辅助函数 code4.png

code1.png

code2.png

使用actions辅助函数

code4.png

code1.png

code2.png

code3.png

代码仓库地址 gitee.com/diyakai/com…