Vue超级api:$data,$props,$el,$options,$options.render,$root

2020-04-08 16:49:25

如果你看到了这篇文章,知道了vue的这些底层api,你会发现你完全可以成为vue大牛了,这写api能帮助我们很好的解决问题,并且我们能通过这些api开发出不错的组件来。

参考地址 Vue基础(一):$data,$props,$el,$options,$options.render,$root


前言:


因为 Vue 的东西相对比较多,所以它的 API 我们完整的过一遍之后,才能真正的知道 Vue 到底有哪些功能。


同时,将来在我们开发的过程当中,你遇到了一个问题,才能一下子就想到,我用 Vue 里面的哪个 API,或者哪一个功能点,能够帮我去解决这个问题。


在学习一个框架之前,一定先把它整个的流程搞清楚、它的原理、它主要去解决了哪些问题、它主要的 API、以及它编程的一些思想。


只有这些东西弄清楚了,真正的用到项目中之后,你才能更得心应手。


不然的话这个框架你一知半解,然后你去使用它的时候,就会发现:我去解决某一个问题的时候,解决起来非常困难,虽然说可以实现,但是我会绕了一个大圈子。


而如果你知道了所有的 API、所有的用法之后,你可能会发现它其实有一个更简单的方法去解决。


这就是我们学习某一项技术必须要打好基础的原因。


 


那么正题开始:


启动项目之后,我们创建一个 Vue 的实例:




 


那么我们通过 new Vue传进去的那个对象是什么呢?


其实就和我们写 .vue 文件的时候, export default 出来的这部分内容差不多。


它也是一个对象,里面这些属性,我们也都可以传进去。并且用法也都是一样的。




 


那么现在有个问题:


如果我们没有传 el: '#app',是不是就没有办法把下面 template 的代码渲染到 html 节点上面呢?


答案是否定的。我们可以通过 $mount('#app') 挂载到 html 节点上。


通过这种方式,和指定 el,它们的效果是一模一样的,如下图:




 


那么我们通过 app = new Vue() 的意义是什么呢?


让我们一步步的往下看。


 


首先,我们先看下 app 上面的 num




我们可以看到,每过一秒,num 就加 1,这个值是动态变化的。


 


app.$data


那么 app.$data 又是什么呢?app.$data 就是我们 new Vue 时传进去的 data。




 


app.$props




我们可以看到,app.$props 的值是 undefined,这是为什么呢?


因为我们根本没有在组件上面去声明这个东西。只有声明,并且传入了之后,它才会有内容。如下图:




 


app.$el


app.$el 就是挂载到 html 上面的节点,它对应的是对这个节点的引用。




 


app.$options


app.$options 对应的其实就是我们在 new Vue() 时传进去的一整个对象。


注意:app.$options 是有一个默认值的,这个默认值和我们传进去的合并之后,就变成了 app.$options




那么在上图的 app.$options 上,我们可以看到 data 这个属性。


那么如果我们通过 app.$options 去修改这个 data,会不会有对应的变化呢?


我们来测试一下:




通过上图,我们可以看到:视图是没有任何变化的。


那么我们可以得出一个结论:我们传入进去 options 里面的 data,其实是通过 Vue 在 init() 的时候,做过了一些修改,而不是直接引用的 $options.data,它们不是同一个对象。所以我们直接修改 $options.data 上面的数据是没有任何作用的。


那么,如果我们直接给 app.$data 上面进行赋值呢?我们来试一下:




我们可以看到是有变化的。这说明了我们挂载在 Vue 实例根对象上的 num 其实跟 $data 上面的 num 是同一个属性。


按照官方的说法:我们直接通过 instance 上面调用 data 上相关的数据,其实就是它代理到 app.$data 上面的属性。


所以这两个属性其实是相通的,那么如果有些特定情况要用到,也可以使用这种方法。


 


app.$options 上面还有一个比较特殊的属性:app.$options.render




我们看到:


刚渲染的时候,0 是没有任何变化的,但是当1秒后 app.num += 1,就更新为 render 方法中的字段了,并且后面不再变化。


说明 render 方法是需要等下一次值变化,重新进行渲染的时候,才会生效。


 


