Vue基础

341 阅读1分钟

vue访问url执行流程

index.html -> app.js -> App.vue -> router(index.js) -> components

1、index.html

浏览器访问项目,最先访问的是index.html文件。

其中<div id="app"></div> 表示自动挂载


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>后台管理系统</title>
    <link href="//xxx.com/static/css/vue.css" rel="stylesheet">
  </head>
  <body>
    <div id="app"></div> 
    <!-- 打包构建的文件 -->
    <script type="text/javascript" src="//xxx.com/static/js/manifest.js"></script>
    <script type="text/javascript" src="//xxx.com/static/js/vue.js"></script>
    <script type="text/javascript" src="//xxx.com/static/js/router.js"></script>
    <script type="text/javascript" src="//xxx.com/static/js/vendor.js"></script>
    <script type="text/javascript" src="//xxx.com/static/js/app.js"></script>
  </body>
</html>

2、app.js

app.js作为项目的入口文件,在运行中会找到实例需要挂载的位置,即index.html中id="app"。

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',  <!-- 在index.html中找到挂载点 -->
  router,
  components: { App }, <!-- 表示挂载的局部组件为App.vue -->
  template: '<App/>'
})

3、App.vue

vue组件由html、js、css组成,App.vue为根组件,通过router-view加载其他组件。

<template>  <!-- html -->
  <div id="app">
    <img src="./assets/logo.png">
    <router-view/> 
  </div>
</template>

<script> <!-- js -->
export default {
  name: 'App'
}
</script>

<style>  <!-- css -->
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

4、router/index.js

配合router-view使用,会根据访问的url去加载对应的vue组件。

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'helloWorld',
      component: helloWorld
    },
    {
      path: '/query',
      name: 'query',
      component: query
    }
  ]
})

问:App.vue中router-view是如何根据url中的路径如https://xxx.com/query去访问指定的路由/query的?

VueRouterhistory属性实例化的时候会添加popstate或hashchange事件监听。

HTML5History

window.addEventListener('popstate', function (e) {
      var current = this$1.current;
      // Avoiding first `popstate` event dispatched in some browsers but first
      // history route not updated since async guard at the same time.
      var location = getLocation(this$1.base);
      if (this$1.current === START && location === initLocation) {
        return
      }
      this$1.transitionTo(location, function (route) {
        if (expectScroll) {
          handleScroll(router, route, current, true);
        }
      });
});

HashHistory

window.addEventListener(supportsPushState ? 'popstate' : 'hashchange', function () {
      var current = this$1.current;
      if (!ensureSlash()) {
        return
      }
      this$1.transitionTo(getHash(), function (route) {
        if (supportsScroll) {
          handleScroll(this$1.router, route, current, true);
        }
        if (!supportsPushState) {
          replaceHash(route.fullPath);
        }
      });
});

vue底层原理

编译器+运行时

**
**

编译器

编译器其实是一段程序,用来将源代码翻译成目标代码

对于vue.js模板编译器来说,源代码就是组件的模板,而目标代码是能够在浏览器平台上运行的JavaScript代码,或其他拥有JavaScript运行时的平台代码,Vue.js模板编译器的目标代码其实就是渲染函数

详细来说,Vue.js模板编译器会首先对模板进行词法分析和语法分析,得到模板AST。接着,将模板AST转换为JavaScript AST。最后,根据JavaScript AST生成JavaScript代码,即渲染函数代码。

1、解析:通过封装parse函数来完成对模板的词法分析和语法分析,得到模板AST, parse函数接收字符串模板作为参数,并将解析后得到的AST作为返回值返回。 在语义分析的基础上,我们即可得到模板 AST。

2、转换和优化:因为Vuejs 模板编译器的最终目标是生成渲染函数,而渲染函数本质上是JavaScript代码,所以我们需要将模板AST转换成用于描述渲染函数的JavaScript AST 。可以封装transform函数来完成模板AST到JavaScriptAST的转换工作 。

3、生成渲染函数:有了JavaScrpt AST后,我们就可以根据它生成渲染函数了,这一步可以通过封装generate函数来完成。generate函数会将渲染函数的代码以字符串的形式返回,并存储在code的常量中。

const templateAST = parse(template)
const jsAST = transform(templateAST)
const code = generate(jsAST)

运行时

1、依赖收集

依赖收集准备阶段——Observer、Dep的实例化。

依赖收集触发阶段——Wather实例化、访问数据、触发依赖收集。

2、派发更新

对象属性修改触发set,派发更新。

数组调用方法,派发更新。

computed依赖收集

**
**

computed派发更新

派发相对来说比较简单了~跟响应式的派发更新基本一致。

user Watcher依赖收集

参考:

vue环境搭建及访问流程梳理

router-view基础

总结vue的6大高级特性——及浅谈一下nextTickkeep-alive的原理

学完即用之Vue.extend+$mount改造dialog实践

computed监听Vuex中state对象中的对象属性时,监听不生效的问题

手摸手,带你用vue撸后台 系列一(基础篇)

【vue设计与实现】框架设计相关知识

【vue设计与实现】编译器 - 基本的编译技术

【vue设计与实现】解析器 - 文本模式及其对解析器的影响 & 递归下降算法构造模板 AST

纯干货!图解Vue响应式原理

写给初中级 Vue 工程师的高级进阶指南

汪图南的 Vue2 源码分析