Vue组件的九种通信方式

目录

1.父传子props

2.子传父$emit

3.兄弟组件传值eventBus

4.父组件使用子组件的数据和方法$refs

5.子组件使用父组件的数和方法$parent

6.祖先传值provide/inject

7.爷孙传值 $attrs/$listeners

8.路由传值

9.Vuex传值


1.父传子props

同过props里面的值在子组件上与父组件的数据进行绑定就能获取到父组件的数据

 <div id="app">
    <!-- 第一个list是子组件里面的props里面的list第二个list是父组件的list
    这样通过props作为一个中间接受值进行绑定传值 -->
    <son :list="list"></son>
  </div>
  <script>
    //定义一个子组件
    const son = {
      props: ['list'],
      template: `
        <div>
          我是子组件
          {{list}}
        </div>
      `
    }
    new Vue({
      el: "#app",
      data: {
        list: '父组件的数据'
      },
      components: {
        son
      }
    })
  </script>

2.子传父$emit

通过$emit第二个参数对父组件进行传值

 <div id="app">
    <h1>父组件:{{list}}</h1>
    <!-- @getdata是自定义事件是$emit里面的第一参数 -->
    <son @getdata="getData"></son>
  </div>
  <script>
    //定义一个子组件
    const son = {
      template: `
        <div>
          我是子组件
          <button @click="setData">setData</button>
        </div>
      `,
      data() {
        return {
          list: '子组件的数据'
        }
      },
      methods: {
        setData() {
          this.$emit('getdata', this.list);//第一个参数是自定义事件第二个参数是要传给父组件的值
        }
      }
    }
    new Vue({
      el: "#app",
      data: {
        list: '父组件的数据'
      },
      components: {
        son
      },
      methods: {
        getData(data) {
          this.list = data
        }
      }
    })
  </script>

3.兄弟组件传值eventBus

new 一个Vue对象来作为中间对象

<div id="app">
    <son1></son1>
    <son2></son2>
  </div>
  <script>
    const eventBus = new Vue()
    //定义一个子组件
    const son1 = {
      template: `
        <div>
          我是子组件a----{{list}}
          <button @click="setData">setData</button>
        </div>
      `,
      data() {
        return {
          list: 'a子组件的数据'
        }
      },
      methods: {
        setData() {
          eventBus.$emit('getdata', this.list)
        }
      }
    }
    const son2 = {
      template: `
        <div>
          我是子组件b----{{list}}
        </div>
      `,
      data() {
        return {
          list: 'b子组件的数据'
        }
      },
      methods: {

      },
      created() {
        eventBus.$on('getdata', function (data) {
          console.log(data);
        })
      }
    }
    new Vue({
      el: "#app",
      data: {
        list: '父组件的数据'
      },
      components: {
        son1,
        son2
      },
      methods: {

      }
    })
  </script>

4.父组件使用子组件的数据和方法$refs

在子组件上定义ref=""在通过$refs.ref去获取对应的dom

<div id="app">
    <h1 @click="change">父组件</h1>
    <comp ref="ref"></comp>
  </div>
  <script>
    const comp = {
      template: `
        <div>
          <h1>子组件</h1>
        </div>
      `,
      data() {
        return {
          item: '子组件数据'
        }
      },
      methods: {
        getData() {
          console.log(this.item);
        }
      }
    }
    new Vue({
      el: "#app",
      data: {
        parent: '父组件数据'
      },
      components: {
        comp
      },
      methods: {
        change() {
          this.$refs.ref.getData()//执行子组件的方法
        }
      }
    })
  </script>

5.子组件使用父组件的数和方法$parent

<div id="app">
    <comp></comp>
  </div>
  <script>
    const comp = {
      template: `
        <div>
          <h1>子组件</h1>
          <button @click="getparent">获取</button>
        </div>
      `,
      data() {
        return {
          item: '子组件数据'
        }
      },
      methods: {
        getparent() {
          this.$parent.getData()//执行父组件的方法
          console.log(this.$parent);//获取父组件dom
        }
      }
    }
    new Vue({
      el: "#app",
      data: {
        parent: '父组件数据'
      },
      components: {
        comp
      },
      methods: {
        getData() {
          console.log(this.parent);
        }
      }
    })
  </script>

6.祖先传值provide/inject

