使用Mitt进行vue组件之间的通信例演示&&解说

文章目录

  • 前言
  • 一、Mitt是什么?
  • 二、使用步骤
    • 1.npm 引入(实际项目中推荐)
    • 2.UMD构建也可以在unpkg上使用(html单页面使用,常用来练习)
    • 3.使用方法(参考官网)
  • 三、案例分析
    • 1.需求分析
    • 2.实际操作
      • (1)初始代码
      • (2)分离form 和 table 并引入 mitt.js
      • (3)改造 js代码
        • 1.在js中初始化mitt
        • 2.全局定义 my-form \ my-table 子组件并初始化data数据
        • 3.在 my-form \ my-table 子组件中发送和监听数据
  • 四、完整代码


前言

用 Mitt 进行组件传值几乎可以解决vue组件传值的所有问题

例如:兄弟传兄弟 /父传子 /子传父 /孙子传爷爷。


一、Mitt是什么?

mitt又称事务总线,是第三方插件。 Vue2.x 使用 EventBus 进行组件通信,而 Vue3.x 推荐使用 mitt.js。点击 Mitt 了解更多

二、使用步骤

1.npm 引入(实际项目中推荐)

cd到自己项目文件夹下在项目终端输入

$ npm install --save mitt

然后使用像rollupwebpack这样的模块捆绑器,像使用其他任何东西一样使用:

// using ES6 modules
import mitt from 'mitt'

// using CommonJS modules
var mitt = require('mitt')

2.UMD构建也可以在unpkg上使用(html单页面使用,常用来练习)

将以下代码复制到所要使用的 .html 文件 的 head标签中 例如

<head>

    <script src="https://unpkg.com/mitt/dist/mitt.umd.js">script>
head>

你可以在window.mitt上找到这个mitt包

3.使用方法(参考官网)

//若是使用cdn引入这需要将以下两行代码更换成
// const emitter = window.mitt() //注意这里的 window 首字母小写
import mitt from 'mitt'

const emitter = mitt()

// listen to an event(监听一个event事件)
emitter.on('foo', e => console.log('foo', e) )

// listen to all events (监听所有的event事件)
emitter.on('*', (type, e) => console.log(type, e) )

// fire an event (发送事件)
emitter.emit('foo', { a: 'b' })

// clearing all events (清除事件)
emitter.all.clear()

// working with handler references (使用处理程序引用):
function onFoo() {}
emitter.on('foo', onFoo)   // listen
emitter.off('foo', onFoo)  // unlisten

三、案例分析

1.需求分析

(1)需要在root根组件下的my-form组件和my-table组件中进行数据的传递。并在my-table组件中回显----------是不是so easy ,让我们来试一试吧。 案例代码我会放在下面哦
使用Mitt进行vue组件之间的通信例演示&&解说_第1张图片

2.实际操作

(1)初始代码



DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Documenttitle>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js">script>
  <style>
    li {
      list-style: none;
    }

    .center {
      margin: 0 auto;
      width: 400px;
      text-align: center;
    }

    .red {
      color: red;
    }

    .green {
      color: green;
    }
  style>
head>

<body>
  <div id="app">div>
  <template id="root">
    <div class="center">
      <h3>用户注册h3>
      <ul>
        <li>
          <label>用户名:label><input type="text" @blur="checkUserName" v-model="username" placeholder="请输入用户名">
          <span :class="[this.errors.username=='校验通过'?'green':'red']">{{errors.username}}span>
        li>
        <li>
          <label>密码:label><input type="password" @blur="checkPass" v-model=" password" placeholder="请输入密码">
          <span>{{errors.password}}span>
        li>
        <li>
          <label>性别:label>
          <input type="radio" name="gender" value="male" v-model="gender" /><input type="radio" name="gender" value="female" v-model="gender" />li>
        <li>
          <label>地址:label>
          <select v-model="selectedCity">
            <option :value="c.name" v-for="c in cities">{{c.text}}option>
          select>
        li>
      ul>
      <button @click="handleRegister">注册button>
      <div style="display: flex;flex-direction: row;justify-content: center;">
        <table border="1">
          <tr>
            <td>序号td>
            <td>用户名td>
            <td>性别td>
            <td>地址td>
          tr>
          <tr v-for="(u,index) in users">
            <td>{{index+1}}td>
            <td>{{u.username}}td>
            <td>{{u.gender=='male'?'男':'女'}}td>
            <td>{{handleCity(u.city)}}td>
          tr>
        table>
      div>

    div>
  template>
