第五单元 脚手架
一、本单元教学目标
(Ⅰ)重点知识目标
1. 理解什么是脚手架 2. 怎么使用脚手架创建项目 3. 项目的目录规范 4. 单文件组件 5. 如何设置私有作用域样式 6. Chrome调试工具的使用 7. 单文件组件的使用
二、本单元知识详讲
5.1 脚手架
5.1.1 脚手架简介
什么是脚手架
通过下面这个图,我们来分析一下,什么是脚手架。 目前我们vue最常用的两个脚手架,一个是VueCLI
,另外一个就是create-vue
。
-
VueCLI
-
-
Vue2 时期官方的一款脚手架工具。不再推荐。
-
虽然不推荐了,但是还是可以使用它来创建 Vue2、Vue3 的项目。
-
内部使用的构建工具是 Webpack 。 圣诞大餐
-
create-vue
-
-
Vue3 出来之后,官方推荐的。
-
内部使用的构建工具是 Vite。
-
它是基于
create-vite
,提供给专门创建 Vue 项目的。
5.1.2 Vite 是什么
官网链接:Vite | 下一代的前端工具链
尤雨溪团队最新打造的。下一代的前端工具链(构建工具)。用于取代以往的 Webpack 。
5.2 VueClI 创建项目 5.0.8
-
先配置下
npm
的淘宝镜像。
# 配置 npm config set registry https://registry.npmmirror.com # 查看当前的配置 npm config get registry
-
全局安装脚手架工具
npm install -g @vue/cli
-
验证安装是否成功
vue --version
输出 @vue/cli 的版本。注意:不是 Vue 版本
-
选择一个目录,运行如下命令,创建 Vue 项目
vue create [project-name]
-
创建成功,进入到项目目录下,运行如下命令启动项目
npm run serve
-
项目启动之后,会在本地运行一个服务,默认监听的是 8080 端口。如果需要关闭本地运行的话,可以在终端连按两次 ctrl + c 键。
5.3 CreateVue 创建项目
-
无需全局安装,直接选择一个目录,运行如下命令:
npm init vue # or npm create vue
-
第一次使用时,会提示如下的内容。直接 回车 即可。
-
按照提示,输入项目名称,选择项目的一些配置即可。
-
a是否需要 vue-router
-
b是否需要 pinia
-
c是否需要 typescript
-
...
-
跟 create-vite 一样,不会自动帮我们安装项目依赖。需要我们自己进入项目目录之后,手动安装
5.4 项目目录结构介绍
+---.vscode | extensions.json 团队推荐要安装的 vscode 插件。一般会随着git提交。 +---.vscode +---dist 该目录是构建产物目录,在运行 npm run build 命令之后出现。 项目上线时,不是将整个项目代码上传到服务器,而是只将 该目录 中的内容上线到服务器。 +---node_modules 项目的依赖包文件。 +---public 静态资源托管目录,该如下的文件可以直接文件名构造url地址来访问 +---src 项目源代码目录。我们写代码基本都是往这个目录下来写。 | +---assets 用于存放一些 css、image 等文件的地方。 | +---components 用于存放公共组件的目录。 | +---directives 用于存放公共组件的目录。 | +---hooks 用于存放公共hooks | +---layout 用于存放模板 | +---router router | +---store store | +---utils 用于存放工具js | \---views 项目的视图文件 | App.vue 根组件 | main.js 入口JS文件,该文件名不能随意修改。 |---.gitignore Git版本管理的忽略文件,用于配置哪些文件不需要被Git管理起来。 |---index.html 项目的html文件。 |---package-lock.json 项目依赖包的版本锁文件 |---package.json 项目的描述文件,该文件有如下配置项 |---README.md 项目的说明文件,该文件一般会描述,如何启动项目,项目的一些基础介绍之类的。 |---vite.config.js 项目是基于 vite 的。该文件是 vite 的配置文件。
5.5 单文件组件介绍
5.5.1 什么是单文件组件
在 Vue 项目中,后缀名为 .vue 的,就是单文件组件。简称 SFC(Single File Component)
5.5.2 有什么好处
-
使用熟悉的 HTML、Css、JavaScript 语法编写模块化的组件
-
通过给编辑器(VsCode)安装一些插件,有语法高亮、代码提示
-
可以实现组件的私有样式
5.5.3 单文件组件的组成
<template> <div>必须要有一个根标签</div> </template> <script> export default { } </script> <style> /* 样式部分 */ </style>
-
template 组件的模板部分
-
必须的,有且能有有一个
-
-
script 组件的逻辑部分
-
主要做暴露一个组件的配置对象
-
可选的,可以有多个 script 标签。但是只能导出一份配置对象
-
-
style 组件的样式部分
-
默认是全局样式,可以通过给
style
标签添加一个scoped
属性,让这个样式只针对当前组件生效。 -
可选的,可以有多个 style 标签
-
5.6 如何设置私有作用域样式
5.6.1 方式:
可以通过给 style
标签添加一个 scoped
属性,让这个样式只针对当前组件生效。
5.6.2 如何实现的呢:
-
会将设置了
scoped
属性的组件的模板的所有元素上,都添加上一个data-xxxx
属性 -
最终生成的样式,会携带上
[data-xxxx]
这样的属性选择器
5.6.3 样式穿透
如果一个组件有自己的私有作用域样式,我使用它时要修改它的样式该如何办
-
使用深度选择器
:deep()
来控制子组件内的样式 - 推荐 ::v-deep(选择器){} -
再写一个不设置
scoped
属性的style
标签
5.7 使用 css预处理器
css预处理器有哪些:
-
scss
-
less
-
windcss tailwindcss
只需要给 style 标签,设置一个 lang 属性,属性值为对应的预处理器即可。
<style lang="scss"></style>
PS: 需要额外安装一个 sass 的模块
npm install sass -D
5.8 Chrome调试工具
工具下载
vuejs-devtools.zip(2.4 MB)
安装调试工具
安装步骤:
-
打开浏览器,地址栏输入 chrome://extensions/ 回车,进入扩展程序界面。
-
打开右上角的开发者模式
-
完全退出(关闭)浏览器(尤其是Mac系统,在最底下的图标上右键,退出)
-
重启浏览器,再次 输入 chrome://extensions/ 回车,进入扩展程序界面
-
解压 vue-devtools.zip ,得到 vue-devtools.crx 文件
-
将 vue-devtools.crx 文件,拖到浏览器的扩展程序界面,松开鼠标,确认安装。
安装好之后,如果你打开Vue项目,这个小图标就会变亮。
注意,只有打开Vue项目,这个图标才会亮。
初步使用调试工具
-
1通过 localhost:8080 打开刚刚创建好的项目。
-
2打开浏览器调试控制台(F12)
-
3你会发现多了一个Vue面板,左右拖动它到你想要的位置
-
4初次安装,会有使用提示,我们直接点击 Skip 跳过。
-
这个调试工具,是响应式的布局,有可能你看到的不是左右结构,是上下结构,也是正常的。
5.9 vue.config.js 的配置
首先在 vue 的项目下面 新建一个 vue.config.js 该文件夹和src是同级的文件夹。 下面代码是一个简单的配置文件
module.exports = { publicPath: "./", // 部署应⽤包时的基本 URL outputDir: "dist", // npm run build ⽣成的⽂件夹,默认是dist assetsDir: "static", // 在kaixin⽂件夹下⾯⽣成static⽬录存放js,img,css等静态资源 indexPath: "index.html", // ⽣成的单⽂件的,⽂件名, filenameHashing: true, // 文件名哈希(默认情况下,生成的静态资源在它们的文件名中包含了 hash 以便更好的控制缓存。然而,这也要求 index 的 HTML 是被 Vue CLI 自动生成的。如果你无法使用 Vue CLI 生成的 index HTML,你可以通过将这个选项设为 false 来关闭文件名哈希) pages: { index: { // page 的入口文件 entry: 'src/index/main.js', // 模板文件 template: 'public/index.html', // 在 dist/index.html 的输入文件 filename: 'index.html', // 当使用页面 title 选项时, // template 中的 title 标签需要的是 <title><%= htmlWebpackPlugin.options.title %></title> title: 'Index Page', // 在这个页面中包含的块,默认情况下会包含 // 提取出来的通用 chunk 和 vandor chunk。 chunks: ['chunk-vendors', 'chunk-common', 'index'] }, // 当使用只有入口的字符串格式时, // 模板文件默认是 'public/subpage.html' // 如果不存在,就回退到 'public/index.html' // 输出文件默认是 'subpage.html' subpage: 'src/subpage/main.js' }, // 是否在保存的时候使用'eslint-loaer'进行检查。 lintOnSave: true, // 是否使用带有浏览器内编译器的完整构建版本 runtimeCompiler: false, // 在生成的 HTML 中的 <link rel="stylesheet"> 和 <script> 标签上启用 Subresource Integrity (SRI)。如果你构建后的文件是部署在 CDN 上的,启用该选项可以提供额外的安全性。 integrity: true, // 配置跨域服务代理 devServer: { host: "127.0.0.1", // 配置主机地址 port: process.env.NODE_ENV == 'production' ? 3000 : 8888, // 配置运⾏的端⼝ // proxy: "接⼝地址", 跨域代理! 【重要!】 proxy: { // 配置多个! // '/api': { // target: 'http://localhost:3030/api', // ws: true, // 跨域地址是https协议! // changeOrigin: true, // pathRewrite: { // "^/api": "" // 将 '/api' 替换成 '' // } // } }, }, css: { // 将组件内的 CSS 提取到一个单独的 CSS 文件 (只用在生产环境中) // 也可以是一个传递给 `extract-text-webpack-plugin` 的选项对象 extract: true, // 是否开启 CSS source map? sourceMap: false, // 为预处理器的 loader 传递自定义选项。比如传递给 // Css-loader 时,使用 `{ Css: { ... } }`。 loaderOptions: { css: { // 这里的选项会传递给 css-loader }, postcss: { // 这里的选项会传递给 postcss-loader } }, // 为所有的 CSS 及其预处理文件开启 CSS Modules。 // 这个选项不会影响 `*.vue` 文件。 modules: false }, }
5.10 单文件组件的使用
5.10.1 普通嵌套循环
<template lang=""> <div> <ul> <li v-for='(item,index) in list'> {{item.name}} <ul> <li v-for='childitem in item.children'> {{childitem.name}} </li> </ul> </li> </ul> </div> </template> <script> export default { name:'tree', props:['item'], data() { return { list:[ {id:0,name:'权限菜单',children:[ {id:0,name:'菜单添加'}, {id:1,name:'菜单删除'}, {id:2,name:'菜单改变'}, ]}, {id:1,name:'用户中心',children:[ {id:0,name:'用户添加'}, {id:1,name:'用户删除'}, ]}, {id:2,name:'订单中心',children:[ {id:0,name:'订单添加'}, {id:1,name:'订单删除'}, ]} ] } }, } </script>
5.10.2 递归组件。
定义组件src/view/TreeList.vue
<template lang=""> <div> <ul> <li v-for='(item,index) in list'> {{item.name}} <TreeList :list='item.children'></TreeList> </li> </ul> </div> </template> <script> import { defineComponent, ref} from 'vue' export default defineComponent({ name:'TreeList', props:['list'], mounted(){ console.log(this.$props); } }) </script>
调用组件并传值
<template> <div> <TreeList :list="list"></TreeList> </div> </template> <script> import { defineComponent, ref} from 'vue' import TreeList from './views/TreeList.vue' export default defineComponent({ data() { return { list:[ {id:0,name:'权限菜单',children:[ {id:0,name:'菜单添加'}, {id:1,name:'菜单删除'}, {id:2,name:'菜单改变'}, ]}, {id:1,name:'用户中心',children:[ {id:0,name:'用户添加'}, {id:1,name:'用户删除'}, ]}, {id:2,name:'订单中心',children:[ {id:0,name:'订单添加'}, {id:1,name:'订单删除'}, ]} ] } }, components:{ TreeList } }) </script>