Vue基础知识-脚手架开发-初始化目录解析

发布于:2025-09-07 ⋅ 阅读:(24) ⋅ 点赞:(0)

一、项目完整代码

首先附上项目所有核心文件的完整代码,项目结构如下(标准 Vue-cli 初始化的基础结构):

src/
├─ components/
│  ├─ School.vue   // 学校组件
│  └─ Student.vue  // 学生组件
├─ App.vue         // 根组件
└─ main.js         // 入口文件
public/
└─ index.html      // 页面模板

1. public/index.html(页面模板)

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <!-- 让IE浏览器以最高的渲染级别渲染界面 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <!--BASE_URL表示根路径/。在vue中,/即表示从public目录下找。-->
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <!-- 找到package.json中的name -->
    <title><%= htmlWebpackPlugin.options.title %></title>
    <!-- 引入第三方样式 -->
		<link rel="stylesheet" href="<%= BASE_URL %>css/bootstrap.css">
  </head>
  <body>
    <!-- 
    访问localhost:8080/logo.png即访问public/logo.png。src目录下的assets不可直接通过url访问
    <img src="/logo.png"></img> 
    -->
   <!--  浏览器不支持js时,noscript中的内容会显示 -->
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> 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>

2. src/components/School.vue(学校组件)

<template>
    <div class="demo">
        <h1>学校名称:{{name}}</h1>
    </div>
</template>
<script>
    export default {
        name:'School',
        data(){
            return {
                name:'北京大学'
            }
        }
    }
</script>
<!--scoped表示css局部生效-->
<style scoped>
    .demo{
        background-color: red;
    }
</style>

3. src/components/Student.vue(学生组件)

<template>
    <div class="demo">
        <h1>学生名称:{{name}}</h1>
    </div>
</template>
<script>
    /* 
    const student = Vue.extend({
        data() {
            return {
                name:'张三' 
            }
        }
    }) 
    */
    // 1  Vue.extend 可以直接简写为对象形式。最终Vue会帮你调用
    export default { //默认暴露
        name:'Student',
        data(){
            return {
                name:'张三'
            }
        }
    }
</script>
<!--css局部生效-->
<style scoped>
    .demo{
        background-color: orange;
    }
</style>

4. src/App.vue(根组件)

<template>
    <div>
        <School/>
        <Student/>
    </div>
</template>

<script>
    import School from './components/School'   ///默认导出的组件在导入时可简写:import 自定义名 from './School'。完整写法为 import {default as School} from './School'
    import Student from './components/Student';    
    export default {
        name:'App',
        components:{
            // 注册子组件:键值同名时可简写(等价于 School: School, Student: Student)
            School,
            Student
        }
    }
</script>

<style>
   
</style>

5. src/main.js(入口文件)

//main.js为入口

/* 
    引入Vue.js。
    'vue'是一个非相对导入。即不以 ./、../或/开头的路径
    非相对导入通常被解释为包名,这些包位于node_modules目录中
    vue包中的package中有配置:"module": "dist/vue.runtime.esm.js"。因此相当于引入了运行时Vue.js

    完整版vue.js:核心功能+模板解析器
    运行时vue.js:核心功能
    因此,本Vue项目不能使用Vue里面的template配置项(使用render函数)
    但是.vue文件中的<template>标签可以由本项目的依赖"vue-template-compiler"来解析
*/
import Vue from 'vue'
//引入App组件
import App from './App.vue'
//关闭生产提示
Vue.config.productionTip = false
//创建vm
new Vue({
    //将App组件放入容器(挂载到public/index.html中的<div id="app"></div>)
    render: h => h(App),
    /* 
        完整写法:
        render:function(createElement){
            return createElement(App)
        }
    */
}).$mount('#app')//挂载。和配置el选项一样
/*
相当于实现如下功能:
new Vue({
    template:`<App/>`,
    el:'#App',
    components:{
        App
    }
}
*/

二、核心知识点解析

1. 入口文件 main.js 的关键作用

  • Vue 引入逻辑:默认引入的是「运行时 Vue」,无法解析template配置(如new Vue({ template: '<App/>' })会报错),因此必须用render函数直接生成虚拟 DOM。
  • render 函数hcreateElement的别名(Vue 源码约定),h(App)会递归解析 App 组件及其子组件,生成完整的虚拟 DOM 树,最终通过$mount('#app')挂载到页面。

2. 组件的定义与使用流程

一个 Vue 组件从创建到使用需 3 步,以 Student 组件为例:

  1. 定义组件:通过export default { ... }暴露组件配置(data、template、style 等),Vue 会自动通过Vue.extend转换为组件构造函数。
  2. 导入组件:在父组件(如 App.vue)中通过import 组件名 from '路径'导入,默认导出的组件可省略复杂语法。
  3. 注册并使用:在父组件的components选项中注册组件,然后在模板中用<组件名/>标签使用。

3. 样式作用域:scoped 的原理

  • scoped 样式:在<style>标签加scoped后,webpack 会为当前组件的所有 DOM 元素添加一个唯一属性(如data-v-xxx),并为样式规则添加该属性选择器(如.demo[data-v-xxx]),确保样式仅作用于当前组件。
  • 全局样式:无scoped的样式会作用于整个项目,建议仅在 App.vue 或单独的全局样式文件中使用,避免样式冲突。

4. public 目录与 src/assets 的区别

  • public 目录:存放静态资源(如 favicon.ico、bootstrap.css),资源不会被 webpack 处理,访问时需通过根路径(如/css/bootstrap.css),适合引入第三方固定路径的资源。
  • src/assets 目录:存放项目内部资源(如图片、自定义样式),资源会被 webpack 处理(如图片转 base64、样式压缩),访问时需通过import导入(如import './assets/logo.png')。

5. 模板解析机制

  • .vue 文件中的<template>:由项目依赖vue-template-compiler解析(webpack 打包时处理),将模板转换为render函数,因此即使使用运行时 Vue,也能正常解析组件模板。
  • Vue 实例的 template 配置:运行时 Vue 无模板解析器,直接使用会报错,因此必须用render函数替代。

三、项目运行流程梳理

  1. 启动项目后,webpack 首先执行入口文件 main.js。
  2. 引入 Vue 和 App 组件,创建 Vue 实例。
  3. render: h => h(App)生成 App 组件的虚拟 DOM 树(包含 School 和 Student 子组件)。
  4. $mount('#app')将虚拟 DOM 转换为真实 DOM,挂载到 index.html 的 #app 容器中。
  5. 浏览器渲染真实 DOM,展示最终页面(红色背景的学校组件 + 橙色背景的学生组件)。

四、注意事项

  1. 组件 data 必须是函数:确保每个组件实例的数据独立,避免多个实例共享同一数据(如多个 Student 组件实例的 name 互不影响)。
  2. 默认导入 / 导出的简写:默认导出的组件导入时可直接写名称(如import School from './School'),无需{ default as School }
  3. 生产环境配置:关闭Vue.config.productionTip = false,减少生产环境代码体积,避免不必要的提示。
  4. 第三方样式引入:若引入 Bootstrap、Element UI 等第三方样式,建议放在 public 目录(避免 webpack 重复处理),或通过 npm 安装后导入。

网站公告

今日签到

点亮在社区的每一天
去签到