body>
<script>
  const app = Vue.createApp({
    template: "#root",
    data() {
      return {
        username: '',
        password: '',
        gender: 'male',
        cities: [
          { name: 'cq', text: '重庆' },
          { name: 'bj', text: '北京' },
        ],
        selectedCity: 'cq',
        errors: {},
        users: [],
        id: ''
      }
    },
    methods: {
      handleModify() {
        const user = this.users.find((u) => { return u.id == this.id })
        user.username = this.username
        user.password = this.password
        user.gender = this.gender
        user.city = this.selectedCity
      },
      handleRegister() {
        if (this.errors.username == '校验通过' && this.errors.password == '校验通过') {
          console.log({
            username: this.username,
            password: this.password,
            gender: this.gender,
            city: this.selectedCity
          })
          this.users.push({
            username: this.username,
            password: this.password,
            gender: this.gender,
            city: this.selectedCity
          })
        }
      },
      checkUserName() {
        if (this.username == "" || this.username == null) {
          this.errors.username = "用户名不能为空"
        } else {
          this.errors.username = "校验通过"
        }
      },
      checkPass() {
        if (this.password == "" || this.password == null) {
          this.errors.password = "密码不能为空"
        } else {
          if (this.password.length < 6) {
            this.errors.password = "密码长度不正确"

          } else {
            this.errors.password = "校验通过"

          }
        }
      },
      handleCity(name) {
        let text = ''
        this.cities.forEach(c => {
          if (c.name == name) {
            text = c.text
          }
        });
        return text
      }
    }
  })
  app.mount("#app")
script>

html>

(2)分离form 和 table 并引入 mitt.js

以上代码我们可以知道 form表单和table表格还并不是一个单独的组件,因此我们第一步就是将他们从根组件中分离出来并在 head 标签中引入 mitt 包



DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
    
    <script src="https://unpkg.com/vue@3/dist/vue.global.js">script>
    
    <script src="https://unpkg.com/mitt/dist/mitt.umd.js">script>
    <style>
        li {
            list-style: none;
        }
        
        .center {
            margin: 0 auto;
            width: 400px;
            text-align: center;
        }
        
        .red {
            color: red;
        }
        
        .green {
            color: green;
        }
    style>
head>

<body>
    <div id="app">div>
    
    <template id="root">
    <div class="center">
     <div style="border:1px #123 solid">
      这是子组件 from
      <my-form>my-form>
     div>
     <div style="border:1px #123 solid">
      这是子组件 table
      <my-table>my-table>
     div>
    div>
  template>
 
    <template id="form">
    <div>
      <h3>用户注册h3>
      <ul>
        <li>
          <label>用户名:label><input type="text" @blur="checkUserName" v-model="username" placeholder="请输入用户名">
          <span :class="[this.errors.username=='校验通过'?'green':'red']">{{errors.username}}span>
        li>
        <li>
          <label>密码:label><input type="password" @blur="checkPass" v-model=" password" placeholder="请输入密码">
          <span>{{errors.password}}span>
        li>
        <li>
          <label>性别:label>
          <input type="radio" name="gender" value="male" v-model="gender" /><input type="radio" name="gender" value="female" v-model="gender" />li>
        <li>
          <label>地址:label>
          <select v-model="selectedCity">
            <option :value="c.name" v-for="c in cities">{{c.text}}option>
          select>
        li>
      ul>
      <button @click="handleRegister">注册button>
    div>
  template>
 
    <template id="table">
    <div>
      <div style="display: flex;flex-direction: row;justify-content: center;">
        <table border="1">
          <tr>
            <td>序号td>
            <td>用户名td>
            <td>性别td>
            <td>地址td>
          tr>
          <tr v-for="(u,index) in users">
            <td>{{index+1}}td>
            <td>{{u.username}}td>
            <td>{{u.gender=='male'?'男':'女'}}td>
            <td>{{handleCity(u.city)}}td>
          tr>
        table>
      div>
    div>
  template>
body>

<script>
  const app = Vue.createApp({
    template: "#root",
    data() {
      return {
        username: '',
        password: '',
        gender: 'male',
        cities: [
          { name: 'cq', text: '重庆' },
          { name: 'bj', text: '北京' },
        ],
        selectedCity: 'cq',
        errors: {},
        users: [],
        id: ''
      }
    },
    methods: {
      handleModify() {
        const user = this.users.find((u) => { return u.id == this.id })
        user.username = this.username
        user.password = this.password
        user.gender = this.gender
        user.city = this.selectedCity
      },
      handleRegister() {
        if (this.errors.username == '校验通过' && this.errors.password == '校验通过') {
          console.log({
            username: this.username,
            password: this.password,
            gender: this.gender,
            city: this.selectedCity
          })
          this.users.push({
            username: this.username,
            password: this.password,
            gender: this.gender,
            city: this.selectedCity
          })
        }
      },
      checkUserName() {
        if (this.username == "" || this.username == null) {
          this.errors.username = "用户名不能为空"
        } else {
          this.errors.username = "校验通过"
        }
      },
      checkPass() {
        if (this.password == "" || this.password == null) {
          this.errors.password = "密码不能为空"
        } else {
          if (this.password.length < 6) {
            this.errors.password = "密码长度不正确"

          } else {
            this.errors.password = "校验通过"

          }
        }
      },
      handleCity(name) {
        let text = ''
        this.cities.forEach(c => {
          if (c.name == name) {
            text = c.text
          }
        });
        return text
      }
    }
  })
  app.mount("#app")
script>
html>

(3)改造 js代码

1.在js中初始化mitt
//在
                    
                    

你可能感兴趣的:(vue.js,javascript,前端)