search
HomeWeb Front-endVue.jsLet's talk about the pointing problem of this in vue2.x. Why does it point to the vue instance?

This article will talk about the pointing problem of this in vue2.x, and introduce why this points to the vue instance. I hope it will be helpful to everyone!

Let's talk about the pointing problem of this in vue2.x. Why does it point to the vue instance?

The code walkthrough in the group accidentally mentioned why this can be directly called to the values ​​in data, methods, props, and computed. Then everyone had some guesses, but none of them were clear. In order to clarify this question, I checked the source code of vue. I have some understanding and wrote an article to record it.

Throw a question

Normally develop vue code, almost always write it like this

export default {
    data() {
        return {
            name: '彭鱼宴'
        }
    },
    methods: {
        greet() {
            console.log(`hello, 我是${this.name}`)
        }
    }
}

Why can this.name here directly access data? What about the name defined in, or this.someFn can directly access the function defined in methods? With this question, I started to look at the source code of vue2.x to find the answer.

Source code analysis

Here is the source code address of vuevue source code. Let’s first take a look at the constructor of the vue instance. The constructor is in the source code directory/vue/src/core/instance/index.js. There is not much code. Post it all to see.

function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue

The constructor is very Simple, if (!(this instanceof Vue)){} Determine whether the new keyword is used to call the constructor, if not, a warning will be thrown, here is this refers to an instance of Vue. If the new keyword is used normally, just use the _init function. Isn’t it very simple?

_init function analysis

let uid = 0

export function initMixin (Vue: Class<Component>) {
  Vue.prototype._init = function (options?: Object) {
    const vm: Component = this
    // a uid
    vm._uid = uid++

    let startTag, endTag
    /* istanbul ignore if */
    if (process.env.NODE_ENV !== &#39;production&#39; && config.performance && mark) {
      startTag = `vue-perf-start:${vm._uid}`
      endTag = `vue-perf-end:${vm._uid}`
      mark(startTag)
    }

    // a flag to avoid this being observed
    vm._isVue = true
    // merge options
    if (options && options._isComponent) {
      // optimize internal component instantiation
      // since dynamic options merging is pretty slow, and none of the
      // internal component options needs special treatment.
      initInternalComponent(vm, options)
    } else {
      vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
      )
    }
    /* istanbul ignore else */
    if (process.env.NODE_ENV !== &#39;production&#39;) {
      initProxy(vm)
    } else {
      vm._renderProxy = vm
    }
    // expose real self
    vm._self = vm
    initLifecycle(vm)
    initEvents(vm)
    initRender(vm)
    callHook(vm, &#39;beforeCreate&#39;)
    initInjections(vm) // resolve injections before data/props
    initState(vm)
    initProvide(vm) // resolve provide after data/props
    callHook(vm, &#39;created&#39;)

    /* istanbul ignore if */
    if (process.env.NODE_ENV !== &#39;production&#39; && config.performance && mark) {
      vm._name = formatComponentName(vm, false)
      mark(endTag)
      measure(`vue ${vm._name} init`, startTag, endTag)
    }

    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }
  }
}

_The init function is a bit long and does a lot of things, so I won’t explain it one by one here, and we will explore it this time The relevant content should be in the initState(vm) function. Let's continue to the initState function.

initState function analysis

export function initState (vm: Component) {
  vm._watchers = []
  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)
  if (opts.methods) initMethods(vm, opts.methods)
  if (opts.data) {
    initData(vm)
  } else {
    observe(vm._data = {}, true /* asRootData */)
  }
  if (opts.computed) initComputed(vm, opts.computed)
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }
}

It can be seen that initState has done 5 things

  • Initialize props
  • Initialization methods
  • Initialization data
  • Initialization computed
  • Initialization watch

Let’s first focus on what the initialization methods do

initMethods initialization method