<div id="app">
    <h1>爷爷</h1>
    <parent></parent>
  </div>

  <script>
    const son = {
      inject: ['msg', 'event'],
      template: `
        <div>
          <h3>儿子</h3>
          {{msg}}
          <button @click="setData">setData</button>
        </div>
      `,
      methods: {
        setData() {
          this.event.getson('哈哈哈')
        }
      }
    }
    const parent = {
      inject: ['msg'],
      template: `
        <div>
          <h2>爸爸</h2>
          {{msg}}
          <son></son>
        </div>
      `,
      components: {
        son
      }
    }
    new Vue({
      el: "#app",
      data: {

      },
      provide: {
        msg: '压岁钱',
        event: {
          getson(data) {
            console.log(data);
          }
        }
      },
      methods: {

      },
      components: {
        parent
      }
    })
  </script>

7.爷孙传值 $attrs/$listeners

<div id="app">
    <h1>爷爷</h1>
    <!--儿子获取到爷爷的数据:通过:msg="msg"对爸爸组件标签绑定爷爷里面的数据,然后在儿子组件标签身上v-bind="$attrs"这样儿子就能通过$attrs.msg获取到爷爷的数据了 -->
    <!--爷爷获取到儿子的数据,在儿子组件标签身上v-on="$listeners",然后儿子组件里面需要用$emit去放回数据给爷爷,这样爷爷就能获取到儿子的数据了  -->
    <parent
      :msg="msg"
      @abc="getMsg"
    ></parent>
  </div>

  <script>
    const son = {
      template: `
        <div>
          <h3>儿子</h3>
          {{$attrs.msg}}
          <button @click="$emit('abc','谢谢爷爷')">getMsg</button>
        </div>
      `
    }
    const parent = {
      template: `
        <div>
          <h2>爸爸</h2>
          <son v-bind="$attrs" v-on="$listeners"></son>
        </div>
      `,
      components: {
        son
      }
    }
    new Vue({
      el: "#app",
      data: {
        msg: '爷爷给的压岁钱'
      },
      methods: {
        getMsg(data) {
          console.log(data);
        }
      },
      components: {
        parent
      }
    })
  </script>

8.路由传值

<div id="app">
    <button @click="goDetail">goDetail</button>
    <router-view></router-view>
  </div>
  <script>
    const Home = {
      props: ['name', 'age'],
      template: `
        <div>
          <h1> Home --- {{name}} --- {{age}}</h1>
          query:<h1> Home --- {{$route.query.name}} --- {{$route.query.age}}</h1>
          params<h1> Home --- {{$route.params.name}} --- {{$route.params.age}}</h1>
        </div>
      `,
    };
    const About = {
      template: `
        <div>
          About  
        </div>
      `,
    };

    const NotFoundPage = {
      template: '<div>404</div>'
    }
    const router = new VueRouter({
      routes: [
        {
          path: '/',
          redirect: '/home'
        },
        {
          path: "/home",
          component: Home,
        },
        {
          path: "/home/:name/:age",
          component: Home,
          props: true
        },
        {
          path: "/about",
          component: About,
        },
        {
          path: '*',
          component: NotFoundPage
        }
      ],
    })

    new Vue({
      el: "#app",
      data: {},
      router,
      methods: {
        goDetail() {
          // $route 参数获取
          // $router 路由跳转
          // console.log(this.$router)
          // string
          // this.$router.push('home')
          // this.$router.push('/home?name=fly&age=18')
          this.$router.push('/home/zs/30')
          // object
          // this.$router.push({ path: '/home' })
          // this.$router.push({ path: '/home', query: { name: 'zs', age: 18 } })  问号后面的参数
          // this.$router.push({ name: 'home', params: { name: 'zs', age: 18 } })  /后面的参数
        }
      }
    });
  </script>

9.Vuex传值

定义store

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    school: "北京大学",
    a:"nice"
  },
  getters: {
    returnVal(state) {
      return state.school + state.a;
    },
  },
  mutations: {
    changeSchool(state, val) {
      state.school = val;
      console.log('修改成功');
    },
  },
  actions: {},
  modules: {}
});

挂载

import Vue from 'vue';
import App from './App.vue';
import router from "./router";
import store from "./store";
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
import publicFn from "./publicFn/publicFn";

Vue.config.productionTip = false


const url = process.env.VUE_APP_URL;
Vue.prototype.$url = url;
Vue.prototype.$publicFn = publicFn;

Vue.use(ElementUI);

new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app')

使用

<template>
  <div class="hello">
    <h1 @click="add">{{ title }}</h1>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: ["title"],
  data() {
    return {
      age:18
    };
  },
  methods: {
    add(){
      console.log(this.$store.state.school);//获取值
    }
  },
};
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值