preface

The Select drop-down box is often used in form submission and search, and component libraries have packages for related components, such as ant-Design-Vue’s A-select, Element-UI’s el-select, Usage is common selection, multiple selection, search enabled selection, linkage, and so on, yet none of these common components provide beforeChange hooks.

Have you ever had to intercept a select switch? I met such a requirement today, and gave three implementation solutions after thinking about it.

Effect:

Online test address

The main points of

The official documentation for native SELECT, A-SELECT, and el-Select does not show that they provide hooks like beforeChange events, but only callbacks for change events with changed options. In this way, if you bind the popover event in the change event, it will cause that when the Modal dialog box pops up, the options have changed, and then you choose to cancel the operation, you still need data backtracking, and the visual experience is not good. I offer three solutions to this problem.

event.stopPropagation

The idea is to block the propagation of the event by adding a click event to the DOM under a-select-option with an event modifier click.stop.

<div @click.stop="handleClick"> </div> </a-select-option> methods: {handleClick(item) {let _this = this _this.$confirm({title: "Do you want to switch?" Mask: false, onOk() {_this.data.value = item.value}, onCancel() {},}); }}Copy the code

Object.defineProperty

The object.defineProperty () method allows you to describe an Object by property, define or modify a property, and then return the modified Object. See the Attribute Description Object section in the javascript tutorial of this book for the syntax. Here I use its store function set to handle data.value

<a-select centered default-value="lucy" style="width: 120px" V-model ="data.value" > <a-select-option value=" Shanghai "> < A-select-option value=" Shanghai "</a-select-option> <a-select-option value=" Shanghai" </a-select-option> </a-select-option value=" shenzhen "</a-select-option> </a-select> methods: { initProxy() { let _this = this Object.defineProperty(this.data, "value", { set: Function (value) {_this.$confirm({title: "reloading ", content:" reloading ", mask: false, onOk() { return value }, onCancel() {}, }); }, }) }, mounted() { this.initProxy() }Copy the code

The Proxy to intercept

The Proxy can intercept the value of a-select and then modify its default behavior, unlike directly modifying the value. Equivalent to making changes at the language level, it is a kind of “meta programming”, that is, programming a programming language.

The syntax of ECMAScript6 is described in the proxy section of ECMAScript6.

<a-select centered default-value="lucy" style="width: 120px" V-model ="data.value" > <a-select-option value=" Shanghai "> < A-select-option value=" Shanghai "</a-select-option> <a-select-option value=" Shanghai" </a-select-option> </a-select-option value=" shenzhen "</a-select-option> </a-select> methods: { initProxy() { let _this = this; This. Data = new Proxy({value: "Shanghai"}, {set: function (target, propKey, value) {return _this.$confirm({title: "Sure you want to switch?" , content: "Switching reseller will reload page data ", mask: false, onOk() { target["value"] = value }, onCancel() {}, }) }, } ) }, }, mounted() { this.initProxy() },Copy the code

By the way, the V-model of a-select supports only input events by default. The source code of Ant-Design-Vue overwrites the V-model directive with the model option and changes its trigger condition to change.

  model: {
    prop: 'value',
    event: 'change'
  }
Copy the code

All the above three schemes can achieve the effect we want. As for which is better, there is no need to tangle, depending on your preferences, because the requirements are not complex enough to reflect the differences between them.

conclusion

Today, through a select interception requirement (radio, checkbox, the same thing), to explain to you the application of the relevant knowledge of event passing, object.defineProperty, proxy, I do not know if you have found these tools only often used features. It can also serve the daily business development well, isn’t it a cool thing? Did you get anything out of it?


Collection: My Github blog and case source code