用 Mitt 进行组件传值几乎可以解决vue组件传值的所有问题
例如:兄弟传兄弟 /父传子 /子传父 /孙子传爷爷。
mitt又称事务总线,是第三方插件。 Vue2.x 使用 EventBus 进行组件通信,而 Vue3.x 推荐使用 mitt.js。点击 Mitt 了解更多
cd到自己项目文件夹下在项目终端输入
$ npm install --save mitt
然后使用像rollup或webpack这样的模块捆绑器,像使用其他任何东西一样使用:
// using ES6 modules
import mitt from 'mitt'
// using CommonJS modules
var mitt = require('mitt')
将以下代码复制到所要使用的 .html 文件 的 head标签中 例如
<head>
<script src="https://unpkg.com/mitt/dist/mitt.umd.js">script>
head>
你可以在window.mitt上找到这个mitt包。
//若是使用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)需要在root根组件下的my-form组件和my-table组件中进行数据的传递。并在my-table组件中回显----------是不是so easy ,让我们来试一试吧。 案例代码我会放在下面哦。
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>
以上代码我们可以知道 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>
//在