Vue基础知识-脚手架开发-初始化目录解析
一、项目完整代码
首先附上项目所有核心文件的完整代码,项目结构如下(标准 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 函数:
h
是createElement
的别名(Vue 源码约定),h(App)
会递归解析 App 组件及其子组件,生成完整的虚拟 DOM 树,最终通过$mount('#app')
挂载到页面。
2. 组件的定义与使用流程
一个 Vue 组件从创建到使用需 3 步,以 Student 组件为例:
- 定义组件:通过
export default { ... }
暴露组件配置(data、template、style 等),Vue 会自动通过Vue.extend
转换为组件构造函数。 - 导入组件:在父组件(如 App.vue)中通过
import 组件名 from '路径'
导入,默认导出的组件可省略复杂语法。 - 注册并使用:在父组件的
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
函数替代。
三、项目运行流程梳理
- 启动项目后,webpack 首先执行入口文件 main.js。
- 引入 Vue 和 App 组件,创建 Vue 实例。
render: h => h(App)
生成 App 组件的虚拟 DOM 树(包含 School 和 Student 子组件)。$mount('#app')
将虚拟 DOM 转换为真实 DOM,挂载到 index.html 的 #app 容器中。- 浏览器渲染真实 DOM,展示最终页面(红色背景的学校组件 + 橙色背景的学生组件)。
四、注意事项
- 组件 data 必须是函数:确保每个组件实例的数据独立,避免多个实例共享同一数据(如多个 Student 组件实例的 name 互不影响)。
- 默认导入 / 导出的简写:默认导出的组件导入时可直接写名称(如
import School from './School'
),无需{ default as School }
。 - 生产环境配置:关闭
Vue.config.productionTip = false
,减少生产环境代码体积,避免不必要的提示。 - 第三方样式引入:若引入 Bootstrap、Element UI 等第三方样式,建议放在 public 目录(避免 webpack 重复处理),或通过 npm 安装后导入。