app.$root


那么这个 app.$root 是干嘛用的呢?




我们可以看到上面打印出来的是个对象。根据对象上面的属性,可以说明它是 Vue 的 instance。


那么这个 Vue 的 instance 又是什么呢?


整个 Vue 是以树状结构往下进行渲染的,我们在最上层会有一个根节点,这个根节点就是我们 new 出来的 app。


因为我们是通过 new 出来的这个 app,然后把整个应用挂载到 html 上面的。


所以我们得出一个结论:app.$root === app。


那么 app.$root 的用途是什么呢?在所有的整个 Vue 应用当中,每一个节点上面,我们都可以进行调用。它们拿到的 $root 其实都是同一个值,也就是我们在最外层去生成的,并且通过这个节点去挂载到 html 上面那个 Vue 对象。



  • 2018-08-14 23:35:28

    Retrofit 设置 超时时间

    今天开发的时候遇到一个网络请求超时的问题,后台处理是成功的,但是移动端返回的总是提示请求超时,在设置了retrofit请求超时的时间延长以后,就可以请求成功了,下面是配置的方法:

  • 2018-08-16 16:10:43

    Laravel 跨域解决方案

    我们在用 laravel 进行开发的时候,特别是前后端完全分离的时候,由于前端项目运行在自己机器的指定端口(也可能是其他人的机器) , 例如 localhost:8000 , 而 laravel 程序又运行在另一个端口,这样就跨域了,而由于浏览器的同源策略,跨域请求是非法的。其实这个问题很好解决,只需要添加一个中间件就可以了。

  • 2018-08-18 20:30:12

    laravel5.5 路由分割成不同文件

    routes.php/api.php文件用来放置laravel路由,当项目越来越大,相应的路由文件也会越来越多。如果能够将不同功能的路由分割到不同的文件,那么对以后的维护将很有帮助。

  • 2018-08-20 15:26:19

    关于OnTouch 和OnClick同时调用冲突的解决方案

    大家在搞轮播图的时候会碰到这样的情况,点击进入webview界面,长按轮播图停止轮播,手松开图又开始轮播,这里就涉及到了OnTouch 和OnClick同时调用。两者是有冲突的。这里简单介绍,给大家提供思路。

  • 2018-08-20 15:29:11

    揭开RecyclerView的神秘面纱(二):处理RecyclerView的点击事件

    主要讲述了RecyclerView的基本使用方法,不同的布局管理器而造成的多样化展示方式,展示了数据之后,一般都会与用户进行交互,因此我们需要处理用户的点击事件。在ListView和GridView提供了onItemClickListener这个监听器,然而我们查找RecyclerView的API却没有类似的监听器,因此我们需要自己手动处理它的点击事件。 以下提供两种方法来实现处理RecyclerView点击事件的功能,以下代码均基于上一篇文章的代码做出修改。

  • 2018-08-20 22:58:46

    onInterceptTouchEvent和onTouchEvent调用关系详解 ...

    老实说,这两个小东东实在是太麻烦了,很不好懂,我自己那api文档都头晕,在网上找到很多资料,才知道是怎么回事,这里总结一下,记住这个原则就会很清楚了:

  • 2018-08-23 15:32:18

    map对象拷贝问题

    最后面是使用序列化的方式,发现,更改引用类型的数据的时候,mapNew对象并没有发生变化,所以产生了深拷贝。 上述的工具类,可以实现对象的深拷贝,不仅限于HashMap,前提是实现了Serlizeable接口。

  • 2018-08-24 11:33:17

    总结和分析几种判断 RecyclerView 到达底部的方法

    SwipeRefreshLayout 写一个 RecyclerView 的上下拉 ,里面有一个判断 RecyclerView 是否到达底部的方法 isBottom。我的同事用了这个上下拉之后发现有些小 bug,没考虑周全,譬如各个子项高度不统一的时候,然后我找到原因是因为这个判断上下拉的问题。所以,我就去网上查到几种判断 RecyclerView 到达底部的方法,发现各有千秋。以下的分析都以上一篇文章的 SwipeRecyclerView 为例