总结Vue中index.html、main.js、App.vue、index.js之间关系以及Vue项目加载流程_index.html 是vue 项目的-程序员宅基地

技术标签: Vue  

总结Vue中index.html、main.js、App.vue、index.js之间关系以及Vue项目加载流程

1 vue中index.html、main.js、App.vue、index.js关系

简介

项目部署完成后的项目结构以及index.html、main.js、App.vue、index.js如下图所示:

在这里插入图片描述

  1. index.html—主页,项目入口
  1. App.vue—根组件,主窗口 组件汇聚点 Vue是基于主键化开发
  1. main.js—入口文件: 整个项目工程入口 用于全局配置
  1. index.js设置路由–名字和资源映射起来

src中所有的编译打包后在public下index.html中app里面

引出我们的问题:那么这几个文件之间的联系如何呢?

1.1 项目的运行入口index.html

为什么index.html是项目的入口以及为什么index.html加载后会继续加载main.js、App.vue、index.js,以及他们之间的关系是如何联系起来的呢???

解释:

这是vue底层源码实现的,通过项目的里面webpack.dev.conf.js等配置文件,可以加载运行我们的index.html文件以及自动关联vue相关的模块。感兴趣的可以了解下。

首先我们来看一下index.html中的内容

<!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">
    <link rel="icon" href="<%= BASE_URL %>favicon.png">
    <title>vue-mooc</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but vue-mooc doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

在网页的Title部分,加载了index.html中定义的Title,而在正文部分,加载了App.vue中定义的部分。
网页效果如下:
在这里插入图片描述

1.2 入口文件main.js

