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

Meta viewport makes the web page full screen display control on iPhone

In desperation, I suddenly thought, how is the Sin...

Use viewport in meta tag to define screen css

<meta name="viewport" content="w...

An example of elegantly writing status labels in Vue background

Table of contents Preface optimization Extract va...

Getting Started Tutorial on Animating SVG Path Strokes Using CSS3

Without relying on JavaScript, pure CSS is used t...

Nginx load balancing algorithm and failover analysis

Overview Nginx load balancing provides upstream s...

Detailed explanation of nginx optimization in high concurrency scenarios

In daily operation and maintenance work, nginx se...

Vue implements calling PC camera to take photos in real time

Vue calls the PC camera to take pictures in real ...

Tips for List Building for Website Maintenance Pages

And, many times, maintenance requires your website...

Complete steps to build a squid proxy server in linux

Preface This article mainly introduces the releva...

MySQL 8.0.12 installation and configuration method graphic tutorial (windows10)

This article records the installation graphic tut...

Linux uses stty to display and modify terminal line settings

Sttty is a common command for changing and printi...

Implementing CommonJS modularity in browsers without compilation/server

Table of contents introduction 1. What is one-cli...

Description of the hr tag in various browsers

Generally, we rarely meet HR, but once we do, it c...

zabbix custom monitoring nginx status implementation process

Table of contents Zabbix custom monitoring nginx ...