文章目录
1. 项目工具准备
-
问题:如何创建一个脚手架项目:
-
前提:需要保证正确安装@vue/cli全局包并得到vue命令一次
yarn global add @vue/cli
npm i @vue/cli -g -
创建命令
vue create 脚手架文件名
-
-
问题:用yarn或者npm如何运行项目带的自定义命令?
- 前提:自定义命令在package.json里scripts选项定义的,右侧才是真正执行的命令
- 前提:敲击命令时,终端所在的文件夹,应该是package.json所在的文件夹(项目文件夹)
npm run 自定义命令
yarn run 自定义命令
-
问题:什么是ESLint?
- 代码检查工具(本质上:它是脚手架环境带的包和配置,也是一些代码)
- 运行在哪两个地方?
- webpack开发服务器环境下(终端)
- vscode+eslint插件,编写代码区域
- 如何让vscode自动修复一些问题?
- vscode打开项目的根目录(eslint插件要用根目录下eslintrc.js文件规则)
- eslint插件填入配置
- 按ctrl+s可以修复文件的一些语法问题
2. 项目框架准备
组件库
- 什么是组件库?
- 别人封装好的样式标签和一些vue功能代码,多个组件形成的一个仓库(其实也是一个包)
- 是否使用组件库?用的是哪个?如何使用?
- 采用的是ElementUI组件库,根据文档说明,下载并引入到项目代码中,全局注册了组件
- 项目为何要使用组件库?
- 用它封装好的标签和样式和vue代码,快速的搭建我的项目
- 是否所有的项目都适用组件库?
- 你要做的项目设计图(标签和样式)和现有的组件库比较贴合,才能使用贴合的这个组件库
网络请求库
- 采用的是哪个网络请求的库?
- axios库
- 项目里是如何管理网络请求的?
- 下载到axios包到当前项目文件夹中
- 封装request请求并配置基地址
- 封装统一api接口方法
- 在逻辑页面,需要用到哪个就引入,然后调用,等待请求后的结果,在逻辑页面使用后台返回数据
管理准备
项目代码版本管理工具:git
- 新/旧项目,确保有什么文件夹?
- 确保项目文件夹下,有隐藏的.git文件夹(它里面记录了你所有的版本提交,远程仓库相关配置)
- 如果没有则运行如下命令,初始化一个:git init
- 别人的/克隆的项目,我们需要git init吗?
- 不需要,因为项目已经拥有了git仓库
拿到:
-
旧项目(进公司第一件事)?如何得到别人的项目代码?
- 先知道git远程仓库的地址
- 本机新建空白的文件夹,敲击如下命令,第一次克隆
- git clone 远程仓库git地址
-
克隆命令是做什么的呢?
- 把远程仓库git地址位置对应的代码+它里面所有之前提交记录都下载到本地
Note:- https开头的地址,如果是公开的仓库,可以直接克隆
- https开头的地址,如果是私有的仓库,你必须要在git仓库网站注册账号,让管理员拉你进组,才能克隆
- git@开头的地址,如果是公开的仓库,你必须要在git仓库网站注册账号,并把本机电脑和远程网站账号配置ssh秘钥,才能克隆
- git@开头的地址,如果是私有的仓库,你必须要在git仓库网站注册账号,并把本机电脑和远程网站账号配置ssh秘钥,还要让管理员拉你进组,才能克隆
- 把远程仓库git地址位置对应的代码+它里面所有之前提交记录都下载到本地
-
如果远程仓库有更新,如何拿到更新以后的内容到本地?
-
如果本地无变更
git pull
-
如果本地有变更
git add.
git commit -m ‘写点你本次提交了什么,注释,为了方便以后回滚到这里查看注释’
git pull
注释: 提交一次就会在本地git仓库里出现一次提交保存的记录(本时间节点的代码记录一次快照)
git pull 以后会把远程更新和本地的更新合并到一个项目内,所以冲突很有可能发生在这个命令后 -
推送:
-
本机,每次写完一个功能,本地提交一次,暂时不上传?
git add.
git commit -m ‘注释’ -
如果今日代码写完了,你本地git记录有很多次,一次性,想要保存到远程仓库上?
-
本地仓库第一次新建的,无远程仓库配置
git remote add origin 远程仓库git地址
git push -u origin master // 把本地master主分支所有提交记录,推送到远程仓库的master主分支上,-u配置一条通道以后直接本地在master分支时,可以直接git push即可 -
之前本地仓库已经配置好了,远程仓库的地址
git push
-
3. 代码问题
包和模块的使用
-
什么叫包?
- 多个模块组成的一个文件夹,默认会有出口文件和导出,让别人引入它封装的代码使用
-
什么叫模块?
- 封装的一些属性和方法的文件/webpack是一个静态模块打包工具(每个文件都会被认为是一个模块)
- 特点:js模块需要导出,别的文件想要使用其内部的东西需要导入
- 模块导出和导入的语法
- 默认导出:export default 对象/函数
- 默认导入:import 变量名 from ‘模块标识’(自己模块:相对路径开头,第三方模块直接写模块名)
- 命名导出:export 变量声明
- 命名导入:import {同名变量} from ‘模块标识’
-
问题:npm 或 yarn 如何下包?
npm i 包名
yarn add 包名 -
问题:如何在下包的时候,指定版本?
- 前提:npmjs.com网站搜下这个包有哪些版本/通过百度,笔记得知适配版本
yarn add 包名@版本号
npm i 包名@版本号
- 前提:npmjs.com网站搜下这个包有哪些版本/通过百度,笔记得知适配版本
-
问题:下的包都在哪里呢?
- 在node_modules下
-
问题:下的包如何在工程里使用?
- 在需要使用的文件里,用import引入过来
-
问题:yarn 和 npm 下的包,用import引入,但是浏览器不能直接识别import语法,我们下的包是如何作用在html网页里的?
- webpack构建工具,翻译预执行你的代码,然后把打包后的代码放到html中运行
-
问题:如果拿到别人的项目,发现没有node_modules,怎么办?
- npm i 或者 yarn
Vue.use作用
它其实为了给Vue扩展一些功能,给Vue添加插件
我们把函数或者对象带install方法的交给Vue.use方法内部,它会调用你的函数/install方法回传过来vue类
那你可以在函数内部给Vue添加一些全局功能,全局属性,全局方法,全局组件,全局自定义指令
Vue.use((Vue) => {
Vue.prototype.$a = 10
Vue.prototype.$message = () => {}
Vue.component()
Vue.directive()
})
Vue.use({
install(Vue){
Vue.prototype.$a = 10
Vue.prototype.$message = () => {}
Vue.component()
Vue.directive()
}
})
Vue代码里使用其他文件
- style和template标签里直接写路径即可,webpack分析到路由后,会把目标文件当做模块引入和打包处理并转换真实路径
- js里,我们需要自己显示写出import语句来引入其他的模块文件(例如图片),引入后数据我们才能赋予到template里标签上
特殊:如果图片是外链,字符串直接使用后,浏览器发现http://直接请求外部服务器地址,就不会有问题;如果图片是相对路径,必须在当前服务器环境下,保证运行时相对路径正确
Vuex如何使用
- store只能是唯一的一个
state里定义全局状态变量 - mutations里唯一同步修改state里的值
用store.commit(‘要触发的mutations函数名’)出来mutations里函数执行
- actions里定义异步代码(一般调用后端接口,然后把值commit给mutations)
用store.dispatch(‘要触发的actions函数名’)触发actions里函数执行
- modules:分模块
el-form表单数据问题
el-form在第一次创建并挂载的时候,会使用model对应数据对象值,复制到内部作为初始值(这个值以后不会受到影响),接着调用resetFields()方法,它会用model绑定的初始值来重置。
问题:先给了要编辑的值,再让el-form出现,它用到了要编辑的值作为默认值,置空不掉
解决:让回显的值稍微慢点执行
4. 经验问题
- 前端项目中,如何让用户看到一个美观的按钮,点击后能选择文件?
- 准备原生input[type=file]标签并用CSS方式隐藏起来
- 再准备美观按钮绑定点击事件,在事件方法中获取input标签,并用js触发它的点击事件,导致它的选择窗口默认行为出现
- 给input绑定change事件,等待它选择后通过事件对象.target.files拿到文件数组
- 如果用户选择的是图片文件,如何做纯前端的预览?
- 前提:img标签的src属性的值,只能是图片base64字符串(data:image/png格式开头的)或者是图片链接地址
- 图片文件 -> 图片base64字符串
const fr = new FileReader() fr.readAsDataURL(files[0]) // 传入文件对象开始读 fr.onload = (e) => { // onload等待把文件读成base64字符串后会触发onload事件函数 //e.target.result的值就是读完的结果 this.avatar = e.target.result // 赋予给变量,让他显示在img的src中 }
- 图片文件 -> 前端临时地址
注意:此地址只能在浏览器本地使用,不能传给后台URL.createObjectURL(file[0])
- 图片文件 -> 图片base64字符串
- 如何把图片文件传递给后台?
- 图片base64字符串
- 可以用application/json的格式,传递json字符串给后台
- 可以用formData,传递表单数据给后台
- 图片文件本身直接发给后台
- 可以用formData,传递表单数据给后台
const fd = new FormData() // 准备一个表单数据对象的容器 FormData类是HTML5新出的专门为了装文件内容和其他的参数的容器 fd.append('title', this.pubForm.title) fd.append('cate_id', this.pubForm.cate_id) fd.append('content', this.pubForm.content) fd.append('cover_img', this.pubForm.cover_img) fd.append('state', this.pubForm.state)
- 图片base64字符串
- 后台返回的图片路径,为何只有后半段?(文章详情)
- 防止以后后台服务器域名更改,频繁切换的麻烦
- 后端告诉前端前缀固定地址,让前端请求时自己拼接即可
组件默认值问题
- 效果:控制台里报错了,但效果还是出来了
- 知识点:组件在创建和挂载时,会先使用data里变量默认值,让template标签渲染一次,可能你取到的undefined导致了报错。接着,网络请求的数据稍后回来了,会让使用此变量的标签重新更新,所以效果出现了
- 解决:v-if先让没有数据的时候,标签不去加载默认值防止报错,等数据回来后,v-if为true,标签再创建执行
函数形参的对象解构赋值
- 不解构,正常传递
const getListFn = (obj) => { console.log(obj.name) console.log(obj.age) console.log(obj.sex) } const perObj = { name:'老李', age:18, sex:'男' } getListFn(perObj)
- 函数形参如果是个对象,那解构一下
- 函数内,用对象变量一个个点我觉得有点麻烦
- 目标:我想用3个变量,分别提取对象里同名属性的值
const getListFn = ({name:name, age:age, sex:sex, 同名key:变量名}) => { // 本来用一个变量接受一个大对象 // obj = {name:'xiaochen', age:18, sex:'female'} // 正常写解构赋值(快速提取对象里属性的值),解构赋值语法: // {key名:变量名} = {key名:值} // 运行时效果:变量名里装的,会是右侧赋予给左边的值 // {name:name1,age:age1,sex:sex1} = {name:'xiaochen', age:18, sex:'female'} // 变量名可以随便起,可以简化一下 // key和value变量名同名可以简写 { name, age, sex } = {name:'xiaochen', age:18, sex:'female'} } const perObj = { name:'xiaochen', age:18, sex:'female' } getListFn(perObj)
token判断
- 在全局前置路由守卫中,我们用token只能判断什么
- 判断它是否登录,有token证明登录过(即使过期的),可以看到登录才能看到的页面放行
- 如果未登录,无token值,如果你要去登录页面/注册页面放行,其他页面强制next切换到登录页面
- 在axios响应拦截器里,我们判断的是token的什么?
- 前端携带过期token给后端,后端验证过期后返回401,进入响应拦截器
- 我们在响应拦截器里写判断代码,所以401了,就强制退出登录
- 在axios请求拦截器里,我们对token做了什么?
- 把token值携带在请求头上,任意一次请求都会执行这里携带
退出登录
无论是主动退出,还是被动(强制)退出
- 清除vuex和本地的值
- 强制切换到登录页面
新增和编辑用同一套标签和代码
怎么在点击确定的时候区分,是新增/编辑
1. 定义变量标记一下,如isEdit(true是编辑,false是新增),默认为false
2. 在点击编辑的时候,isEdit改为true
3. 在点击新增的时候,isEdit改为false
4. 在点击确定的时候,就用isEdit变量做区分即可
在组件上绑定的原生事件名字
- 在组件标签上,绑定的原生事件名字,是原生的事件?
- 不是,需要组件标签内,通过$emit()来触发才行,所以去看看文档/试试
- 如果不支持
- 先用@原生事件名.native修饰符,它可以试着给组件根标签绑定原生事件
- 看看是否可以用插槽,传入原生标签显示内容,在原生的标签上绑定原生的事件
前端参数名
最后对象的属性名,直接和一会儿要调用的接口需要的参数名一致
我们可以直接把对象传递给后台