# test_xwtt1008 **Repository Path**: uptocoding/test_xwtt1008 ## Basic Information - **Project Name**: test_xwtt1008 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 0 - **Created**: 2022-03-08 - **Last Updated**: 2023-02-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 一.课程内容 ## Day01项目搭建 ### 1.创建项目 + 使用 Vue脚手架 创建 项目:`xwtt_1008` ![image-20220308104838278](assets/image-20220308104838278.png) ![image-20220308105205186](assets/image-20220308105205186.png) ![image-20220308105304932](assets/image-20220308105304932.png) ![image-20220308105415058](assets/image-20220308105415058.png) ![image-20220308105622747](assets/image-20220308105622747.png) image-20220308105745828 ![image-20220308105829581](assets/image-20220308105829581.png) ### 2.打开和配置项目 #### 2.1 配置 eslint + 文件:`.eslintrc.js` ```js module.exports = { root: true, env: { node: true, }, extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"], parserOptions: { parser: "babel-eslint", }, rules: { "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", // 配置 eslint 的 引号规范,使用 单引号,不然就报错! "quotes": ["error", "single"] }, }; ``` #### 2.2 配置 prettier + 文件:`.prettierrc.js` ```js //此处的规则供参考,其中多半其实都是默认值,可以根据个人习惯改写 module.exports = { // printWidth: 80, //单行长度 // tabWidth: 2, //缩进长度 // useTabs: false, //使用空格代替tab缩进 // semi: true, //句末使用分号 singleQuote: true, //使用单引号 // quoteProps: 'as-needed', //仅在必需时为对象的key添加引号 // jsxSingleQuote: true, // jsx中使用单引号 // trailingComma: 'all', //多行时尽可能打印尾随逗号 // bracketSpacing: true, //在对象前后添加空格-eg: { foo: bar } // jsxBracketSameLine: true, //多属性html标签的‘>’折行放置 // arrowParens: 'always', //单参数箭头函数参数周围使用圆括号-eg: (x) => x // requirePragma: false, //无需顶部注释即可格式化 // insertPragma: false, //在已被preitter格式化的文件顶部加上标注 // proseWrap: 'preserve', //不知道怎么翻译 // htmlWhitespaceSensitivity: 'ignore', //对HTML全局空白不敏感 // vueIndentScriptAndStyle: false, //不对vue中的script及style标签缩进 // endOfLine: 'lf', //结束行形式 // embeddedLanguageFormatting: 'auto', //对引用代码进行格式化 }; ``` #### 2.3 提交git仓库 + 本地仓库提交: ```js git status -s // 查看工作区状态 git add . // 将工作区文件 提交到 本地仓库暂存区 git commit -m '初始化' // 将 暂存区 文件 提交到 仓库区生成版本 ``` + 远程仓库提交: + 去 gitee.com 新建远程仓库 ```js // 将 仓库 ssh地址 复制,并保存到本地仓库 git remote add origin git@gitee.com:uptocoding/test_xwtt1008.git // 将 本地仓库最新版本 提交到 远程仓库的 master分支 git push -u origin master ``` #### 2.4 简化eslint + vue 创建项目时,选择了 `prettier`规范套装,不好用,去掉它! 修改配置:**.eslintrc.js** ```js module.exports = { root: true, env: { node: true, }, extends: ["plugin:vue/essential", "eslint:recommended"], // 移出【, "@vue/prettier"】 parserOptions: { parser: "babel-eslint", }, rules: { "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", // 配置 eslint 的 引号规范,使用 单引号,不然就报错! "quotes": ["error", "single"] }, }; ``` ### 3.初始化项目 #### 3.1 创建基础文件 + `./src/api` : 接口函数 + `./src/utils` :工具函数 + `request.js` :axios统一配置 + `storage.js`:localStorage 操作 + `./src/styles`:样式文件 + `index.less` :全局样式文件 -> 在 **main.js** 导入 ```js import Vue from 'vue'; import App from './App.vue'; import router from './router'; import store from './store'; // 导入 全局 less文件,这个文件的样式会被添加到 style标签中 import './styles/index.less' Vue.config.productionTip = false; new Vue({ router, // 在 Vue实例中,通过 $router 访问 store, // 在 Vue实例中,通过 $store 访问 render: (h) => h(App), }).$mount('#app1'); ``` + 注意:此时 可以 提交到 git 备份一个版本! #### 3.2 准备字体图标 + 推荐网站:https://www.iconfont.cn/ 注册,并登录后 点击 **我的项目** ![image-20220308154302212](assets/image-20220308154302212.png) + 创建 项目 + 上传 图标图片(svg格式) ,注意 点击 **去除颜色**, 可以看到 生成的**字体图标**了 ![image-20220308154927890](assets/image-20220308154927890.png) #### 3.3 使用字体图标 + 导入 **less** 文件,有两种导入语法: + 在 **js 文件** 中 导入:`import './styles/iconfont.less'` + 在 **less 文件** 中 导入:`@import './iconfont.less';` ![image-20220308160424290](assets/image-20220308160424290.png) ### 4.组件库使用 + 2.0官网:https://vant-contrib.gitee.io/vant/v2/#/zh-CN #### 4.1 安装 vant + 安装 vant 库 + 通过 导入 cdn 中的 vant 样式 和 js 来实现,极大的**减少** webpack 打包的**工作量** 和 打包后的 **文件大小** + 通过 包管理工具 下载到 项目 **node_modules** 文件夹使用 + 使用包工具安装:注意->我们用的vue2.0,所以要安装匹配的 **vant** ```js // Vue 2 项目,安装 Vant 2【我们用这个2.0的】 npm i vant@latest-v2 // Vue 3 项目,安装最新版 Vant npm i vant ``` #### 4.2 使用 vant 组件 + 手动按需引入组件 在不使用插件的情况下,可以手动引入需要的组件 + 导入所有组件 + 自动按需引入(推荐) ![image-20220308163839577](assets/image-20220308163839577.png) #### 4.3 编译时px->rem + 原因:vant 组件库 内部使用的都是 px 单位,无法实现 终端适配 + 解决方案:项目打包编译时,通过 @vue/cli -> webpack -> postcss -> **postcss-pxtorem** 来转 + 下载` npm i -D postcss-pxtorem@5.0` + 问题版本匹配: + pxtorem@5.0 使用 postcss@7.0 + pxtorem@6.0 使用 postcss@8.0 + 项目中 默认 postcss 的版本 是 7.0,而 直接下载 pxtorem 最新版本 是 6.0 + 解决方案:直接下载 pxtorem@5.0 版本 + 添加配置文件:`.postcssrc.js` ```js 'postcss-pxtorem': { rootValue: 37.5, // 编译时 37.5px 转成 1rem,原因:vant是按照375px宽算的基准值 propList: ['*'] // 将样式表中所有样式属性的 px 都转成 rem // propList: ['width','font-size'] } ``` + 结果:项目中所有 px 单位 都被转成了 rem单位,浏览器拿到的 也都是 rem单位的样式 ![image-20220308172444304](assets/image-20220308172444304.png) #### 4.4 计算rem基准值 + 下载 `amfe-flexible` : `npm i amfe-flexible` + 在 `main.js` 中导入 ```js // 导入 flexalbe 模块,协助计算 rem 基准值 import 'amfe-flexible' ``` ![image-20220309102600537](assets/image-20220309102600537.png) + **amfe-flexible** 核心源码 ```js //... var docEl = document.documentElement // set 1rem = viewWidth / 10 function setRemUnit () { var rem = docEl.clientWidth / 10 docEl.style.fontSize = rem + 'px' } setRemUnit() // reset rem unit on page resize window.addEventListener('resize', setRemUnit) window.addEventListener('pageshow', function (e) { if (e.persisted) { setRemUnit() } }) //... ``` + 会计算两个值: + rem基准值:放在 html根标签上,执行时机:首次加载,窗体改变大小 + 字体默认大小:放在 body标签上,执行时机:首次记在 ![image-20220309103258250](assets/image-20220309103258250.png) #### 4.5 配置不同 编译基准值 + `.postcssrc.js` ```js module.exports = { plugins: { 'postcss-pxtorem': { // rootValue: 37.5, // 将 多少 像素 转成 1rem rootValue({ file }) { // 如果是 vant 组件库的样式,则使用 37.5 的基准值,否则使用 75的基准值 return file.indexOf('\node_modules\vant') > -1 ? 37.5 : 75 }, // propList 配置 css中需要将px转成rem的 样式属性名称 // propList: ['width','height','font-size'], propList: ['*'], // 选择器黑名单:不被编译的 选择器,凡是符合的选择器中的px 都不会被转成 rem selectorBlackList: ['markdown-body'], // 不被编译的 css文件 exclude: 'github-markdown' } } } ``` ![image-20220309105013059](assets/image-20220309105013059.png) ## Day02登录 ### 5.安装 axios + 第一步:安装: `npm i axios` + 第二步:文件:`./src/utils/request.js` + 只有一个服务器基地址的情况 + 服务器端 有多个 基地址,需要 通过 create创建 n个 axios对象,分配配置基地址 ```js // 方式1:只有一个服务器基地址的情况--------------------- // 负责 统一封装 axios import axios from 'axios' // 1.设置 基地址 (简化 和 复用 基地址) axios.defaults.baseURL: 'http://toutiao.itheima.net/' // 2.默认导出axios export default axios // 方式2:有多个服务器基地址的情况------------------------ // 负责 统一封装 axios import axios from 'axios' // 1.通过 create 创建n个axios实例 // 设置 基地址 (简化 和 复用 基地址) const axios1 = axios.create({ // 设置 当前 axios对象的 基地址 baseURL: 'http://toutiao.itheima.net/' }) // 2.按需导出 export const axios11 = axios1 ``` #### 5.1 axios.create ![image-20220309113828917](assets/image-20220309113828917.png) #### 5.2 关于 axios 拦截器 ![image-20220309112014309](assets/image-20220309112014309.png) #### 5.3 统一添加和访问 + 在 `main.js` 中导入并添加到 Vue原型 ```js import Vue from 'vue'; import App from './App.vue'; import router from './router'; import store from './store'; // ---------------导入 axios -------------------------- import axios from './utils/request.js' // 将 axios 挂载到 Vue原型中 Vue.prototype.$axios = axios Vue.config.productionTip = false; new Vue({ router, // 在 Vue实例中,通过 $router 访问 store, // 在 Vue实例中,通过 $store 访问 render: (h) => h(App), }).$mount('#app1'); ``` + 在 项目`任意 .vue` 组件中,可以直接通过 this 访问 ```js created(){ this.$axios({ url: '/v1_0/channels', method: 'get', }).then(function (res) { console.log(res); }); }, ``` ![image-20220309141556813](assets/image-20220309141556813.png) #### 5.4 axios与try.catch ![image-20220310175555974](assets/image-20220310175555974.png) ### 6.登录组件 #### 6.1 新建组件文件 + `./src/views/login/index.vue` + 编写基础代码 (可以通过代码片段直接生成) #### 6.2 配置登录路由 + 直接 配置,浏览器一旦运行此程序,就会 加载 Login组件到内存中 + 缺点:哪怕用户压根就没有访问这个组件,也会被 加载到内存中!浪费! ```js import login from '../views/login' // 路由表(配置 hash值 和 组件的 映射关系 和 附带参数) const routes = [ { path: '/login', // localhost:80/#/login component: login } ]; ``` + 按需加载组件(延迟加载组件) ```js // 路由表(配置 hash值 和 组件的 映射关系 和 附带参数) const routes = [ { path: '/login', // localhost:80/#/login component: () => import('@/views/login/index.vue') } ]; ``` + 路由管理器 根据 hash 渲染组件 图解: ![image-20220309144338771](assets/image-20220309144338771.png) #### 6.3 vant表单组件 + 表单、输入框、输入框插槽、发送短信按钮、登录按钮 ![image-20220309182352416](assets/image-20220309182352416.png) ```vue ``` ### 8.发送短信功能 #### 8.1 改成普通按钮 + Vant的按钮组件 通过 `native-type="button"`将按钮改成 普通按钮 ```vue 发送验证码 ``` #### 8.2 手动校验 + 为 Vant表单 添加引用名 `ref="引用名"` ```html ``` + 通过 `this.$refs` 获取 组件对象,再通过 `表单组件.validate` 方法来校验指定 输入框是否符合规则 ```js // 发送短信验证码------------------- async sendSms() { // 1.使用 try catch 代替 成功 和 失败回调函数 try { // 执行校验,并返回一个 Promise对象 await this.$refs.loginForm.validate('mobile'); } catch (error) { // 校验失败,直接Return,后面代码就不执行了! return console.log('校验失败了哦~!'); } } ``` #### 8.3 请求短信接口 ```js // 发送短信验证码------------------- async sendSms() { // 1.使用 try catch 代替 成功 和 失败回调函数 try { // 执行校验,并返回一个 Promise对象 await this.$refs.loginForm.validate('mobile'); } catch (error) { // 校验失败,直接Return,后面代码就不执行了! return console.log('校验失败了哦~!'); } this.isShowCount = true; // 2.调用 短信验证码 接口 try { await sendSMS(this.user.mobile); this.$toast.success('发送短信验证码成功~'); } catch (error) { this.$toast.fail('发送短信验证码失败~~!'); console.log('发送短信验证码失败~~!', error.message); } } ``` ![image-20220310175825671](assets/image-20220310175825671.png) ### 9.关于路由组件加载关系 + **一级路由**的组件 会 渲染到 **根组件(App.vue)** 中 `路由占位符` 处 + **二级(子)路由** 的组件 会渲染到 **上级组件** 中的 `路由占位符` 处 ![image-20220310162355913](assets/image-20220310162355913.png) ### 10.layout组件 ![image-20220310174445308](assets/image-20220310174445308.png) + 布局组件,让多个子组件共用 一套底部按钮 + 包含两部分:`二级路由占位符` 和 `底部按钮导航区` + van-tabbar的 route属性,可以开启路由模式: + 点击 内部按钮时,会直接 将 **to 属性值** 设置给浏览器 **hash** ```vue ``` ### 11.父子路由与path + 注意:如果 在配置 **子路由**时 + **path** 没有 使用 `/`,那么 匹配的是 `父路由path+子路由path` + url: `localhost:8080/#/layout/qa` + **path**有 使用 `/`,那么匹配的是 `子路由path` + url: `localhost:8080/#/video` ```js // 路由表(配置 hash值 和 组件的 映射关系 和 附带参数) const routes = [ { path: '/layout', // localhost:80/#/layout component: () => import('@/views/layout/index.vue'), children: [ { path: '', component: () => import('@/views/home/index.vue') }, { path: 'qa', component: () => import('@/views/qa/index.vue') }, { path: '/video', component: () => import('@/views/video/index.vue') }, { path: '/my', component: () => import('@/views/my/index.vue') }, ] } ]; ``` ### 12.个人中心组件 ![image-20220310175216685](assets/image-20220310175216685.png) + 根据 vuex中state.user 值判断是否有登录过 + 内部使用vuex的 `mapState` 函数 将` $store.state.user` 映射为 同名 计算属性 `user` ```vue ``` ## Day04新闻频道tabs ### 13.scoped组件局部样式 #### 13.1 原理 + 为什么要用?`就是想要 组件样式 只作用于 当前组件的标签` + 页面中样式,如果只想用于 当前 组件,则可以使用 **scoped 属性** + 原理: + 根据 当前组件文件名字 生成一个 **hash 值** + 为 组件中 的 选择题 添加一个 **属性选择器**,使用 **hash值** + 为 组件中所有标签 都添加一个 属性,使用 **hash值** ![image-20220311100922909](assets/image-20220311100922909.png) #### 13.2 作用于子组件根标签 + 注意:子组件 的 根标签 也会被 添加 父组件的 hash值属性,所以 也能使用父组件的局部样式 ![image-20220311102627650](assets/image-20220311102627650.png) #### 13.3 深度选择器 + 作用:如果 想在 scoped 样式 作用域 子组件的 标签,就需要使用 深度选择器 + 语法: `/deep/ ` ```css ``` + 原理:前置 `属性选择器` 的 位置 ![image-20220311104011978](assets/image-20220311104011978.png) ### 14.美化未登录头部 ![image-20220311182427583](assets/image-20220311182427583.png) + 未登录头部的修改 ```html
``` + 样式 ```css .not-login { .login-btn { display: flex; flex-direction: column; justify-content: center; align-items: center; .mobile-img { width: 132px; height: 132px; margin-bottom: 15px; } .text { font-size: 28px; color: #fff; } } } ``` ### 15.退出按钮 + 在退出按钮 上 设置点击事件,并绑定 logout 方法 ```html ``` + 添加 logout方法 + 通过 `$dialog 组件` confirm 提示框,点击确认才 退出 + 退出时,直接 将 **vuex仓库** 和 **localStorage** 设置为 空 ![image-20220311111215798](assets/image-20220311111215798.png) + $dialog 的由来 + 在 注册vant组件库 时,就被挂载到 vue原型了 ![image-20220311111034977](assets/image-20220311111034977.png) ### 16.登录页面跳转 + VueRouter 官网:https://router.vuejs.org/zh/introduction.html + 调用 `$router.back()` 本质就是 `window.history.back()` ![image-20220311114428631](assets/image-20220311114428631.png) ### 17.钩子函数 + 4大类,8个钩子函数,重要的4个函数: ```js // 1.created钩子函数【"组件的入口函数"】 // 当 组件对象 初始化完毕(配置信息 都 挂载到 当前组件对象时执行) created() {}, // 2.钩子函数:当视图 首次 渲染完毕执行 mounted() { // 可以访问 到 dom }, // 3.钩子函数:当数据 发生变化,引发【dom更新】后 执行 updated() { // 可以访问到 更新后的 最新dom }, // 4.钩子函数:当组件被销毁时,执行,用来 释放组件占用的资源 // 触发实际 -> this.$destory() // v-if destroyed() {}, ``` ### 18.个人中心.请求用户信息 #### 18.1 axios 添加token + 将 请求报文头 添加 token,注意: + 必须 用 Authorization + 必须 用 Bearer 开头 + 必须 在 Bearer 和 token 之间 加 空格 ![image-20220311193810340](assets/image-20220311193810340.png) + 代码实现: + 在 axios 的参数中 使用 **headers 属性** 添加 **token** ![image-20220311200204796](assets/image-20220311200204796.png) ![image-20220311150651773](assets/image-20220311150651773.png) #### 18.2 请求拦截器设置token + axios 请求拦截器:每当 axios发送请求,都会先 执行 拦截器,再发送请求 + 作用:在请求拦截器中,可以统一修改配置信息 ( 基地址、token... ) ![image-20220311155015757](assets/image-20220311155015757.png) #### 18.3 axios结果对象结构 ![image-20220311200443463](assets/image-20220311200443463.png) ### 20.新闻频道组件 + 根组件 -> Layout -> Home ![image-20220311175908116](assets/image-20220311175908116.png) + 组件代码 ```html ``` + 路由 前面 已经 配置 好了 ![image-20220311185723034](assets/image-20220311185723034.png) #### 20.1添加搜索按钮 + 组件标签和样式 ```vue ``` #### 20.2 频道tabs标签 + 基础标签 + `animated` 切换标签的动画效果 + `swipeable` 滑动效果 ```vue 内容 1 内容 2 内容 3 内容 4 ``` #### 20.3 汉堡按钮 + 基础标签和样式 ```vue 内容 1 内容 2 内容 3 内容 4
``` #### 20.4 请求频道tabs + 从 **服务器获取 频道列表数据**,并通过 `v-for` 遍历生成 `tab` ![image-20220311171527053](assets/image-20220311171527053.png) ### 21. 文章列表组件 + 目的:让每个频道 都 独立保存 自己的 文章列表 和 标签 + 方法:为每个频道 创建 新的 文章列表 组件 ![image-20220311181739302](assets/image-20220311181739302.png) #### 21.1 文章列表组件 + 新建:`./src/views/home/components/artilce-list.vue` ```vue ``` #### 21.2 引用到频道组件 + 将 **文章列表组件** 引入到 **频道组件**,循环生成,并 将**频道数据** 传给 **文章列表组件** ![image-20220311192800166](assets/image-20220311192800166.png) ## Day05.新闻列表组件 ### 22.查询频道新闻列表 ### 23.使用List组件渲染新闻 ### 24.List组件触底加载 ### 25.PullRefresh组件下拉更新 ### 26.新闻去重显示 ### 27.加载成功失败组件提示 ## Day06.新闻列表项组件 ### 文章列表组件 ### 28.van-cell插槽 ### 29.关于组件的Props ### 30.新闻项组件的样式和布局 ### 31.图片referer属性 ### 32.dayjs模块使用 ### 33.过滤器与this ## Day07.频道编辑与搜索历史组件 ### 34.频道编辑弹层显示 ### 35.频道编辑组件 ### 36.推荐频道数据来源 ### 37.频道编辑组件基础样式 ### 38.高亮显示选中频道 ### 39.选择添加用户频道 ### 40.持久化用户频道 + 如果登录了,添加到数据库 + 如果未登录,添加到localStroage ### 41.未登录用户频道保存 ### 42.从本地读取频道数组 ### 43.用户频道编辑状态 ### 44.删除频道数据保持 ### 45.频道白名单 ### 46.搜索组件与路由配置 ### 47.路由配置import易错 ### 48.搜索历史组件 ## Day08.搜索建议与结果组件 ### 49.三个子组件的显示逻辑 ### 50.取消与后退处理 ### 51.搜索建议组件 ### 52.通过侦听器请求建议数据 ### 53.复习正则与字符串替换 ### 54.高亮显示关键字 ### 55.点击关键字显示搜索框 ### 56.使用lodash实现关键字防抖 ### 57.搜索结果组件与数据展示 ## Day09.文章详情 ### 58.文章详情组件 ### 59.路由传参 ### 60.文章数据请求与渲染 ### 61.js大数字解决方案 ### 62.统一请求详情状态码 ### 63.模拟异常与异常处理 ### 64.点击重试与重新加载 ### 65.图片预览插件使用 ## Day10.收藏与refreshToken ### 66.文章关注按钮组件 ### 67.自定义组件与v-model ### 68.refreshToken机制1 ### 69.refreshToken机制2 ## 二.扩展 ### 1.vue根组件替换 + `./public/index.html` 文件 是一个模板,在**编译**和**执行**时使用 ![image-20220308142702978](assets/image-20220308142702978.png) ### 2.VueRouter源码的clone ```js function clone (value) { if (Array.isArray(value)) { return value.map(clone) } else if (value && typeof value === 'object') { var res = {}; for (var key in value) { res[key] = clone(value[key]); } return res } else { return value } } ``` ### 3.Vue.use原理 + 如果传入的 对象 有 install 方法,则会调用 它,完成批量组件注册 ![image-20220308144520748](assets/image-20220308144520748.png) ### 4.import 缓存 ![image-20220308145415991](assets/image-20220308145415991.png) ### 5.全局样式文件编译 ![image-20220308152934142](assets/image-20220308152934142.png) ### 6.格式化时修复错误 + 显示和修复错误,需要两个 扩展插件+配置文件配合使用 ![image-20211226212435833](assets/image-20211226212435833.png) #### 6.1 eslint扩展 修复代码 + eslint 扩展工具 默认 **只检查** 规范问题,但 **不修复** + 为它配置开启修复功能: + 去 vscode 配置文件中设置 ![image-20211226163918879](assets/image-20211226163918879.png) + 代码: ```js "editor.codeActionsOnSave": { "source.fixAll.eslint": true } ``` + 配置好后,再保存代码文件时,就会自动修复了! + **问题:**只能修复 .js 文件,.vue 文件处理不了! + 如果要处理 .vue 文件,就需要 使用 格式化插件了 #### 6.2 vuter.prettier 修复代码 > vscode 的 Prettier 扩展工具专门用来格式化代码,所它也可以根据规范来格式化修复代码 ![image-20211226110619083](assets/image-20211226110619083.png) + 注意:此时,我们不需要单独安装它,因为 **vetur** 内置了 **prettier** **如果已经单独安装了 Prettier,请禁用 或 卸载它,否则 会 影响 eslint 和 vetur 扩展的功能!** ![image-20211226111124614](assets/image-20211226111124614.png) ##### 6.2.1 Vetur介绍 + 功能: + 对 **.vue** 文件 做 语法着色 + 对 **.vue** 代码做格式化( 通过 第三方的 格式化器 来做代码格式化 ) + 什么时候做格式化呢? + 默认 是需要 右键菜单 `格式化文档` 来操作 ![image-20211226111920033](assets/image-20211226111920033.png) + 设置 vscode **保存时** 来格式化 ![image-20211226112020250](assets/image-20211226112020250.png) ##### 6.2.2 格式化时修复错误 + 介绍:Vetur 内部模式使用 **prettier** 来格式化 .**vue 文件** 代码 + 注意: + 语法规范检查 用的是 eslint 语法规范包(airbnb/standard/google/...) + 对.vue 格式化的 用的是 **prettier** 工具自己的语法规范 + **这样容易产生冲突( prettiter 格式化后的 代码 不符合 eslint 的语法规范包,导致eslint报错)** + 解决方案: + 将 **prettier** 的语法规范 配置成 eslint 一致的规范! ##### 6.2.3 prettier 规范配置 + 官网:https://prettier.io/docs/en/options.html + 创建 配置文件 `.prettierrc.js` + 配置 prettier规则: ```js // 配置文件 -> .prettierrc.js module.exports = { // ------------------------最重要---------------------------- // 最大长度80个字符 printWidth: 80, // 使用单引号, 默认false(在jsx中配置无效, 默认都是双引号) singleQuote: true, // 行末分号, 默认true semi: false, // 尽可能使用尾随逗号(包括函数参数),默认none,可选 none|es5|all // es5 包括es5中的数组、对象 // all 包括函数对象等所有可选 trailingComma: 'none', // ------------------------------------------------------------ // 对象字面量的大括号间使用空格(默认true) { a:1 } bracketSpacing: true, // 箭头函数参数括号 默认avoid 可选 avoid| always // avoid 能省略括号的时候就省略 如x => x // always 总是有括号 如(x) => x arrowParens: 'always', // tab缩进大小,默认为2 tabWidth: 2, // 使用tab缩进还是空格,默认false useTabs: false, // ------------------------------------------------------------ // vue缩进脚本和样式 vueIndentScriptAndStyle: false, // 在文件顶部插入一个特殊的 @format 标记,指定文件格式需要被格式化。 insertPragma: false, // 行尾换行格式 endOfLine: 'auto', // html空格敏感度 htmlWhitespaceSensitivity: 'ignore', // jsx 中的 > 标签放在最后一行的末尾,而不是单独放在下一行 默认false // jsxBracketSameLine: true, // JSX双引号 // jsxSingleQuote: false, }; ``` > 大功告成,现在,项目 在打开代码文件后,会自动显示 规范错误 > 在保存代码时,可以自动格式化 并 修复代码错误啦~! ### 7.vscode代码片段 + 作用:能快速 生成 模板代码 + 步骤: 1. **vscode菜单**: -> 文件 -> 首选项 -> **用户片段** 2. 选择 **新建全局代码频段文件...**,并输入 文件名 ![image-20220309142254253](assets/image-20220309142254253.png) 3. 复制代码片段并保存: ```js { "vue文件结构": { "prefix": "v2", "body": [ "", "", "", "", "", "" ], "description": "vue 三个标签结构 ,div容器,导入 lib/vue.js,创建vue 实例" } } ``` ### 8.VueRouter监控hash值 ![image-20220310181010340](assets/image-20220310181010340.png) ### 9.组件初始化 + 编译时:`.vue`文件被编译成 `VueComponent`组件 + 执行时:会 将 **export default** 的**配置对象所有成员**,添加到 **当前组件对象** 中 ![image-20220311195602374](assets/image-20220311195602374.png) ## 三.常见问题 ### 1.对象null错误 ![image-20220311200652596](assets/image-20220311200652596.png) ### 2.子组件属性检查错误 ![image-20220316105219944](assets/image-20220316105219944.png) ### 3.常见脚本问题 #### 3.1找不到 脚本 ![image-20220310103558395](assets/image-20220310103558395.png) + 原因有两种: + 其一:没有安装 这个包! + 其二:系统找不到这个包的 安装路径 + 解决方式: + 其一:安装这个包 `npm i -g yarn` + 其二:将 npm 的 全局全装路径 添加到 环境变量中! + 查看npm 全局安装路径: `npm config get prefix` + 将 路径 添加到 环境变量中! + 配置 yarn 的全局安装路径 到 环境变量 + 查看 yarn 全局包的脚本路径: `yarn global bin` + 将 路径 添加到 环境变量 #### 3.2 禁止运行脚本 ![image-20220310104544693](assets/image-20220310104544693.png) + 操作系统默认 关闭了 脚本运行的**开关**,需要手动打开: + `set-executioinpolicy remotesigned` + 输入 `y `就可以了 ![image-20220310104645353](assets/image-20220310104645353.png) ## 四.面试题 ```html ```