index.htmlbody体中只有一个div标签,其idapp,这个id将会连接到src/main.js内容,接着我们看一下main.js中的主要的代码`

import Vue from 'vue'
import App from './App.vue'
import router from 'router/index.js'
import store from './store/index.js'

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import locale from 'element-ui/lib/locale/lang/en' // lang i18n

// set ElementUI lang to EN
Vue.use(ElementUI, {
     locale })

// register custom base component
import Mooc from './register.js'
import 'assets/theme/index.styl'
Vue.use(Mooc)

import 'assets/stylus/index.styl'


Vue.config.productionTip = false

new Vue({
    
  router,
  store,
  render: h => h(App),
}).$mount('#app')

main.js中,new一个vue实例,并手动挂载在index.html中app里面。也就是说通过main.js我们关联到App.vue组件

1.3 根组件App.vue

接着,我们继续看一下App.vue组件中的内容。

<template>
  <div id="app" :style="getStyle">
    <mooc-container>
      <mooc-header height="72px">
        <m-header />
      </mooc-header>
      <mooc-main>
        <router-view />
      </mooc-main>
      <mooc-footer height="120px">
        <m-footer />
      </mooc-footer>
    </mooc-container>

    <mooc-backtop :show-height="500"></mooc-backtop>
    <login v-if="showLogin" @maskClick="handleMaskClick" />
  </div>
</template>

<script>
import MHeader from 'components/header/index.vue'
import MFooter from 'components/footer/footer.vue'
import {
     mapGetters, mapMutations } from 'vuex'
import {
     scrollMixin } from 'assets/js/mixin.js'
export default {
    
  name: 'App',
  mixins: [scrollMixin],
  computed: {
    
    getStyle () {
    
      return {
    
        'max-height': this.showLogin ? '100%' : '',
        'overflow': this.showLogin ? 'hidden' : ''
      }
    },
    // vuex
    ...mapGetters(['showLogin'])
  },
  methods: {
    
    // 遮罩点击事件
    handleMaskClick () {
    
      this.setShowLogin(!this.showLogin)
    },
    // vuex
    ...mapMutations({
    
      'setShowLogin': 'login/SET_SHOW_LOGIN'
    })
  },
  components: {
    
    MHeader,
    MFooter,
    Login: () => import('components/login/login.vue')
  }
}
</script>

App.vue中的内容是一个标准的vue模板的形式,包含了<template></template>、<script></script>、<style></style>三部分

script中直接处理好业务,template中直接渲染 ,通过v-model双向绑定,

template标签中可以看到,引入了其他页面组件,也就是我们使用npm run serve运行vue项目后看到的界面
在这里插入图片描述
问题:那么内容是从哪里渲染出来的呢?

1.4 控制路由index.js

我们注意到,<template>标签下,除了<img>标签外,还有<router-view>标签,<router-view>标签将会把路由相关内容渲染在这个地方,接下来,我们看一下路由的内容有哪些,在哪里出现的。其实,这个文件位于src/router/index.js中,我们看一下index.js中的代码

import Vue from 'vue'
import Router from 'vue-router'
import store from '../store/index.js'
import {
     getUserInfo } from 'utils/cache.js'
Vue.use(Router)

const Home = () => import('pages/home/index.vue') // 首页路由
const CourseIndex = () => import('pages/course/index.vue') // 免费课程路由
const CourseDetail = () => import('pages/course-detail/index.vue') // 免费课程详情路由
const LessonIndex = () => import('pages/lesson/index.vue') // 实战课程路由
const LessonDetail = () => import('pages/lesson-detail/index.vue') // 实战课程详情路由
const ReadIndex = () => import('pages/read/read.vue') // 专栏路由
const ReadDetaiil = () => import('pages/read-detail/read-detail.vue') // 专栏详情路由
const UserCenter = () => import('pages/user/index.vue') // 个人中心路由
const VipCenter = () => import('pages/vip/index.vue') 

const UserCRUD = () => import('pages/admin/user/index')
const CourseCRUD = () => import('pages/admin/course/index')
const ArticleCRUD = () => import('pages/admin/article/index')
const CommentCRUD = () => import('pages/admin/comments/index')

//路由元信息
const routes = [
  {
    
    path: '/crud/user',
    name: 'UserCRUD',    //给路由起个名,标识路由对象,可以根据name去取一个路由
    component:UserCRUD,
    meta: {
    
      requireAuth: true  //将开启你的页面路由守卫
    }
  },
  {
    
    path: '/crud/course',
    name: 'CourseCRUD',
    component:CourseCRUD,
    meta: {
    
      requireAuth: true
    }
  },
  {
    
    path: '/crud/article',
    name: 'ArticleCRUD',
    component:ArticleCRUD,
    meta: {
    
      requireAuth: true
    }
  },
  {
    
    path: '/crud/comments',
    name: 'CommentCRUD',
    component:CommentCRUD,
    meta: {
    
      requireAuth: true
    }
  },
  {
    
    path: '/',
    name: 'Index',
    redirect: '/home'
  },
  {
    
    path: '/home',
    name: 'Home',
    component:Home
  },
  {
    
    path: '/user',
    name: 'UserCenter',
    component:UserCenter,
    meta: {
    
      requireAuth: true
    }
  },
  {
    
    path: '/vip',
    name: 'VipCenter',
    component:VipCenter,
    meta: {
    
      requireAuth: true
    }
  },
  {
    
    path: '/course',
    name: 'CourseIndex',
    component: CourseIndex,
  },
  {
    
    path: '/course/:id',
    name: 'CourseDetail',
    component: CourseDetail,
    meta: {
    
      requireAuth: true
    }
  },
  {
    
    path: '/lesson',
    name: 'LessonIndex',
    component:LessonIndex
  },
  {
    
    path: '/lesson/:id',
    name: 'LessonDetail',
    component: LessonDetail,
    meta: {
    
      requireAuth: true
    }
  },
  {
    
    path: '/read',
    name: 'ReadIndex',
    component:ReadIndex,
  },
  {
    
    path: '/read/:id',
    name: 'ReadDetaiil',
    component:ReadDetaiil,
    meta: {
    
      requireAuth: true
    }
  }
]
const router = new Router({
    
  routes: routes,
  scrollBehavior () {
    
    return {
    
      x: 0,
      y: 0
    }
  }
})

// 路由拦截   全局路由守卫  权限控制,前端路由守卫控制,登录才可以访问
router.beforeEach((to, from, next) => {
    
  let userinfo = getUserInfo()
  if (to.meta.requireAuth) {
    
    if (userinfo.username) {
    
      next()
    } else{
    
      store.commit('login/SET_SHOW_LOGIN', true)
    }
  } else {
    
    next()  //拿到next才放行
  }
})

//对外输出一个router实例
export default router

index.js的代码中,建立了路由相关的内容,也就会渲染到App.vue下面的router-view中。
本项目在index.js下面配置了路由守卫,路由守卫一般应用于权限控制
路由守卫具体作用可以理解为:前端每次跳转路由,就判断 localStroage中有无token,没有就跳转到登录页面,有则跳转到对应路由页面(本项目为例)

index.js中,取其中一个例子,将UserCRUD组件发布为路由,换句说,index.js在这里就是将UserCRUD发布为路由,以在下面进行展示UserCRUD内容,接下来我们再看看components/UserCRUD中的内容是啥(由于里面的内容比较多,这里我们只截取了template中的内容)。

<template>
  <ul class="course-list">
    <li v-for="(item,index) in list" :key="index" class="course-item" @click="handleCourseClick(item)">
      <div class="img-box">
        <img :src="item.img" alt="">
        <span v-if="item.type == 'vip'" class="vip">{
    {
    item.type}}</span>
        <span v-else class="free">{
    {
    item.type}}</span>
        <div v-if="item.tags && item.tags.split(',').length > 0" class="tags">
          <span v-for="(tag, index) in item.tags.split(',')" :key="index" class="tag-item">{
    {
     tag }}</span>
        </div>
        <div v-if="item.process > 0" class="badge rate">
          {
    {
     item.process }}%
        </div>
        <div v-if="item.script" class="badge script">
          {
    {
     item.script }}
        </div>
      </div>
      <p class="course-name">
        {
    {
     item.title }}
      </p>
      <p class="info">
        <span>{
    {
     item.rank }}</span>
        <span><i class="iconfont icon-user">&#xe607;</i></span>
        <span>
          <mooc-star class="star-box" :value="num" :disabled="true" />
        </span>
      </p>
    </li>
  </ul>
</template>

course.vuetemplate中,我们可以看到界面上渲染的一些连接等内容。
course实际渲染效果如下:
在这里插入图片描述

到此,这个页面的加载渲染过程结束了。

2 Vue项目加载流程

通过上述过程,我们可以看到项目加载的过程是index.html->main.js->app.vue->index.js->course.vue

本项目完整代码可以进入我的码云查看:我的码云

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/C2925811081/article/details/106123298

智能推荐

1.1.1 操作系统的层次结构、基本概念、功能和目标-程序员宅基地

文章浏览阅读5.5k次,点赞2次,收藏15次。01 | 熟悉的操作系统举例02 | 操作系统的层次结构03 | 操作系统的概念04 | 操作系统的功能和目标4.1 | 作为计算机系统资源的管理者1️⃣处理器(CPU)管理2️⃣存储器管理3️⃣文件管理4️⃣设备管理4.2 | 作为用户与计算机硬件系统之间的接口1️⃣命令接口2️⃣程序接口4.3 | 作为扩充机器(虚拟机)05 | 知识回顾与重点考点_操作系统的层次结构

Python常用标准库logging-程序员宅基地

文章浏览阅读454次,点赞23次,收藏14次。python logging的简单使用

信息安全:防火墙技术原理与应用._防火墙应用场景-程序员宅基地

文章浏览阅读2.5k次,点赞29次,收藏49次。防火墙是网络安全区域边界保护的重要技术。为了应对网络威胁,联网的机构或公司将自己的网络与公共的不可信任的网络进行隔离,其方法是根据网络的安全信任程度和需要保护的对象,人为地划分若干安全区域,这些安全区域有:公共外部网络;内联网;外联网(内联网的扩展延伸,常用作组织与合作伙伴之间进行通信);军事缓冲区域,简称 DMZ;它一般安装在不同的安全区域边界处,用于网络通信安全控制,由专用硬件或软件系统组成._防火墙应用场景

make,Makefile简易教程_make makefile-程序员宅基地

文章浏览阅读832次。一、概述make是一个类UNIX系统下的编译命令,也可以理解为一个项目管理工具,通过make可以按照自己指定的编译命令编译整个项目,相当于将在命令行的编译命令按序执行,省去了反复键入编译命令的麻烦。除此之外,如果手动执行编译命令,不仅费时难以记忆,最重要的是每执行一次编译命令,项目中的整个文件都要重新编译,即使是未修改过的文件,这在大型项目中是难以忍受的。而make就提供了一种完美的解决方案,它将要执行的编译命令通过特定的语法组织到Makefile文件中,每次只要执行make命令,就可以完成整个项目的构建_make makefile

SyntaxError: Non-ASCII character '\xe5' in file TestMain.py on line 4, but no encoding declared;-程序员宅基地

文章浏览阅读5.8k次。【问题描述】运行Python程序时报错,提示为:SyntaxError: Non-ASCII character '\xe5' in file TestMain.py on line 4, but no encoding declared;【原因分析】Python默认是以ASCII作为编码方式的,如果在自己的Python源码中包含了中文(或者其他非英语系的语言),此时即使你把自..._syntaxerror: non-ascii character '\xe5' in file

yolov8 瑞芯微RKNN和地平线Horizon芯片仿真测试部署_yolov8 rknn-程序员宅基地

文章浏览阅读1w次,点赞19次,收藏89次。yolov8 瑞芯微RKNN和地平线Horizon芯片仿真测试部署。包含模型、测试图片和完整测试代码。跟上技术的步伐,yolov8 首个板端芯片部署。_yolov8 rknn

随便推点

公司软件开发人员绩效评价标准_软件开发人员绩效考核可以量化的指标有-程序员宅基地

文章浏览阅读1.7k次。 总则: 通过量化的指标准确的评定软件开发人员的绩效,从而对薪酬分配提供可靠的依据。 基本说明: 绩效评价,包括业绩考核和能力评定。对软件开发人员的绩效评定,每一项问答表现优秀加一分,表现不佳扣一分,表现平平不得分,最后计算总分。 业绩考核: 此项考核主要考核在一定时间内软件开发人员的任务完成情况。主要包括有以下指标:目标的完成度、难易度、贡献度。 目标完成度 ●完_软件开发人员绩效考核可以量化的指标有

ESP32/ESP8266_esp32 软复位后不停重启-程序员宅基地

文章浏览阅读1.3k次。用乐鑫的这些芯片主要是图arduino能快速搭建工程好开发,遇到的问题也都是arduino开发环境下的,EDP-IDF只在刚拿着玩的时候用过(属实难用)。有一个个人建议,如果没有热风枪或者焊接水平一般,建议远离ESP32-PICO-D4这种侧面几乎没有焊点的QFN封装芯片,检查虚焊短路能让人怀疑人生。_esp32 软复位后不停重启

Lua 面向对象-程序员宅基地

文章浏览阅读838次,点赞24次,收藏5次。基于Lua 实现类的封装,

基于Springboot外卖系统14:菜品新增模块+多个数据表操作+文件上传下载复用_flavors.foreach(dishflavor -> { dishflavor.setdish-程序员宅基地

文章浏览阅读2w次。在该Controller的方法中,不仅需要保存菜品的基本信息,还需要保存菜品的口味信息,需要操作两张表,所以我们需要在DishService接口中定义接口方法,在这个方法中需要保存上述的两部分数据。_flavors.foreach(dishflavor -> { dishflavor.setdishid(dishdto.getid()); });

AD器件距离过近报错 AD修改丝印的距离间距_ad中丝印间距规则怎么改-程序员宅基地

文章浏览阅读1.8w次,点赞21次,收藏80次。今天画板子遇见了一个间距报错,图片如下我当时想着,修改丝印的间距就可以了,查找了一些资料之后发现是这样修改并且我将其修改到了0但是结果还是如上图一样,报错。最后发现除此之外,我们还需要修改元件之间的电气距离修改完成之后就OK!..._ad中丝印间距规则怎么改

论文笔记-End-to-End Human Pose and Mesh Reconstruction with Transformers(使用TransFormer进行端到端的人体姿态估计和网格重建)-程序员宅基地

文章浏览阅读2.4k次,点赞3次,收藏17次。代码和预训练模型:https://github.com/microsoft/MeshTransformer摘要:文章提出MEsh TRansfOrmer(METRO)方法,用于从单个图像重建三维人体姿态和网格顶点。其中用到了注意力编码器来联合建模顶点-顶点和顶点-关节的交互,并同时输出三维关节坐标和网格顶点。介绍:复杂的关节运动和咬合带来了很多挑战。在这方面的工作分为两类①使用参数模型并学习预测形状和姿态系数(SMPL,用到了β和θ作为输入参数,其中β代表是个人体高矮胖瘦、头身比等比例的10个参数.

推荐文章

热门文章

相关标签