Vue.$set failure pitfall discovery and solution

Vue.$set failure pitfall discovery and solution

I accidentally found that Vue.$set was invalid in the project

There is a requirement to add data filtering. The left side is the control selection, the middle is the condition, and the right side is the value.

Because different value option controls will be rendered depending on the control

    <el-form inline>
      <el-form-item style="margin-bottom: 20px;">
        <el-select v-model="data[props.prop]" @change="data[props.value] = ''">
          <el-option
            v-for="item in controls"
            :key="item.id"
            :value="item.id"
            :label="item.label">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item style="margin-bottom: 20px;">
        <el-select v-model="data[props.type]">
          <el-option
            v-for="item in condition"
            :key="item.code"
            :value="item.code"
            :label="item.name"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item style="margin-bottom: 20px;">
        <FormControl v-if="control" :control="control" :value="data[props.value]" @input="onValueChange" ></FormControl>
        <el-input v-else :value="data[props.value]" @input="onValueChange"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-plus" @click="add"></el-button>
      </el-form-item>
    </el-form>
{
  props:{
    props: {
      type: Object,
      default: () => ({
        prop: 'prop',
        value: 'value',
        type: 'type'
      })
    }
  },
  data(){
    return {
      data:{
        
      }
    }
  },
  methods:{
    onValueChange(val){
      this.$set(this.data, this.props.value, val)
    }
  }
  //...
}

Code Snippet

Due to the uncertainty of the control ID, all data cannot be preset with a key in advance, so it is naturally impossible to respond. Therefore, this.$set is used in onValueChange to dynamically add data to achieve response.

Reproduction can find that the data in the value input box cannot respond in real time

I used $set but it didn't respond. After some investigation, I found that the value would not respond after switching the control. However, as long as I input something before switching and then switch, there would be no problem.

After another investigation, we found

<el-select v-model="data[props.prop]" @change="data[props.value] = ''">

The problem is solved after deleting the @change event

The problem occurs when data[props.value] = ''

So check the Vue source code

//vue/src/core/observer/index.js source code snippet/**
 * Set a property on an object. Adds the new property and
 * triggers change notification if the property doesn't
 * already exists.
 */
export function set (target: Array<any> | Object, key: any, val: any): any {
  if (process.env.NODE_ENV !== 'production' &&
    (isUndef(target) || isPrimitive(target))
  ) {
    warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`)
  }
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.length = Math.max(target.length, key)
    target.splice(key, 1, val)
    return val
  }
  if (key in target && !(key in Object.prototype)) {
    target[key] = val
    return val
  }
  const ob = (target: any).__ob__
  if (target._isVue || (ob && ob.vmCount)) {
    process.env.NODE_ENV !== 'production' && warn(
      'Avoid adding reactive properties to a Vue instance or its root $data ' +
      'at runtime - declare it upfront in the data option.'
    )
    return val
  }
  if (!ob) {
    target[key] = val
    return val
  }
  defineReactive(ob.value, key, val)
  ob.dep.notify()
  return val
}

It can be found that before defineReactive, it is determined whether the key exists in the object. If it exists, it is skipped.

The pit is here. I have read the Vue.$set document many times and did not find that $set cannot add monitoring objects to existing keys.

Delete data[props.value] = '' and change it to onValueChange('') ​​to solve the problem perfectly

Summarize

Before Vue.$set, the key must not exist in the object, otherwise it will only update the value and will not add response monitoring for the key

The above is my personal experience. I hope it can give you a reference. I also hope that you will support 123WORDPRESS.COM.

You may also be interested in:
  • Case study of dynamic data binding of this.$set in Vue
  • Vue——Solving the error Computed property "****" was assigned to but it has no setter.
  • Use of setup in vue3.0 (two ways of use)
  • A brief discussion on the precautions for using resetFields() in Vue
  • Vue's vue.$set() method source code case detailed explanation

<<:  Four modes of Oracle opening and closing

>>:  Overview of the Differences between Linux TTY/PTS

Recommend

Detailed explanation of keepAlive use cases in Vue

In development, it is often necessary to cache th...

Detailed explanation of MySQL precompilation function

This article shares the MySQL precompilation func...

Sample code for deploying ELK using Docker-compose

environment Host IP 192.168.0.9 Docker version 19...

Install Kafka in Linux

Table of contents 1.1 Java environment as a prere...

vue+element-ui implements the head navigation bar component

This article shares the specific code of vue+elem...

Ubuntu 16.04 64-bit compatible with 32-bit programs in three steps

Step 1: Confirm the architecture of your system d...

Nginx cache files and dynamic files automatic balancing configuration script

nginx Nginx (engine x) is a high-performance HTTP...

Examples of using Docker and Docker-Compose

Docker is an open source container engine that he...

Vue implements setting multiple countdowns at the same time

This article example shares the specific code of ...

Example code for element multiple tables to achieve synchronous scrolling

Element UI implements multiple tables scrolling a...

How to use js to determine whether a file is utf-8 encoded

Conventional solution Use FileReader to read the ...

Detailed introduction to CSS font, text, and list properties

1. Font properties color, specifies the color of ...

How to Install Xrdp Server (Remote Desktop) on Ubuntu 20.04

Xrdp is an open source implementation of Microsof...

JavaScript to achieve floor effect

This article shares the specific code of JavaScri...

npm Taobao mirror modification explanation

1. Top-level usage 1. Install cnpm npm i -g cnpm ...