[VUE基礎]vue2中emit的使用姿勢

2021-02-21 豆子前端筆記

在本文中, 我主要寫寫$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>
<h1>案例</h1>
<h2>利用組件來實現動態顯示框的傳值</h2>
<div style="text-align:left;margin-bottom:10px">
<input
type="button"
value="新增用戶"
@click="addUser">
</div>
<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">{{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
v-show="isShow">
<form>
<label>
<span>姓名:</span>
<input type="text"
v-model="editedUser.name"
>
</label>
<label>
<span>外號:</span>
<input type="text"
v-model="editedUser.nickName"
>
</label>
<label>
<span>技能:</span>
<textarea v-model="skill"
placeholder="多個技能之間用回車隔開"
rows="4"
></textarea>
</label>
<div>
<input type="button" value="提交" @click="submit">
<input type="button" 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中組件的使用(下)
    vue中組件的使用(上)中,小編總結了組件的分類和註冊、組件的data選項、組件的props選項的使用對此我們可以使用vue提供的API接口$emit實現,實現步驟如下:使用$emit在子組件中自定義觸發事件在父組件中監聽事件,執行對應方法針對以上步驟,代碼是這樣的:
  • Vue組件通信的葵花寶典
    今天我們聊一聊,面試中經常會被問及的問題,vue組件如何通信:props——常用於父子組件$emit——子組件觸發父組件事件.sync——雙向綁定語法糖(較少使用)$attrs和$listeners ——組件封裝provide和inject ——多層組件封裝$parent和$children——父子組件直接調用boradcast和dispatch ——vue2.0刪掉了EventBus
  • Vue2.0父子組件間通信
    vue2.0Vue.js是一套構建用戶界面的漸進式框架。與其他重量級框架不同的是,Vue 從根本上採用最小成本、漸進增量的設計。Vue 的核心庫只專注於視圖層,並且很容易與其他第三方庫或現有項目集成。另一方面,當與單文件組件和 Vue 生態系統支持的庫結合使用時,Vue 也完全能夠為複雜的單頁應用程式提供有力驅動。
  • Vue.js最佳實踐(五招讓你成為Vue.js大師)
    招式解析:首先,在watchers中,可以直接使用函數的字面量名稱;其次,聲明immediate:true表示創建組件時立馬執行一次。/baseButton.vue', 所以這裡我們去掉頭和尾,只保留真正的文件名  )   Vue.component(componentName, componentConfig.default || componentConfig)})最後我們在main.js中import 'components/global.js',然後我們就可以隨時隨地使用這些基礎組件
  • Vue.js布局
    動態Vue.js布局組件前言vue.js是漸進增強的視圖庫,可以作為.html頁面部分使用,也可以結合vue-router、vuex、axios用來構建單頁面或多頁面應用。
  • vue2.0 子組件和父組件之間的傳值
    >剛剛我們創建的是vue基於webpack工具的一個模板項目,對於webpack和熱加載這些不熟悉的同學不必在意,我們現在不會過多關注webpack的,不過建議對vue有興趣的同學還是去了解一下webpack,它也算是vue開發中的一個必備工具接著我們進入Demo,首先我們可以刪除掉模板項目中src/components/
  • vue題
    12、vue.js的兩個核心是什麼?數據驅動和組件化13、vue中 key 值的作用使用key來給每個節點做一個唯一標識key的作用主要是為了高效的更新虛擬DOM。另外vue中在使用相同標籤名元素的過渡切換時,也會使用到key屬性,其目的也是為了讓vue可以區分它們,否則vue只會替換其內部屬性而不會觸發過渡效果。
  • 前端技術:開發一個vue中央事件總線插件vue-bus
    大家都知道,一個中央事件總線bus,可以作為一個簡單的組件傳遞數據,用於解決跨級和兄弟組件通信問題,那麼,這篇文字,我將使用這種思想,將bus封裝為一個Vue的插件,可以在所有的組件間任意使用,而不需要導入bus。
  • vue中的eventBus會產生內存洩漏嗎
    eventBus是在vue中經常用來解決跨組件消息傳遞的問題,但對它的使用要特別注意
  • 【乾貨】Vue的class語法與常規語法對照表
    項目中使用的是vue-class-component、vue-property-decorator配合TypeScript來進行開發的,其中vue-class-component提供了class語法,而vue-property-decorator提供了一些裝飾器來方便代碼的組織和編寫。
  • 實戰教學使用 Vue3 重構 Vue2 項目(萬字好文推薦)
    本文來自於 神奇的程式設計師 的分享好文,點擊閱讀原文查看作者的掘金鍊接。
  • Vue組件的通信--eventBus
    但是對於具有簡單體系結構的應用程式來說,使用事件在組件之間進行通信就足夠了。為此,我們可以創建一個快速的解決方案並實現EventBus,也稱作vue的中央事件總線,適用於跨級或兄弟組件。EventBus允許我們在一個組件中發出一個事件,而在另一個組件中偵聽該事件。本示例將說明如何在Vue.js應用程式中執行此操作。
  • vue數據傳遞--我有特殊的實現技巧
    子組件// propsprops: ['info']// 向上傳值,某個方法中使用this.$emit('event1', val)可以看出本質是一個vue實例充當事件綁定的媒介。 在所有實例中使用其進行數據的通信。雙(多)方使用同名事件進行溝通。問題$emit時,必須已經 $on,否則將無法監聽到事件,也就是說對組件是有一定的同時存在的要求的。
  • Vue-使用vue-video-player組件
    在實際開發過程中會有添加視頻的需求在vue項目中添加視頻可以使用vue-video-player組件來實現實現步驟:1.安裝在控制臺輸入: npm install vue-video-player –s
  • 5招讓你成為Vue.js大師
    招式解析:首先,在watchers中,可以直接使用函數的字面量名稱;其次,聲明immediate:true表示創建組件時立馬執行一次。\w+$/, '') ) Vue.component(componentName, componentConfig.default || componentConfig)})最後我們在main.js中import 'components/global.js',然後我們就可以隨時隨地使用這些基礎組件,無需手動引入了。
  • Vue基礎及常用UI組件庫簡介
    /2.5.17-beta.0/vue.min.js"></script><script type="text/javascript"> new Vue({ el:'#app', data:{ msg: 'Hello World' } })</script
  • JavaScript框架教程-Vue
    $refs 是 Vue 提供的實例屬性,專門用來獲取 DOM 元素2.1 使用 refs在需要獲取的標籤添加 ref="標識符" 行內屬性;然後在 Vue 的實例中通過 vm.局部組件是只能在當前 Vue 實例中使用的組件;6.2 使用局部組件的步驟創建組件註冊組件使用組件
  • 實踐 | Element UI + Vue 管理系統首頁
    核心知識點關於 v-show屬性的相關使用大致效果圖其中上方文頭部導航,左邊為菜單選項,中間為index頁面。前提前提需要閱讀上一篇,使用Vue UI 方式創建 Hello World Vue 項目。return { msg: 'https://www.iming.info/', cur: 1 } } }</script>其中把三個組件進行相關的註冊,註冊到頁面中。
  • 35道常見的前端vue面試題
    如果v-if和v-for一起用的話,vue中的的會自動提示v-if應該放到外層去5、v-for中的key的理解?需要使用key來給每個節點做一個唯一標識,Diff算法就可以正確的識別此節點。主要是為了高效的更新虛擬DOM。6、vue中transition的理解?
  • 前端技術棧:5分鐘入門VUE+Element UI
    另一方面,當與現代化的工具鏈以及各種支持類庫結合使用時,Vue 也完全能夠為複雜的單頁應用提供驅動。此處可以看VUE入門視頻:https://learning.dcloud.io/#/?vid=0本教程是給有一點基礎的人進行VUE的快速入門,搭建一個單頁面的增刪改查。效果演示