Vue2.x
咱們用了好久好久了,然而咱們在平常開發時,有一些好用卻沒發現的大陸。。javascript
在這裏,咱們就不講v-for
啊、v-if
啊等一些很基礎很基礎的。 想了解這些基本東西的話,能夠vue(戳我)html
本篇引用了vue官網絕大部份內容,可直接去官網查看。vue
本篇只是記錄(窩)平常開發時,比較少用卻好用的功能java
Prop
的用法不言而喻,這裏就來恭恭非Prop
。node
一個非 prop
的 attribute
是指傳向一個組件,可是該組件並無相應 prop
定義的 attribute
。express
由於顯式定義的 prop
適用於向一個子組件傳入信息,然而組件庫的做者並不總能預見組件會被用於怎樣的場景。這也是爲何組件能夠接受任意的 attribute
,而這些 attribute
會被添加到這個組件的根元素上。bootstrap
例如,想象一下你經過一個 Bootstrap
插件使用了一個第三方的 <bootstrap-date-input>
組件,這個插件須要在其<input>
上用到一個 data-date-picker
attribute
。咱們能夠將這個 attribute
添加到你的組件實例上:api
<bootstrap-date-input data-date-picker="activated"></bootstrap-date-input>
複製代碼
而後這個 data-date-picker="activated"
attribute
就會自動添加到 <bootstrap-date-input>
的根元素上。瀏覽器
(僞裝我是分割線-------------------------------------)緩存
以上是官文的介紹,看着是否是濛濛的。咱們這裏簡單的講解下。
假如,假如(假如是誰?)bootstrap-date-input
組件的定義是醬紫滴。
// bootstrap-date--input
<div>
<input></input>
</div>
...
props: {
// 我是空的,注意,我是空的
}
複製代碼
耳後,咱們使用bootstrap-date-input
這個組件。
<bootstrap-date-input data-date-picker="activated"></bootstrap-date-input>
複製代碼
這裏咱們知道,在bootstrap-date--input
組件內咱們並無在props
裏的定義data-date-picker
屬性。
到這裏你們應該開始明白了吧?官網解釋(一個非 prop
的 attribute
是指傳向一個組件,而這些 attribute
會被添加到這個組件的根元素上。)
bootstrap-date--input
組件會變成這樣
// bootstrap-date--input
<div data-date-picker="activated">
<input></input>
</div>
複製代碼
這裏直接引號官網的介紹。
想象一下 <bootstrap-date-input>
的模板是這樣的:
<input type="date" class="form-control">
複製代碼
爲了給咱們的日期選擇器插件定製一個主題,咱們可能須要像這樣添加一個特別的類名:
<bootstrap-date-input
data-date-picker="activated"
class="date-picker-theme-dark"
></bootstrap-date-input>
複製代碼
在這種狀況下,咱們定義了兩個不一樣的 class
的值:
form-control
,這是在組件的模板內設置好的date-picker-theme-dark
,這是從組件的父級傳入的對於絕大多數 attribute
來講,從外部提供給組件的值會替換掉組件內部設置好的值。因此若是傳入 type="text"
就會替換掉 type="date"
並把它破壞!慶幸的是,class
和 style
attribute
會稍微智能一些,即兩邊的值會被合併起來,從而獲得最終的值:form-control date-picker-theme-dark
。
若是你不但願組件的根元素繼承 attribute
,你能夠在組件的選項中設置 inheritAttrs: false
。例如:
Vue.component('my-component', {
inheritAttrs: false,
// ...
})
複製代碼
這尤爲適合配合實例的 $attrs
屬性使用,該屬性包含了傳遞給一個組件的 attribute
名和 attribute
值,例如:
{
required: true,
placeholder: 'Enter your username'
}
複製代碼
有了 inheritAttrs: false
和$attrs
,你就能夠手動決定這些 attribute
會被賦予哪一個元素。在撰寫基礎組件的時候是常會用到的:
Vue.component('base-input', {
inheritAttrs: false,
props: ['label', 'value'],
template: `
<label>
{{ label }}
<input
v-bind="$attrs"
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
</label>
`
})
複製代碼
注意 inheritAttrs: false 選項不會影響 style 和 class 的綁定。
複製代碼
這個模式容許你在使用基礎組件的時候更像是使用原始的 HTML
元素,而不會擔憂哪一個元素是真正的根元素:
<base-input
v-model="username"
required
placeholder="Enter your username"
></base-input>
複製代碼
不一樣於組件和 prop
,事件名不存在任何自動化的大小寫轉換。而是觸發的事件名須要徹底匹配監聽這個事件所用的名稱。舉個例子,若是觸發一個 camelCase
名字的事件:
this.$emit('myEvent')
複製代碼
則監聽這個名字的 kebab-case
版本是不會有任何效果的:
<!-- 沒有效果 -->
<my-component v-on:my-event="doSomething"></my-component>
複製代碼
不一樣於組件和 prop
,事件名不會被用做一個 JavaScript
變量名或屬性名,因此就沒有理由使用 camelCase
或 PascalCase
了。而且 v-on
事件監聽器在 DOM
模板中會被自動轉換爲全小寫 (由於 HTML 是大小寫不敏感的),因此 v-on:myEvent
將會變成v-on:myevent
——致使 myEvent
不可能被監聽到。
所以,咱們推薦你始終使用 kebab-case
的事件名。
一個組件上的 v-model
默認會利用名爲 value
的 prop
和名爲 input
的事件,可是像單選框、複選框等類型的輸入控件可能會將 value attribute
用於不一樣的目的。model
選項能夠用來避免這樣的衝突:
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
})
複製代碼
如今在這個組件上使用 v-model
的時候:
<base-checkbox v-model="lovingVue"></base-checkbox>
複製代碼
這裏的 lovingVue
的值將會傳入這個名爲checked
的 prop
。同時當 <base-checkbox>
觸發一個 change
事件並附帶一個新的值的時候,這個 lovingVue
的屬性將會被更新。
注意 你仍然須要在組件的
props
選項裏聲明checked
這個prop
。
你可能有不少次想要在一個組件的根元素上直接監聽一個原生事件。這時,你可使用 v-on
的 .native
修飾符:
<base-input v-on:focus.native="onFocus"></base-input>
複製代碼
在有的時候這是頗有用的,不過在你嘗試監聽一個相似 <input>
的很是特定的元素時,這並非個好主意。好比上述 <base-input>
組件可能作了以下重構,因此根元素其實是一個<label>
元素:
<label>
{{ label }}
<input
v-bind="$attrs"
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
</label>
複製代碼
這時,父級的 .native
監聽器將靜默失敗。它不會產生任何報錯,可是 onFocus 處理函數不會如你預期地被調用。
爲了解決這個問題,Vue
提供了一個 $listeners
屬性,它是一個對象,裏面包含了做用在這個組件上的全部監聽器。例如:
{
focus: function (event) { /* ... */ }
input: function (value) { /* ... */ },
}
複製代碼
有了這個 $listeners
屬性,你就能夠配合 v-on="$listeners"
將全部的事件監聽器指向這個組件的某個特定的子元素。對於相似 <input>
的你但願它也能夠配合 v-model
工做的組件來講,爲這些監聽器建立一個相似下述 inputListeners
的計算屬性一般是很是有用的:
Vue.component('base-input', {
inheritAttrs: false,
props: ['label', 'value'],
computed: {
inputListeners: function () {
var vm = this
// `Object.assign` 將全部的對象合併爲一個新對象
return Object.assign({},
// 咱們從父級添加全部的監聽器
this.$listeners,
// 而後咱們添加自定義監聽器,
// 或覆寫一些監聽器的行爲
{
// 這裏確保組件配合 `v-model` 的工做
input: function (event) {
vm.$emit('input', event.target.value)
}
}
)
}
},
template: ` <label> {{ label }} <input v-bind="$attrs" v-bind:value="value" v-on="inputListeners" > </label> `
})
複製代碼
如今 <base-input>
組件是一個徹底透明的包裹器了,也就是說它能夠徹底像一個普通的<input>
元素同樣使用了:全部跟它相同的 attribute
和監聽器均可以工做。
在有些狀況下,咱們可能須要對一個 prop
進行「雙向綁定」。不幸的是,真正的雙向綁定會帶來維護上的問題,由於子組件能夠修改父組件,且在父組件和子組件都沒有明顯的改動來源。
這也是爲何咱們推薦以 update:myPropName
的模式觸發事件取而代之。舉個例子,在一個包含 title prop
的假設的組件中,咱們能夠用如下方法表達對其賦新值的意圖:
this.$emit('update:title', newTitle)
複製代碼
而後父組件能夠監聽那個事件並根據須要更新一個本地的數據屬性。例如:
<text-document
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
></text-document>
複製代碼
爲了方便起見,咱們爲這種模式提供一個縮寫,即 .sync
修飾符:
<text-document v-bind:title.sync="doc.title"></text-document>
複製代碼
注意帶有
.sync
修飾符的v-bind
不能和表達式一塊兒使用 (例如v-bind:title.sync=」doc.title + ‘!’」
是無效的)。取而代之的是,你只能提供你想要綁定的屬性名,相似v-model
。
當咱們用一個對象同時設置多個 prop
的時候,也能夠將這個 .sync
修飾符和 v-bind
配合使用:
<text-document v-bind.sync="doc"></text-document>
複製代碼
這樣會把 doc
對象中的每個屬性 (如 title
) 都做爲一個獨立的prop
傳進去,而後各自添加用於更新的 v-on
監聽器。
將
v-bind.sync
用在一個字面量的對象上,例如v-bind.sync=」{ title: doc.title }」
,是沒法正常工做的,由於在解析一個像這樣的複雜表達式的時候,有不少邊緣狀況須要考慮。
Vue 實現了一套內容分發的 API,這套 API 的設計靈感源自 Web Components
規範草案,將 <slot>
元素做爲承載分發內容的出口。
它容許你像這樣合成組件:
<navigation-link url="/profile">
Your Profile
</navigation-link>
複製代碼
而後你在 <navigation-link>
的模板中可能會寫爲:
<a
v-bind:href="url"
class="nav-link"
>
<slot></slot>
</a>
複製代碼
當組件渲染的時候,<slot></slot>
將會被替換爲「Your Profile」。插槽內能夠包含任何模板代碼,包括 HTML:
<navigation-link url="/profile">
<!-- 添加一個 Font Awesome 圖標 -->
<span class="fa fa-user"></span>
Your Profile
</navigation-link>
複製代碼
甚至其它的組件:
<navigation-link url="/profile">
<!-- 添加一個圖標的組件 -->
<font-awesome-icon name="user"></font-awesome-icon>
Your Profile
</navigation-link>
複製代碼
若是 <navigation-link>
沒有包含一個 <slot>
元素,則該組件起始標籤和結束標籤之間的任何內容都會被拋棄。
當你想在一個插槽中使用數據時,例如:
<navigation-link url="/profile">
Logged in as {{ user.name }}
</navigation-link>
複製代碼
該插槽跟模板的其它地方同樣能夠訪問相同的實例屬性 (也就是相同的「做用域」),而不能訪問<navigation-link>
的做用域。例如 url
是訪問不到的:
<navigation-link url="/profile">
Clicking here will send you to: {{ url }}
<!--
這裏的 `url` 會是 undefined,由於 "/profile" 是
_傳遞給_ <navigation-link> 的而不是
在 <navigation-link> 組件*內部*定義的。
-->
</navigation-link>
複製代碼
做爲一條規則,請記住:
父級模板裏的全部內容都是在父級做用域中編譯的;子模板裏的全部內容都是在子做用域中編譯的。
有時爲一個插槽設置具體的後備 (也就是默認的) 內容是頗有用的,它只會在沒有提供內容的時候被渲染。例如在一個 <submit-button>
組件中:
<button type="submit">
<slot></slot>
</button>
複製代碼
咱們可能但願這個 <button>
內絕大多數狀況下都渲染文本「Submit」。爲了將「Submit」做爲後備內容,咱們能夠將它放在 <slot>
標籤內:
<button type="submit">
<slot>Submit</slot>
</button>
複製代碼
如今當我在一個父級組件中使用 <submit-button>
而且不提供任何插槽內容時:
<submit-button></submit-button>
複製代碼
後備內容「Submit」將會被渲染:
<button type="submit">
Submit
</button>
複製代碼
可是若是咱們提供內容:
<submit-button>
Save
</submit-button>
複製代碼
則這個提供的內容將會被渲染從而取代後備內容
<button type="submit">
Save
</button>
複製代碼
有時咱們須要多個插槽。例如對於一個帶有以下模板的 <base-layout>
組件:
<div class="container">
<header>
<!-- 咱們但願把頁頭放這裏 -->
</header>
<main>
<!-- 咱們但願把主要內容放這裏 -->
</main>
<footer>
<!-- 咱們但願把頁腳放這裏 -->
</footer>
</div>
複製代碼
對於這樣的狀況,<slot>
元素有一個特殊的 attribute:name
。這個 attribute
能夠用來定義額外的插槽:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
複製代碼
一個不帶 name
的 <slot>
出口會帶有隱含的名字「default」
在向具名插槽提供內容的時候,咱們能夠在一個 <template>
元素上使用 v-slot
指令,並以 v-slot
的參數的形式提供其名稱:
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
複製代碼
如今 <template>
元素中的全部內容都將會被傳入相應的插槽。任何沒有被包裹在帶有 v-slot
的 <template>
中的內容都會被視爲默認插槽的內容。0
然而,若是你但願更明確一些,仍然能夠在一個 <template>
中包裹默認插槽的內容:
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<template v-slot:default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
複製代碼
任何一種寫法都會渲染出:0
<div class="container">
<header>
<h1>Here might be a page title</h1>
</header>
<main>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</main>
<footer>
<p>Here's some contact info</p>
</footer>
</div>
複製代碼
注意 v-slot
只能添加在 <template>
上
有時讓插槽內容可以訪問子組件中才有的數據是頗有用的。例如,設想一個帶有以下模板的 <current-user>
組件:
<span>
<slot>{{ user.lastName }}</slot>
</span>
複製代碼
咱們可能想換掉備用內容,用名而非姓來顯示。以下:
<current-user>
{{ user.firstName }}
</current-user>
複製代碼
然而上述代碼不會正常工做,由於只有 <current-user>
組件能夠訪問到 user
而咱們提供的內容是在父級渲染的。
爲了讓 user
在父級的插槽內容中可用,咱們能夠將 user
做爲 <slot>
元素的一個 attribute
綁定上去:
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
複製代碼
綁定在 <slot>
元素上的 attribute
被稱爲插槽 prop
。如今在父級做用域中,咱們可使用帶值的 v-slot
來定義咱們提供的插槽 prop
的名字:
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
複製代碼
在這個例子中,咱們選擇將包含全部插槽 prop
的對象命名爲 slotProps
,但你也可使用任意你喜歡的名字。
在上述狀況下,當被提供的內容只有默認插槽時,組件的標籤才能夠被看成插槽的模板來使用。這樣咱們就能夠把 v-slot
直接用在組件上:
<current-user v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</current-user>
複製代碼
這種寫法還能夠更簡單。就像假定未指明的內容對應默認插槽同樣,不帶參數的 v-slot
被假定對應默認插槽:
<current-user v-slot="slotProps">
{{ slotProps.user.firstName }}
</current-user>
複製代碼
注意默認插槽的縮寫語法不能和具名插槽混用,由於它會致使做用域不明確:
<!-- 無效,會致使警告 -->
<current-user v-slot="slotProps">
{{ slotProps.user.firstName }}
<template v-slot:other="otherSlotProps">
slotProps is NOT available here
</template>
</current-user>
複製代碼
只要出現多個插槽,請始終爲全部的插槽使用完整的基於 <template>
的語法:
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
<template v-slot:other="otherSlotProps">
...
</template>
</current-user>
複製代碼
做用域插槽的內部工做原理是將你的插槽內容包括在一個傳入單個參數的函數裏:
function (slotProps) {
// 插槽內容
}
複製代碼
這意味着 v-slot
的值實際上能夠是任何可以做爲函數定義中的參數的 JavaScript
表達式。因此在支持的環境下 (單文件組件或現代瀏覽器),你也可使用 ES2015
解構來傳入具體的插槽 prop
,以下:
<current-user v-slot="{ user }">
{{ user.firstName }}
</current-user>
複製代碼
這樣可使模板更簡潔,尤爲是在該插槽提供了多個 prop
的時候。它一樣開啓了 prop
重命名等其它可能,例如將 user
重命名爲 person
:
<current-user v-slot="{ user: person }">
{{ person.firstName }}
</current-user>
複製代碼
你甚至能夠定義後備內容,用於插槽 prop
是 undefined
的情形:
<current-user v-slot="{ user = { firstName: 'Guest' } }">
{{ user.firstName }}
</current-user>
複製代碼
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>
複製代碼
跟 v-on
和 v-bind
同樣,v-slot
也有縮寫,即把參數以前的全部內容 (v-slot
:) 替換爲字符 #
。例如v-slot:header
能夠被重寫爲 #header
:
<base-layout>
<template #header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template #footer>
<p>Here's some contact info</p>
</template>
</base-layout>
複製代碼
然而,和其它指令同樣,該縮寫只在其有參數的時候纔可用。這意味着如下語法是無效的:
<!-- 這樣會觸發一個警告 -->
<current-user #="{ user }">
{{ user.firstName }}
</current-user>
複製代碼
若是你但願使用縮寫的話,你必須始終以明確插槽名取而代之:
<current-user #default="{ user }">
{{ user.firstName }}
</current-user>
複製代碼
插槽 prop
容許咱們將插槽轉換爲可複用的模板,這些模板能夠基於輸入的 prop
渲染出不一樣的內容。這在設計封裝數據邏輯同時容許父級組件自定義部分佈局的可複用組件時是最有用的。
例如,咱們要實現一個 <todo-list>
組件,它是一個列表且包含佈局和過濾邏輯:
<ul>
<li
v-for="todo in filteredTodos"
v-bind:key="todo.id"
>
{{ todo.text }}
</li>
</ul>
複製代碼
咱們能夠將每一個 todo
做爲父級組件的插槽,以此經過父級組件對其進行控制,而後將 todo
做爲一個插槽prop
進行綁定:
<ul>
<li
v-for="todo in filteredTodos"
v-bind:key="todo.id"
>
<!--
咱們爲每一個 todo 準備了一個插槽,
將 `todo` 對象做爲一個插槽的 prop 傳入。
-->
<slot name="todo" v-bind:todo="todo">
<!-- 後備內容 -->
{{ todo.text }}
</slot>
</li>
</ul>
複製代碼
如今當咱們使用 <todo-list>
組件的時候,咱們能夠選擇爲 todo
定義一個不同的 <template>
做爲替代方案,而且能夠從子組件獲取數據:
<todo-list v-bind:todos="todos">
<template v-slot:todo="{ todo }">
<span v-if="todo.isComplete">✓</span>
{{ todo.text }}
</template>
</todo-list>
複製代碼
從新建立動態組件的行爲一般是很是有用的,可是有一些標籤的組件實例可以被在它們第一次被建立的時候緩存下來。爲了解決這個問題,咱們能夠用一個 <keep-alive>
元素將其動態組件包裹起來。
<!-- 失活的組件將會被緩存!-->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
複製代碼
當頁面加載時,該元素將得到焦點 (注意:autofocus
在移動版 Safari
上不工做)。事實上,只要你在打開這個頁面後還沒點擊過任何內容,這個輸入框就應當仍是處於聚焦狀態。如今讓咱們用指令來實現這個功能:
// 註冊一個全局自定義指令 `v-focus`
Vue.directive('focus', {
// 當被綁定的元素插入到 DOM 中時……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
複製代碼
若是想註冊局部指令,組件中也接受一個 directives
的選項:
directives: {
focus: {
// 指令的定義
inserted: function (el) {
el.focus()
}
}
}
複製代碼
而後你能夠在模板中任何元素上使用新的 v-focus
屬性,以下:
<input v-focus>
複製代碼
一個指令定義對象能夠提供以下幾個鉤子函數 (均爲可選):
bind
:只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置。
inserted
:被綁定元素插入父節點時調用 (僅保證父節點存在,但不必定已被插入文檔中)。
update
:所在組件的 VNode
更新時調用,可是可能發生在其子 VNode
更新以前。指令的值可能發生了改變,也可能沒有。可是你能夠經過比較更新先後的值來忽略沒必要要的模板更新 (詳細的鉤子函數參數見下)。
componentUpdated
:指令所在組件的 VNode
及其子 VNode
所有更新後調用。
unbind
:只調用一次,指令與元素解綁時調用。
接下來咱們來看一下鉤子函數的參數 (即 el
、binding
、vnode
和 oldVnode
)。
指令鉤子函數會被傳入如下參數:
el
:指令所綁定的元素,能夠用來直接操做 DOM
。binding
:一個對象,包含如下屬性:
name
:指令名,不包括 v-
前綴。value
:指令的綁定值,例如:v-my-directive="1 + 1"
中,綁定值爲 2
。oldValue
:指令綁定的前一個值,僅在 update
和 componentUpdated
鉤子中可用。不管值是否改變均可用。expression
:字符串形式的指令表達式。例如 v-my-directive="1 + 1"
中,表達式爲 "1 + 1"
。arg
:傳給指令的參數,可選。例如 v-my-directive:foo
中,參數爲 "foo"
。modifiers
:一個包含修飾符的對象。例如:v-my-directive.foo.bar
中,修飾符對象爲{ foo: true, bar: true }
。vnode
:Vue
編譯生成的虛擬節點。移步 VNode
API 來了解更多詳情。oldVnode
:上一個虛擬節點,僅在 update
和 componentUpdated
鉤子中可用。除了
el
以外,其它參數都應該是隻讀的,切勿進行修改。若是須要在鉤子之間共享數據,建議經過元素的dataset
來進行。
Vue.js
容許你自定義過濾器,可被用於一些常見的文本格式化。過濾器能夠用在兩個地方:雙花括號插值和 v-bind
表達式 (後者從 2.1.0+
開始支持)。過濾器應該被添加在 JavaScript
表達式的尾部,由「管道」符號指示:
<!-- 在雙花括號中 -->
{{ message | capitalize }}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>
複製代碼
你能夠在一個組件的選項中定義本地的過濾器:
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
複製代碼
或者在建立 Vue 實例以前全局定義過濾器:
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
new Vue({
// ...
})
複製代碼
當全局過濾器和局部過濾器重名時,會採用局部過濾器。
過濾器是 JavaScript 函數,所以能夠接收參數:
{{ message | filterA('arg1', arg2) }}
複製代碼
這裏,filterA
被定義爲接收三個參數的過濾器函數。其中 message
的值做爲第一個參數,普通字符串 'arg1'
做爲第二個參數,表達式arg2
的值做爲第三個參數。
分享不易,喜歡的話必定別忘了點💖!!!
只關注不點💖的都是耍流氓,只收藏也不點💖的也同樣是耍流氓。
結束👍👍👍。