function initMethods (vm, methods) {
    var props = vm.$options.props;
    for (var key in methods) {
      {
        if (typeof methods[key] !== &#39;function&#39;) {
          warn(
            "Method \"" + key + "\" has type \"" + (typeof methods[key]) + "\" in the component definition. " +
            "Did you reference the function correctly?",
            vm
          );
        }
        if (props && hasOwn(props, key)) {
          warn(
            ("Method \"" + key + "\" has already been defined as a prop."),
            vm
          );
        }
        if ((key in vm) && isReserved(key)) {
          warn(
            "Method \"" + key + "\" conflicts with an existing Vue instance method. " +
            "Avoid defining component methods that start with _ or $."
          );
        }
      }
      vm[key] = typeof methods[key] !== &#39;function&#39; ? noop : bind(methods[key], vm);
    }
}

initMethods mainly consists of some judgments:

判断methods中定义的函数是不是函数,不是函数就抛warning;
判断methods中定义的函数名是否与props冲突,冲突抛warning;
判断methods中定义的函数名是否与已经定义在Vue实例上的函数相冲突,冲突的话就建议开发者用_或者$开头命名;

Except for the above judgments, the most important thing is in vue All methods in methods are defined on the instance, and the bind function is used to point the function's this to the Vue instance, which is the instance object of our new Vue().

This explains why this can directly access the methods in methods.

initData initializes data

function initData (vm) {
    var data = vm.$options.data;
    data = vm._data = typeof data === &#39;function&#39;
      ? getData(data, vm)
      : data || {};
    if (!isPlainObject(data)) {
      data = {};
      warn(
        &#39;data functions should return an object:\n&#39; +
        &#39;https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function&#39;,
        vm
      );
    }
    // proxy data on instance
    var keys = Object.keys(data);
    var props = vm.$options.props;
    var methods = vm.$options.methods;
    var i = keys.length;
    while (i--) {
      var key = keys[i];
      {
        if (methods && hasOwn(methods, key)) {
          warn(
            ("Method \"" + key + "\" has already been defined as a data property."),
            vm
          );
        }
      }
      if (props && hasOwn(props, key)) {
        warn(
          "The data property \"" + key + "\" is already declared as a prop. " +
          "Use prop default value instead.",
          vm
        );
      } else if (!isReserved(key)) {
        proxy(vm, "_data", key);
      }
    }
    // observe data
    observe(data, true /* asRootData */);
}

What does initdata do:

  • First assign a value to the instance_data, and the getData function processes the data This function returns an object
  • to judge the data finally obtained, not the object to give a warning.
  • Determine whether the function in methods conflicts with the key in data
  • Determine whether there is a conflict between props and the key in data
  • Determine whether it is an internal private reserved attribute. If not, make a layer of proxy and proxy it to _data
  • Finally listen to the data and make it responsive data

Let’s take a look at what the proxy function does:

function noop (a, b, c) {}
var sharedPropertyDefinition = {
    enumerable: true,
    configurable: true,
    get: noop,
    set: noop
};

function proxy (target, sourceKey, key) {
    sharedPropertyDefinition.get = function proxyGetter () {
      return this[sourceKey][key]
    };
    sharedPropertyDefinition.set = function proxySetter (val) {
      this[sourceKey][key] = val;
    };
    Object.defineProperty(target, key, sharedPropertyDefinition);
}

In fact, the Object.defineProperty here is used to define the object. The purpose of

proxy is to use this.namePoint tothis._data.name

The remaining observe functions are not within the scope of this discussion. Interested friends can check out the source code themselves.

Summary

Go back to the question raised at the beginning and give an answer:

  • methods The method in bind specifies this as an instance of new Vue (vm), and the functions in methods are also defined in vm is installed, so you can directly access the functions in methods through this.

  • dataThe data objects returned by the function are also stored in _data## on the new Vue instance (vm) #Up, when accessing this.name, what is actually accessed is Object.defineProperty after proxy this._data.name.

As for the advantages and disadvantages of this design pattern of data, you can continue to explore, after all, it is not part of this discussion.

[Related recommendations:

vue.js video tutorial]

