ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue学习05

2022-05-12 13:03:45  阅读:171  来源: 互联网

标签:function vue methods 05 watch vm 学习 key opts


 methods中定义了Vue实例的方法,官网是这样介绍的:

例如::

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="app">{{message}}<button @click="ChangeMessage">测试按钮</button></div>
    <script>
        new Vue({
            el:'#app',
            data:{message:"Hello World!"},
            methods:{
                ChangeMessage:function(){this.message="Hello Vue!";}
            }
        })
    </script>
</body>
</html>

显示的样式为:

当我们点击按钮后变为了:

methods方法中的上下文为当前实例,也就是this为当前实例。

 注:不应该使用箭头函数来定义 method 函数 (例如ChangeMessage:()=>this.message="Hello Vue")。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.message 将是 undefined。

 源码分析


  Vue实例后会先执行_init()进行初始化(4579行)时,会执行initState()进行初始化,如下:

function initState (vm) { //第3303行
  vm._watchers = [];
  var opts = vm.$options;
  if (opts.props) { initProps(vm, opts.props); }
  if (opts.methods) { initMethods(vm, opts.methods); }        //如果定义了methods,则调用initMethods初始化data
  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);
  }
}

 initMethods()定义如下:

function initMethods (vm, methods) {   //第3513行
  var props = vm.$options.props;
  for (var key in methods) {                 //遍历methods对象,key是每个键,比如例子里的ChangeMessage
    {
      if (methods[key] == null) {         //如果值为null,则报错
        warn(
          "Method \"" + key + "\" has an undefined value in the component definition. " +
          "Did you reference the function correctly?",
          vm
        );
      } 
      if (props && hasOwn(props, key)) {     //如果props中有同名属性,则报错
        warn(
          ("Method \"" + key + "\" has already been defined as a prop."),
          vm
        );
      }
      if ((key in vm) && isReserved(key)) {   //如果key是以$或_开头则,也报错
        warn(
          "Method \"" + key + "\" conflicts with an existing Vue instance method. " +
          "Avoid defining component methods that start with _ or $."
        );
      }
    }
    vm[key] = methods[key] == null ? noop : bind(methods[key], vm);             //如果key对应的值不是null,则执行bind()函数
  }
}

执行bind()函数,参数1为对应的函数体,参数2是当前的Vue实例,如下:

function polyfillBind (fn, ctx) {            //当Function的原型上不存在bind()函数时,自定义一个函数实现同样的功能,用apply()或call()来实现
  function boundFn (a) {
    var l = arguments.length;
    return l
      ? l > 1
        ? fn.apply(ctx, arguments)
        : fn.call(ctx, a)
      : fn.call(ctx)
  }

  boundFn._length = fn.length;
  return boundFn
}

function nativeBind (fn, ctx) {             //调用Function的原型上的bind()方法,上下文闻ctx
  return fn.bind(ctx)
}

var bind = Function.prototype.bind             //如果Function的原型上有bind方法,则调用该方法,否则用自定义的polyfillBind()方法
  ? nativeBind
  : polyfillBind;

相比较其它API,method的实现是比较简单的。

vue--watch属性

Vue提供了一个watch方法可以让使用者去监听某些data内的数据变动,触发相应的方法,比如

queryData: {
     name: '',
     creator: '',
     selectedStatus: '',
     time: [],
 },

注: 下面watch后的函数上都可以拿到 新值和老值  function(val, oldVal){ /*do something*/} 

现在我需要监听这个queryData,我可以这样做:

watch: {
     queryData: {
         handler: function() {
            //do something
         },
         deep: true
     }
}

里面的deep设为了true,这样的话,如果修改了这个queryData中的任何一个属性,都会执行handler这个方法。不过其实这样开销是蛮大的,尤其是对象里面结构嵌套过深的时候。而且有时候我们就想关心这个对象中的某个属性,比如name,这个时候可以这样

watch: {
     'queryData.name': {
         handler: function() {
            //do something
         },
     }
}

也可以这样写:

watch: {
     'queryData.name':  function() {
            //do something
      },
     
}

或者还可以这样巧用计算属性

computed: {
    getName: function() {
        return this.queryData.name
    }
}
watch: {
     getName: {
         handler: function() {
            //do something
         },
     }
}

 

搜索

复制

标签:function,vue,methods,05,watch,vm,学习,key,opts
来源: https://www.cnblogs.com/fedrgd/p/16262020.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有