尚品汇项目笔记目录
1、vue文件目录分析
node_modules: 文件夹:项目依赖文件夹
public文件夹: 一般防置一些静态资源(图片),需要注意的,放在public文件夹中的静态资源,webpack进行打包的时候,会原封不动的打包到dist文件夹中.
src文件夹(程序员源代码文件夹):
assets文件夹:一般也是防置静态资源(一般防置多个组件共用的静态资源),需要注意,防置assets文件夹里面静态资源,在webpack打包的时候,webpack会把静态资源当做一个模块,打包JS文件里面。
components文件夹: 一般放置的是非路由组件(全局组件)
APP.vue:唯一的根组件,Vue当中的组件(.vue)
main.js:程序的入口文件 也是最先执行的文件
babel.config.js: 配置文件(babel相关)
package.json: 认为是项目的身份证,记录项目叫什么,项目当中有哪些依赖、项目怎么运行。
package-lock.json: 缓存性文件
README.md: 说明性文件
2、项目的其他配置
2.1项目运行起来的时候,让浏览器自动打开 --package.json
"scripts":{"serve":"vue-cli-service serve --open","build":"vue-cli-service build","lint":"vue-cli-service lint"},
2.2eslint校验功能关闭(根目录下创建vue.config.js)
不关闭会有各种规范,不按照规范就会报错
module.exports ={
//关闭eslint
lintOnSave: false
}
2.3src文件夹简写方法,配置别名
jsconfig.json别名@提示【@代表的src文件夹,这样将来文件过多,找的时候方便很多】
{"compilerOptions":{"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths":{"@/*": [
"src/*"
]
},"lib": [
"esnext","dom","dom.iterable","scripthost"
]
}}
3、组件页面样式
组件页面的样式使用的是less样式、浏览器不识别该样式,需要下载相关依赖
npm install --save less less-loader@5
如果想让组件识别less样式,则在组件中设置
<script scoped lang="less">
4、清除默认的样式
修改public下的index.html文件
<!-- 引入清除默认的样式 -->
<link rel="stylesheet" href="./reset.css">
5、pages文件夹
创建pages文件夹,并创建路由组件
5.1创建router文件夹
创建index.js进行路由配置,最终在main.js中引入注册
5.2路由组件与非路由组件的区别?
1:路由组件一般放置在pages|views文件夹,非路由组件一般放置components文件夹中
2:路由组件一般需要router文件夹中进行注册(使用的即为组件的名字),非路由组件在使用的时候,一般都是以标签的形式使用
3:注册完路由,不管路由组件、还是非路由组件身上都有$route
、
$router
属性
$route:一般获取路由信息【路径、query、params等等】
$router:一般进行编程式导航进行路由跳转【push|replace】
5.3路由的跳转有两种形式
(1)声明式导航router-link,可以进行路由的跳转;
(2)编程式导航push|replace,可以进行路由跳转;
编程式导航:声明式导航能做的,编程式都能做;
但是编程式导航除了可以进行路由跳转,还可以做一些其他的业务逻辑。
6、路由相关面试题*
// 路由传参://第一种:字符串形式this.$router.push("/search/"+this.keyword+"?k="+this.keyword.toUpperCase());//第二种:模板字符串this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`)//第三种:对象this.$router.push({name:"search",params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}})
6.1、路由传递参数(对象写法)path是否可以结合params参数一起使用?
答:路由跳转传参的时候,对象的写法可以是name、path形式,但是需要注意的是,path这种写法不能与params参数一起使用。
6.2、如何指定params参数可传可不传?
如果路由要求传递params参数,但是你就不传递params参数,会导致URL出现问题;
可在配置路由的时候,在占位的后面加上一个问号【params可以传递或者不传递】;
6.3、params参数可以传递也可以不传递,但是如果传递是空串,如何解决?
使用undefined解决:params参数可以传递、不传递(空的字符串)
this.$router.push({name:"search",params:{keyword:''||undefined},query:{k:this.keyword.toUpperCase()}})
6.4、路由组件能不能传递props数据?
(1)布尔值写法:params
props:true,
(2)对象写法:额外的给路由组件传递一些props
props:{a:1,b:2},
(3)函数写法:可以params参数、query参数,通过props传递给路由组件
props:($route)=>({keyword:$route.params.keyword,k:$route.query.k})
注意:在路由配置router内写
6.5、编程式路由跳转到当前路由(参数不变),多次执行会抛出NavigationDuplicated的警告错误?
- 路由跳转有两种形式:声明式导航、编程式导航
- 声明式导航没有这类问题的,因为vue-router底层已经处理好了
6.5.1为什么编程式导航进行路由跳转的时候,就有这种警告错误呢?
“vue-router”:"^3.5.3":最新的vue-router引入promise
6.5.2通过给push方法传递相应的成功、失败的回调函数,可以捕获到当前错误,可以解决
6.5.3通过底层的代码,可以实现解决错误
this.$router.push({name:"search",params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()},()=>{},()=>{}});
这种写法:治标不治本,将来在别的组件当中push|replace,编程式导航还是有类似的错误。
终极解决方案:重写push
//重写push|replace//第一个参数:原来push方法,你在哪里跳转(传递哪些参数)VueRouter.prototype.push =function(location,resolve,reject){if(resolve && reject){
originPush.call(this,location,resolve,reject);}else{
originPush.call(this,location,()=>{},()=>{});}}VueRouter.prototype.replace =function(location,resolve,reject){if(resolve && reject){
originReplace.call(this,location,resolve,reject);}else{
originReplace.call(this,location,()=>{},()=>{});}}
6.6、call与apply区别?
相同点:都可以调用函数一次,都可以篡改函数的上下文
不同点:call与apply传递参数:call传递参数用逗号隔开,apply方法执行,传递数组
7、footer组件显示与隐藏
- footer在登录注册页面是不存在的,所以要隐藏,v-if 或者 v-show
- 这里使用v-show,因为v-if会频繁的操作dom元素消耗性能,v-show只是通过样式将元素显示或隐藏
- 配置路由的时候,可以给路由配置元信息meta,
- 在路由的原信息中定义show属性,用来给v-show赋值,判断是否显示footer组件
8、路由传参
8.1query传参
(1)query参数:不属于路径当中的一部分,类似于get请求,地址表现为/search?k1=v1&k2=v2
(2)query参数对应的路由信息path:“/search”
8.2params传参
(1)params参数:属于路径当中的一部分,需要注意,在配置路由的时候,需要占位,地址栏表现为
/search/v1/v2
(2)params参数对应的路由信息要修改为
path:“/search/:keyword”
这里的
/:keyword
就是一个params参数的占位符。
8.2.1params传参问题
(1)如何指定params参数可传可不传
如果路由path要求传递params参数,但是没有传递,会发现地址栏URL有问题,详情如下:
Search路由项的path已经指定要传一个keyword的params参数,如下所示:
path: "/search/:keyword",
执行下面进行路由跳转的代码:
this.$router.push({name:"Search",query:{keyword:this.keyword}})
当前跳转代码没有传递params参数
地址栏信息:http://localhost:8080/#/?keyword=asd
此时的地址信息少了/search
正常的地址栏信息:http://localhost:8080/#/search?keyword=asd
解决方法:可以通过改变path来指定params参数可传可不传
path:"/search/:keyword?",?表示该参数可传可不传
(2)传参方法
//第一种:字符串形式this.$router.push("/search/"+this.keyword+"?k="+this.keyword.toUpperCase());//第二种:模板字符串this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`)//第三种:对象this.$router.push({name:"search",params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}})//params参数可以传递也可以不传递,但是如果传递是空串,如何解决?this.$router.push({name:"search",params:{keyword:this.keyword||undefined},query:{k:this.keyword.toUpperCase()}})
9、定义全局组件
1、全局组件的配置都需要在main.js中配置
2、全局组件可以在任一页面中直接使用,不需要导入声明
//将三级联动组件注册为全局组件
import TypeNav from '@/pages/Home/TypeNav';
//第一个参数:全局组件名字,第二个参数:全局组件
Vue.component(TypeNav.name,TypeNav);
10、vue项目热更新
module.exports={//关闭eslint
lintOnSave:false,
devServer:{// true 则热更新,false 则手动刷新,默认值为 true
inline:true,// development server port 8000
port:8001,}}
注意:修改完该配置文件后,要重启一下项目
11、封装axios
在根目录下创建api文件夹,创建request.js文件
//对于axios进行二次封装importaxios from 'axios'importnprogress from 'nprogress';//引入进度条样式 start:进度条开始 done:进度条结束import"nprogress/nprogress.css"//1、利用axios对象的方法create,去创建一个axios实例//2、request就是axios,只不过稍微配置一下const requests = axios.create({//配置对象//基础路径,发请求的时候,路径当中会出现api
baseURL:'/api',//代表请求超的时间5s
timeout:5000,});//请求拦截器:在发请求之前,请求拦截器可以检测到,可以在请求发出去之前做一些事情
requests.interceptors.request.use((config)=>{//config:配置对象,对象里面有一个属性很重要,headers请求头//进度条开始动
nprogress.start();return config;})//响应拦截器
requests.interceptors.response.use((res)=>{//成功的回调函数:服务器响应数据回来以后,响应拦截器可以检测到,可以做一些事情//进度条结束
nprogress.done();return res.data;},(error)=>{//失败的回调函数
console.log("响应失败"+error)returnPromise.reject(newError('fails'));})//对外暴露
export default requests;
实际代码展示图
12、前端解决跨域问题-webpack
在根目录下的vue.config.js中配置,proxy为通过代理解决跨域问题。
module.exports={//关闭eslint
lintOnSave:false,//代理跨域
devServer:{// true 则热更新,false 则手动刷新,默认值为 true
inline:false,// development server port 8000
port:8001,//代理服务器解决跨域
proxy:{'/api':{
target:'http://39.98.123.211'}}}}
我们在封装axios的时候已经设置了baseURL为api,所以所有的请求都会携带/api,这里我们就将/api进行了转换。如果你的项目没有封装axios,或者没有配置baseURL,建议进行配置。要保证baseURL和这里的代理映射相同,此处都为’/api’。
13、请求接口统一封装
1、在文件夹api中创建index.js文件,用于封装所有请求
2、将每个请求封装为一个函数,并暴露出去,组件只需要调用相应函数即可,这样当我们的接口比较多时,如果需要修改只需要修改该文件即可。
//当前这个模块:API进行统一管理importrequest from '@/api/request';//三级联动接口 api/produce/getBaseCategoryList get 无参数
export const getBaseCategoryList =()=>{returnrequest({
url:'/product/getBaseCategoryList',
method:'get'})}
14、nprogress进度条插件
版权归原作者 java亮小白1997 所有, 如有侵权,请联系我们删除。