在本文中, 我主要写写$emit的一些用法和实例(笔记用)
1.用法
$emit( eventName, […args] )
eventName:一个事件名,会绑定一个方法。当组件触发事件后,将调用这个方法。 …args:附加参数,会被抛出,由上述绑定的方法接收使用。文档说:它是一个触发当前实例上的事件。附加参数都会传给监听器回调。
子组件使用this.$emit()向父组件传值。首先必须在父组件中引用子组件,然后实现传值。
1.1在父组件中引入子组件
使用import引入组件
import indexImportOrder from ‘./components/indexImportOrder’ 声明
//定义组件 components:{ indexImportOrder, }, 使用
<indexImportOrder ref="indexImportOrder"/>
1.2 子组件向父组件传值
(1)在子组件中需要向父组件传值处使用this.$emit(“function”,param), function为父组件定义函数,param为需要传递参数。
//新订单页面跳转
viewBusiness(){
let flag = false;
this.$emit('closeMain',flag);
},
(2)在父组件中子组件引用处添加函数v-on:function=”function1″;其中function为子组件中定义函数,function1为父组件定义函数–用于接收子组件传值并进行相应数据处理,可定义为同一名称
<indexImportOrder ref="indexImportOrder" v-on:closeMain="closeMain"/>
val及为子组件中flag,即接收的子组件参数
closeMain(val){ this.flag = val; },
2.示例
2.1 只配合一个事件名使用$emit(‘welcome’),无附加参数
// 定义组件
Vue.component('welcome-button', {
template: `
<button v-on:click="$emit('welcome')"> // 【1】 $emit只使用了一个事件名welcome,无参数
Click me to be welcomed
</button>
`
})
//使用组件
<div id="emit-example-simple">
<welcome-button v-on:welcome="sayHi"></welcome-button> // 【2】 为事件名welcome绑定一个方法sayHi
</div>
//创建Vue实例
new Vue({
el: '#emit-example-simple',
methods: {
sayHi: function () { // 【3】 当组件触发事件后,执行welcome所绑定的方法sayHi
alert('Hi!')
}
}
})
2.2 配合额外的参数使用**
// 定义组件
Vue.component('magic-eight-ball', {
data: function () {
return {
possibleAdvice: ['Yes', 'No', 'Maybe']
}
},
methods: {
giveAdvice: function () {
var randomAdviceIndex = Math.floor(Math.random() * this.possibleAdvice.length)
//【1】在组件绑定的方法giveAdvice中触发$emit事件,并抛出参数
this.$emit('give-advice', this.possibleAdvice[randomAdviceIndex])
}
},
template: `
<button v-on:click="giveAdvice">
Click me for advice
</button>
`
})
// 使用组件
<div id="emit-example-argument">
<magic-eight-ball v-on:give-advice="showAdvice"></magic-eight-ball> //【2】为$emit事件绑定一个方法showAdvice
</div>
// 创建Vue实例
new Vue({
el: '#emit-example-argument',
methods: {
showAdvice: function (advice) { // 【3】方法的参数 advice 用来接收 $emit 抛出的参数
alert(advice)
}
}
})
2.3 利用组件来实现动态显示框的传值
应用:填写,修改信息时用到的动态显示框,增加用户友好体验感
这是一个简单的用户信息增删改的例子, 子组件专门写动态显示框的内容,父组件和子组件之间利用$emit来传递用户对象, 或用来触犯父组件中的函数
views/demo.vue部分(父组件, 主体框)
<template>
<div class="demo">
<h1>案例</h1>
<h2>利用组件来实现动态显示框的传值</h2>
<div style="text-align:left;margin-bottom:10px">
<input class="btn"
type="button"
value="新增用户"
@click="addUser">
</div>
<table class="table">
<tr>
<th>姓名</th>
<th>外号</th>
<th>技能</th>
<th>操作</th>
</tr>
<tr v-for="(user,index) of userList"
:key="user.id">
<td>{{user.name}}</td>
<td>{{user.nickName}}</td>
<td>
<span v-for="(skill,skillIndex) of user.skill" :key="skillIndex" class="tag">{{skill}}</span>
</td>
<td>
<a href="javascript:;"
@click="editUser(user,index)">编辑</a> |
<a href="javascript:;"
@click="deleteUser(index)">删除</a>
</td>
</tr>
</table>
<edit-modal v-show="isShow"
:data="editedUser"
@on-submit="submit"
@on-cancel="cancel"></edit-modal>
</div>
</template>
<script>
import EditModal from '../components/model'
export default {
name: 'demo14',
data () {
return {
isShow: false,
editedUser: {},
editedUserIndex: -1,
userList: [
{
id: 1562725945741,
name: '欧阳锋',
nickName: '西毒、老毒物',
skill: ['蛤蟆功', '灵蛇杖法']
},
{
id: 1562723132751,
name: '洪七公',
nickName: '北丐、老叫花',
skill: ['降龙十八掌', '打狗棒法']
},
{
id: 1562725939582,
name: '黄药师',
nickName: '东邪、黄老邪',
skill: ['弹指神通', '碧海潮生曲']
},
{
id: 1562725920190,
name: '段智兴',
nickName: '南帝、一灯大师',
skill: ['一阳指', '先天功']
}
]
}
},
methods: {
addUser () {
this.isShow = true
},
editUser (user, index) {
this.isShow = true
this.editedUser = { ...user }
this.editedUserIndex = index
},
deleteUser (index) {
if (window.confirm('是否确认删除?')) {
this.userList.splice(index, 1)
}
},
submit (data) {
console.log(data)
if (this.editedUserIndex === -1) {
// ADD
data = {
...data,
id: Date.now()
}
this.userList.unshift(data)
} else {
// EDIT
this.userList.splice(this.editedUserIndex, 1, data)
}
this.cancel()
},
cancel () {
this.isShow = false
this.editedUser = {}
this.editedUserIndex = -1
}
},
components: {
EditModal
}
}
</script>
<style lang="less" scoped>
.title {
font-size: 32px;
color: blue;
}
.btn {
border: none;
height: 32px;
line-height: 32px;
padding: 0 16px;
border-radius: 16px;
cursor: pointer;
outline: none;
&.btn-blue {
color: #fff;
background: #00f;
}
&.btn-gray {
color: #333;
background: #e0e0e0;
}
}
.table {
width: 100%;
border-collapse: collapse;
th {
background: #eee;
}
th,
td {
padding: 8px 0;
border: 1px solid #ccc;
}
}
.tag {
display: inline-block;
padding: 0 8px;
line-height: 1.5;
background: #f0f0f0;
// background: grey;
border: 1px solid #d0d0d0;
border-radius: 4px;
margin: 4px;
}
</style>
components/model.vue部分(子组件,动态显示框)
<template>
<div class="modal"
v-show="isShow">
<form class="form">
<label class="form-item">
<span class="label-text">姓名:</span>
<input type="text"
v-model="editedUser.name"
class="form-input">
</label>
<label class="form-item">
<span class="label-text">外号:</span>
<input type="text"
v-model="editedUser.nickName"
class="form-input">
</label>
<label class="form-item">
<span class="label-text">技能:</span>
<textarea v-model="skill"
placeholder="多个技能之间用回车隔开"
rows="4"
class="form-input textarea"></textarea>
</label>
<div class="form-item text-center">
<input type="button" class="btn btn-blue" value="提交" @click="submit">
<input type="button" class="btn btn-gray" value="取消" @click="cancel">
</div>
</form>
</div>
</template>
<script>
export default {
name: 'model',
data () {
return {
isShow: false,
editedUser: this.data
}
},
props: {
data: {
type: Object,
// eslint-disable-next-line vue/require-valid-default-prop
default: {}
}
},
computed: {
skill: {
get () {
return this.editedUser.skill ? this.editedUser.skill.join('n') : ''
},
set (val) {
let skill = val.split('n')
this.editedUser = {
...this.editedUser,
skill
}
console.log(this.editedUser)
}
}
},
methods: {
submit () {
const { name, nickName, skill } = this.editedUser
if (!name) {
alert('请输入姓名')
return
} else if (!nickName) {
alert('请输入外号')
return
} else if (!skill || !skill.join('')) {
alert('请输入技能')
return
}
this.$emit('on-submit', this.editedUser)
},
cancel () {
this.$emit('on-cancel')
}
},
watch: {
data (val) {
this.editedUser = val
}
}
}
</script>
<style lang="less" scoped>
.modal {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
&:before {
content: "";
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
}
.form {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
padding: 16px;
border-radius: 8px;
background: #fff;
}
.form-item {
display: block;
text-align: left;
margin-top: 10px;
&.text-center {
text-align: center;
}
.label-text {
margin-right: 8px;
line-height: 32px;
font-size: 14px;
}
.form-input {
width: 240px;
padding: 0 8px;
background: #fff;
border: 1px solid #d0d0d0;
border-radius: 4px;
height: 32px;
line-height: 1.8;
// font-size: 14px;
// vertical-align: top;
&.textarea {
height: 80px;
overflow: hidden;
vertical-align: top;
height: auto;
}
}
// .btn {
// margin: 0 4xp;
// }
}
}
.btn {
border: none;
height: 32px;
line-height: 32px;
padding: 0 16px;
border-radius: 16px;
cursor: pointer;
outline: none;
&.btn-blue {
color: #fff;
background: #00f;
}
&.btn-gray {
color: #333;
background: #e0e0e0;
}
}
</style>
结果:
————————结束分割线———————————-
原文始发于微信公众号(豆子前端):[VUE基础]vue2中emit的使用姿势
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/56855.html