Vue.js中this如何取到data和method里的属性详解

 更新时间:2022年12月06日 09:46:30   作者:前端摸鱼儿  
methods属性是一个对象,通常我们会在这个对象中定义很多的方法,下面这篇文章主要给大家介绍了关于Vue.js中this如何取到data和method里的属性,需要的朋友可以参考下

本篇文章介绍的是Vue.js如何取到datamethods里的属性?

准备工作

  • 克隆源码到本地
git clone https://github.com/vuejs/vue.git

下载完毕后,用vscode打开,目光移动到package.jsonscripts属性,我们看到有devbuilddev会启动一个开发环境的服务,也就是说,我们在源码里做的改动,都会及时生效。build就是打包。和我们平时开发Vue.js项目是一个道理。

我们首先安装一下Vue.js项目的依赖(使用pnpm),然后运行npm run dev。这样的好处就是我们能随时看到代码改动后的效果。

  • 接下来我们在examples目录下创建一个html文件,引入打包后的vue.js
<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="UTF-8" />
   <meta http-equiv="X-UA-Compatible" content="IE=edge" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <title>Document</title>
 </head>
 <body>
   <div id="app">
     <h1 @click="changeMsg">hello {{msg}}</h1>
   </div>
   <script src="../dist/vue.js"></script>
   <script>
     const vm = new Vue({
       el: '#app',
       data: {
         msg: 'world'
       },
       methods: {
         changeMsg() {
           this.msg = 'me'
         }
       }
     })
   </script>
 </body>
</html>
  • 安装一个serve全局包启动, 在根目录运行一下serve,就能看到页面展示出来了。

调试源码

我们这里使用谷歌浏览器调试,F12找到sources面板如下图所示的位置打上断点,接着刷新页面,就进入了调试模式。

然后,我们就通过step into按钮进入new Vue的函数内部。 接着进入_init的内部,找到initState(vm),也就是当前文件代码的4714行,这个函数的内部就是我们要研究的部分。

进入initState内部,我们看到

  if (opts.methods)
          initMethods(vm, opts.methods);
      if (opts.data) {
          initData(vm);
      }

initMethods

function initMethods(vm, methods) {
      var props = vm.$options.props;
      for (var key in methods) {
          {
              if (typeof methods[key] !== 'function') {
                  warn$2("Method \"".concat(key, "\" has type \"").concat(typeof methods[key], "\" in the component definition. ") +
                      "Did you reference the function correctly?", vm);
              }
              if (props && hasOwn(props, key)) {
                  warn$2("Method \"".concat(key, "\" has already been defined as a prop."), vm);
              }
              if (key in vm && isReserved(key)) {
                  warn$2("Method \"".concat(key, "\" conflicts with an existing Vue instance method. ") +
                      "Avoid defining component methods that start with _ or $.");
              }
          }
          vm[key] = typeof methods[key] !== 'function' ? noop : bind$1(methods[key], vm);
      }
  }
  • 首先判断组件内部是否声明了函数
  • 其次判断是否和props、保留键名的名字冲突了
  • 最后是处理逻辑,如果对应值的类型是函数将传入的vm对应的属性赋值,否则为noop,赋值的函数这里做了一个强绑(使用的bind, this指向vm)。这个bind$来自原生的bind方法
var bind$1 = Function.prototype.bind ? nativeBind : polyfillBind;

initData

调试完了initMehtods后,就开始initData,我们使用step out按钮就跳出了当前函数,接着进入initData内部。

function initData(vm) {
      var data = vm.$options.data;
      data = vm._data = isFunction(data) ? getData(data, vm) : data || {};
      if (!isPlainObject(data)) {
          data = {};
          warn$2('data functions should return an object:\n' +
                  'https://v2.vuejs.org/v2/guide/components.html#data-Must-Be-a-Function', 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$2("Method \"".concat(key, "\" has already been defined as a data property."), vm);
              }
          }
          if (props && hasOwn(props, key)) {
              warn$2("The data property \"".concat(key, "\" is already declared as a prop. ") +
                      "Use prop default value instead.", vm);
          }
          else if (!isReserved(key)) {
              proxy(vm, "_data", key);
          }
      }
      // observe data
      var ob = observe(data);
      ob && ob.vmCount++;
  }

逻辑和initMethods类似,和propsmethods做了比对,最后通过proxydata,绑定到vm

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);
  }

最终我们知道data的值是通过Object.defineProperty,实现绑定的。

结束语

我们要研究一个源码,首先要准备源码、serve、和调试工具(谷歌浏览器),然后进入代码的内部,才能看的清楚明白,我们就此知道了Vue.jsthis如何取到datamethods的属性。

到此这篇关于Vue.js中this如何取到data和method里的属性的文章就介绍到这了,更多相关Vue.js this取data和method属性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解在vue-cli中使用graphql即vue-apollo的用法

    详解在vue-cli中使用graphql即vue-apollo的用法

    这篇文章主要介绍了详解在vue-cli中使用graphql即vue-apollo的用法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • Vue下拉菜单组件化开发详解

    Vue下拉菜单组件化开发详解

    这篇文章主要为大家详细介绍了Vue下拉菜单组件化开发过程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Vue 加载远程组件的解决方案

    Vue 加载远程组件的解决方案

    最近的项目有一个加载远程组件的需求,基于此我对 Vue 加载远程组件的方案进行了研究,并且整理了两个可行的解决方案,有感兴趣的小伙伴跟着小编一起来看看吧
    2023-07-07
  • vue 添加和编辑用同一个表单,el-form表单提交后清空表单数据操作

    vue 添加和编辑用同一个表单,el-form表单提交后清空表单数据操作

    这篇文章主要介绍了vue 添加和编辑用同一个表单,el-form表单提交后清空表单数据操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • vue parseHTML函数源码解析start钩子函数

    vue parseHTML函数源码解析start钩子函数

    这篇文章主要为大家介绍了vue parseHTML函数源码解析start钩子函数,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Vue.js移动端左滑删除组件的实现代码

    Vue.js移动端左滑删除组件的实现代码

    本篇文章主要介绍了Vue.js移动端左滑删除组件的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • vue.js模仿京东省市区三级联动的选择组件实例代码

    vue.js模仿京东省市区三级联动的选择组件实例代码

    选择省市区是我们大家在填写地址的时候经常会遇到的一个功能,下面这篇文章主要给大家介绍了关于利用vue.js模仿实现京东省市区三级联动选择组件的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-11-11
  • VUE3中的函数的声明和使用

    VUE3中的函数的声明和使用

    这篇文章主要介绍了VUE3中的函数的声明和使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • Vue nextTick的原理解析

    Vue nextTick的原理解析

    这篇文章主要介绍了Vue nextTick的原理解析,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下
    2021-04-04
  • vue2.0.js的多级联动选择器实现方法

    vue2.0.js的多级联动选择器实现方法

    下面小编就为大家分享一篇vue2.0.js的多级联动选择器实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02

最新评论