经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » HTML5 » 查看文章
Vue 2.0 深入源码分析(五) 基础篇 methods属性详解
来源:cnblogs  作者:大沙漠  时间:2019/6/18 8:53:24  对本文有异议

用法


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

例如::

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
  6. <title>Document</title>
  7. </head>
  8. <body>
  9. <div id="app">{{message}}<button @click="ChangeMessage">测试按钮</button></div>
  10. <script>
  11. new Vue({
  12. el:'#app',
  13. data:{message:"Hello World!"},
  14. methods:{
  15. ChangeMessage:function(){this.message="Hello Vue!";}
  16. }
  17. })
  18. </script>
  19. </body>
  20. </html>

显示的样式为:

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

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

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

 源码分析


  Vue实例后会先执行_init()进行初始化(4579行)时,会执行initState()对props, methods, data, computed 和 watch 进行初始化,如下:

  1. function initState (vm) { //第3303行
  2. vm._watchers = [];
  3. var opts = vm.$options;
  4. if (opts.props) { initProps(vm, opts.props); }
  5. if (opts.methods) { initMethods(vm, opts.methods); } //如果定义了methods,则调用initMethods初始化data
  6. if (opts.data) {
  7. initData(vm);
  8. } else {
  9. observe(vm._data = {}, true /* asRootData */);
  10. }
  11. if (opts.computed) { initComputed(vm, opts.computed); }
  12. if (opts.watch && opts.watch !== nativeWatch) {
  13. initWatch(vm, opts.watch);
  14. }
  15. }

 initMethods()定义如下:

  1. function initMethods (vm, methods) {   //第3513行
  2. var props = vm.$options.props;
  3. for (var key in methods) { //遍历methods对象,key是每个键,比如例子里的ChangeMessage
  4. {
  5. if (methods[key] == null) {         //如果值为null,则报错
  6. warn(
  7. "Method \"" + key + "\" has an undefined value in the component definition. " +
  8. "Did you reference the function correctly?",
  9. vm
  10. );
  11. }
  12. if (props && hasOwn(props, key)) {     //如果props中有同名属性,则报错
  13. warn(
  14. ("Method \"" + key + "\" has already been defined as a prop."),
  15. vm
  16. );
  17. }
  18. if ((key in vm) && isReserved(key)) {   //如果key是以$或_开头则,也报错
  19. warn(
  20. "Method \"" + key + "\" conflicts with an existing Vue instance method. " +
  21. "Avoid defining component methods that start with _ or $."
  22. );
  23. }
  24. }
  25. vm[key] = methods[key] == null ? noop : bind(methods[key], vm); //如果key对应的值不是null,则执行bind()函数
  26. }
  27. }

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

  1. function polyfillBind (fn, ctx) { //当Function的原型上不存在bind()函数时,自定义一个函数实现同样的功能,用apply()或call()来实现
  2. function boundFn (a) {
  3. var l = arguments.length;
  4. return l
  5. ? l > 1
  6. ? fn.apply(ctx, arguments)
  7. : fn.call(ctx, a)
  8. : fn.call(ctx)
  9. }
  10. boundFn._length = fn.length;
  11. return boundFn
  12. }
  13. function nativeBind (fn, ctx) { //调用Function的原型上的bind()方法,上下文闻ctx
  14. return fn.bind(ctx)
  15. }
  16. var bind = Function.prototype.bind //如果Function的原型上有bind方法,则调用该方法,否则用自定义的polyfillBind()方法
  17. ? nativeBind
  18. : polyfillBind;

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

原文链接:http://www.cnblogs.com/greatdesert/p/11038026.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号