The above is the detailed content of Let's talk about the pointing problem of this in vue2.x. Why does it point to the vue instance?. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:掘金社区. If there is any infringement, please contact admin@php.cn delete
Frontend Development with Vue.js: Advantages and TechniquesFrontend Development with Vue.js: Advantages and TechniquesMay 03, 2025 am 12:02 AM

Reasons for Vue.js' popularity include simplicity and easy learning, flexibility and high performance. 1) Its progressive framework design is suitable for beginners to learn step by step. 2) Component-based development improves code maintainability and team collaboration efficiency. 3) Responsive systems and virtual DOM improve rendering performance.

Vue.js vs. React: Ease of Use and Learning CurveVue.js vs. React: Ease of Use and Learning CurveMay 02, 2025 am 12:13 AM

Vue.js is easier to use and has a smooth learning curve, which is suitable for beginners; React has a steeper learning curve, but has strong flexibility, which is suitable for experienced developers. 1.Vue.js is easy to get started with through simple data binding and progressive design. 2.React requires understanding of virtual DOM and JSX, but provides higher flexibility and performance advantages.

Vue.js vs. React: Which Framework is Right for You?Vue.js vs. React: Which Framework is Right for You?May 01, 2025 am 12:21 AM

Vue.js is suitable for fast development and small projects, while React is more suitable for large and complex projects. 1.Vue.js is simple and easy to learn, suitable for rapid development and small projects. 2.React is powerful and suitable for large and complex projects. 3. The progressive features of Vue.js are suitable for gradually introducing functions. 4. React's componentized and virtual DOM performs well when dealing with complex UI and data-intensive applications.

Vue.js vs. React: A Comparative Analysis of JavaScript FrameworksVue.js vs. React: A Comparative Analysis of JavaScript FrameworksApr 30, 2025 am 12:10 AM

Vue.js and React each have their own advantages and disadvantages. When choosing, you need to comprehensively consider team skills, project size and performance requirements. 1) Vue.js is suitable for fast development and small projects, with a low learning curve, but deep nested objects can cause performance problems. 2) React is suitable for large and complex applications, with a rich ecosystem, but frequent updates may lead to performance bottlenecks.

Vue.js vs. React: Use Cases and ApplicationsVue.js vs. React: Use Cases and ApplicationsApr 29, 2025 am 12:36 AM

Vue.js is suitable for small to medium-sized projects, while React is suitable for large projects and complex application scenarios. 1) Vue.js is easy to use and is suitable for rapid prototyping and small applications. 2) React has more advantages in handling complex state management and performance optimization, and is suitable for large projects.

Vue.js vs. React: Comparing Performance and EfficiencyVue.js vs. React: Comparing Performance and EfficiencyApr 28, 2025 am 12:12 AM

Vue.js and React each have their own advantages: Vue.js is suitable for small applications and rapid development, while React is suitable for large applications and complex state management. 1.Vue.js realizes automatic update through a responsive system, suitable for small applications. 2.React uses virtual DOM and diff algorithms, which are suitable for large and complex applications. When selecting a framework, you need to consider project requirements and team technology stack.

Vue.js vs. React: Community, Ecosystem, and SupportVue.js vs. React: Community, Ecosystem, and SupportApr 27, 2025 am 12:24 AM

Vue.js and React each have their own advantages, and the choice should be based on project requirements and team technology stack. 1. Vue.js is community-friendly, providing rich learning resources, and the ecosystem includes official tools such as VueRouter, which are supported by the official team and the community. 2. The React community is biased towards enterprise applications, with a strong ecosystem, and supports provided by Facebook and its community, and has frequent updates.

React and Netflix: Exploring the RelationshipReact and Netflix: Exploring the RelationshipApr 26, 2025 am 12:11 AM

Netflix uses React to enhance user experience. 1) React's componentized features help Netflix split complex UI into manageable modules. 2) Virtual DOM optimizes UI updates and improves performance. 3) Combining Redux and GraphQL, Netflix efficiently manages application status and data flow.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

Atom editor mac version download

Atom editor mac version download

The most popular open source editor