Vue2电商前台项目——项目的初始化及搭建
Vue基础知识点击此处——Vue.js
文章目录
- Vue2电商前台项目——项目的初始化及搭建
- 一、项目初始化
- 1、脚手架目录介绍
- 2、项目的其他配置
- 二、项目的路由分析及搭建
- 1、项目的路由分析
- 2、开发项目的步骤
- 3、非路由组件的搭建
- 4、路由组件的搭建
- (1)配置并使用路由器
- (2)路由组件与非路由组件的区别?
- (3)重定向
- (4)路由跳转的两种方式
- 三、Footer组件的显示与隐藏——路由元信息
- 四、路由传参
- 1、复习路由跳转的两种方式
- 2、路由传参,参数有几种写法?
- 3、路由传参复习题(⭐)
- 五、解决bug
一、项目初始化
使用脚手架创建项目,在需要放置项目的目录下打开cmd输入:
vue create name
- 这个name是项目名(我的项目名是potato-mall
创建有问题或者不太熟悉的具体参考之前的脚手架配置笔记
1、脚手架目录介绍
项目创建成功后,点开项目目录,会出现以下文件:
这些文件说明如下:
node_modules文件夹:放置项目的依赖
public文件夹:一般放置的是静态资源(图片),需要注意:放在public文件夹中的静态资源,webpack进行打包的时候,会原封不动打包到dist文件夹中,不会当做一个模块打包到 JS 里面
src文件夹(程序员源代码文件夹):
-
assets文件夹:一般放置的是静态资源(一般放置多个组件公用的的静态资源),需要注意:放置在assets文件夹里面的资源,webpack打包的时候,会把静态资源当做一个模块,打包到JS文件里面
-
components文件夹:一般放置的是非路由组件(全局组件)
-
App.vue :唯一的根组件,Vue当中的组件都是(.vue)
-
main.js:程序的入口文件,也是整个程序当中最先执行的文件
babel.config.js:配置文件,与babel相关
package.json文件:项目“身份证”,记录着项目信息,叫什么…有哪些依赖…项目怎么运行…
package-lock.json:缓存性文件
README.md:说明性文件
2、项目的其他配置
(1)项目运行起来时,自动打开浏览器
找到package.json文件,找到"scripts"进行如下修改:
"scripts": {
"serve": "vue-cli-service serve --open", //在后面加“--open” 运行时自动打开浏览器
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
(2)eslint语法校验功能关闭。
可关可不关,开启会报错但是不影响代码运行。
在根目录下,创建一个vue.config.js文件(一般创建项目时自带这个文件),添加以下代码:
const { defineConfig } = require("@vue/cli-service");
module.exports = defineConfig({
transpileDependencies: true,
//关闭eslint语法校验
lintOnSave: false,
});
(3)src文件夹简写方法,配置别名。
在jsconfig.json文件中。@代表的是src文件夹,这样将来文件过多,找的时候方便很多。
二、项目的路由分析及搭建
1、项目的路由分析
前端所谓路由:key-value键值对
key:URL(地址栏中的路径)
value:相应的路由组件
项目结构:上中下结构
非路由组件:Header
,Footer(首页,搜索页)
路由组件:Home首页
,Search搜索
,login登录(无Footer)
,register注册(无Footer,可以通过条件渲染控制)
2、开发项目的步骤
-
书写静态页面(HTML,CSS)
-
拆分组件(路由/非路由)
-
获取服务器的数据动态展示
-
完成相应的动态业务逻辑
注意1:创建组件的时候,找准 组件结构 + 组件的样式 + 图片资源
注意2:项目如果采用的less样式,浏览器不识别less样式,需要通过less、less-loader【安装六版本】进行处理less:npm i less-loader@6,如果想要组件识别less样式,需要在style标签加上lang=“less”。(如果运行时less还是报错,可以尝试关闭项目再重新进入重新运行上面的安装命令)
注意3:引入清除默认样式,将默认样式文件放在public文件夹内,在index.html里引入。
3、非路由组件的搭建
非路由组件一般都写在components文件夹里,本项目有Header和Footer。
组件的使用步骤:
-
创建或定义组件
-
引入组件
-
注册组件
-
使用组件
4、路由组件的搭建
(1)配置并使用路由器
Vue2安装vue-router,命令:npm i vue-router@3
Vue3安装vue-router,命令:npm i vue-router
前面我们已经了解学习过,详情请查看笔记——路由的基本知识及使用
路由组件有四个:Home(首页),Search(搜索),Login(登录),Register(注册)
components
文件夹:经常放置 非路由组件 (公用全局组件)
pages
|views
文件夹:经常放置 路由组件
项目中配置的路由一般放置在router文件夹中,在里面配置路由。
用<router-view></router-view>
指定展示位置,然后登录,注册,搜索这几个a标签都换成router-link
标签,href
换成to
(2)路由组件与非路由组件的区别?
-
路由组件一般放置在pages|views文件夹,非路由组件一般放置在components文件夹中
-
路由组件一般需要在router文件夹中的index.js文件中配置路由规则(使用路径和组件名字等属性),非路由组件在使用的时候,一般都是以标签的形式使用
-
注册完路由,不管是路由组件还是非路由组件,身上都有 r o u t e , route, route,router属性
r o u t e :一般获取路由信息【路径, q u e r y , p a r a m s 等等】,其实非路由组件当中的 t h i s . route:一般获取路由信息【路径,query,params等等】,其实非路由组件当中的this. route:一般获取路由信息【路径,query,params等等】,其实非路由组件当中的this.route就是当前显示的路由组件的一些信息,比如路径,name,meta等等
$router:一般进行编程式导航进行路由跳转【push | replace】
(3)重定向
在项目跑起来的时候,访问/,立马让他定向到首页 写在 src/router/index.js
文件里
(4)路由跳转的两种方式
-
声明式导航router-link
-
编程式导航 push| replace
声明式路由导航可以做的事情 编程式导航都能做,除此之外,编程式导航还能做一些其他的业务
这两种路由跳转方式在前面笔记有,并且有案例说明,详情点击此处——编程式路由导航
- 如果只是路由跳转,没有其他业务逻辑,使用声明式导航router-link
- 如果路由跳转时需要其他业务逻辑,比如传参,可以使用编程式导航
这里的搜索按钮需要带着搜索框里的输入信息进行路由跳转,使用编程式导航:
注意:使用编程式导航时这里的搜索按钮多次点击重复导航可能出现报错的情况,可以在每次调用时加上捕获异常的方法,也可以在route/index.js里加上下面这段代码解决这个问题,原理是对Router原型链上的push、replace方法进行重写,用call改变this指向,抛出异常。
let originPush = VueRouter.prototype.push; //备份原push方法
VueRouter.prototype.push = function (location, resolve, reject){
if (resolve && reject) { //如果传了回调函数,直接使用
originPush.call(this, location, resolve, reject);
}else { //如果没有传回调函数,手动添加
originPush.call(this, location, ()=>{}, ()=>{});
}
}
三、Footer组件的显示与隐藏——路由元信息
显示或隐藏组件:v-if
/ v-show
Footer组件在 Home,Search中是显示的,在Login和Register中是隐藏的
我们可以根据$route.path
是否是home或search来控制Footer的显示与隐藏
<Header></Header>
<!-- 路由组件出口 -->
<router-view></router-view>
<!-- 在Home、Search显示,其他隐藏 -->
<Footer
v-show="$route.path === '/home' || $route.path === '/search'"
>
</Footer>
但是如果有很多组件都要显示Footer呢?就要写很多,这样不太好。
this.$route
里存放着当前页面路径下的路由信息,我们可以利用其中的meta属性,也就是路由元信息
四、路由传参
params和query参数是可以一起传的
1、复习路由跳转的两种方式
声明式导航:router-link(务必要有to属性)
编程式导航:利用的是组件实例的$router.push | replace 方法
2、路由传参,参数有几种写法?
参数分别有params参数和query参数,详情请点击此处——路由传参
query参数
:/home?k=v&kv=,不需要占位
params参数
:在配置路由的时候,需要占位
路由携带
params
参数时,若使用to
的对象写法
,则不能使用path
配置项,必须使用name
配置!而且params需要去占位!
3、路由传参复习题(⭐)
-
路由传递参数(对象写法) path是否可以结合params参数一起使用?
不可以。路由跳转传参的时候,对象的写法可以是name,path的形式,但需要注意的是,path这种写法不能与params参数一起使用
-
如何指定params参数可传可不传?
在配置路由的时候,给params占位 的后面加上?,代表可传递也可以不传递
比如:配置路由的时候如果已经给params参数占位了但不写问号,那么路由跳转的时候不传递params参数,路径就会出现问题 。你跳转的本来是 http://localhost:8080/#/search/k=QWE 这个位置,结果你跳转的是 http://localhost:8080/#/k=QWE 这个位置,search路径直接没了,这可不行
-
params参数可传递也可以不传递,但是如果传递是空串,如何解决?
若有占位符也有问号,但传递的是空串的话,路径也会有问题(和上面路径问题一样,search直接没了)
使用undefined解决:params参数可传递不可传递的时候,传递是空串路径有问题的错误
params:{
keyWord:'' || undefined,
},
- 路由组件能不能传递props数据?
可以的,有三种写法:对象式,布尔值,函数式,具体见笔记路由中的props配置
五、解决bug
编程式路由跳转到当前路由(参数不变),多次执行会抛出NavigationDuplicated的警告错误?
因为路由跳转有两种形式:声明式导航,编程式导航,其中声明式导航没有这类问题,因为vue-router底层已经处理好了
为什么编程式导航进行路由跳转的时候,就有这种警告错误?
1、“vue-router”: “^3.6.4”:最新的vue-router引入promise,push返回的是promise,promise有两个形参,成功返回的函数和失败返回的函数
通过push方法传递相应的成功,失败的回调函数,可以捕获到当前错误,可以解决
通过下面的代码可以实现解决错误
this.$router.push({
// 第三种:对象写法
name:'sousuo',
// params参数
params:{
keyWord:'' || undefined,
},
// query参数
query:{
k:this.keyWord.toUpperCase()
}
},()=>{},()=>{})
这种写法治标不治本,将来在别的组件当中 push | replace,编程式导航还是有类似错误
由于this是组件,$router是VueRouter的一个实例,它可以访问到VueRouter原型对象上的push,所以我们通过重写push方法, 就可以解决问题。(上文提到过)
// 以下代码在src/router/index.js文件中
//重写push和replace解决重复点击报错的问题
//先把VueRouter原型对象的push和replace,先保存一份
let originPush = VueRouter.prototype.push
let originReplace = VueRouter.prototype.Replace
//重写push|replace方法
//第一个参数location:告诉原来push方法,往哪里跳转(传递哪种参数)
//第一个参数resolve:成功的回调
//第三个参数reject:失败的回调
VueRouter.prototype.push = function(location,resolve,reject){
if(resolve && reject){
//call||apply:相同点:都可以调用函数一次,都可以篡改函数的上下文一次
//不同点:call与apply传递参数:call传递参数多个参数用逗号隔开,而apply方法执行要传递数组
//调用originPush,把this指向push的调用者
originPush.call(this,location,resolve,reject)
}else{
originPush.call(this,location,()=>{},()=>{})
}
}
//第一个参数:告诉原来replace方法,往哪里跳转(传递哪种参数)
VueRouter.prototype.replace = function(location,resolve,reject){
if(resolve && reject){
originReplace.call(this,location,resolve,reject)
}else{
originReplace.call(this,location,()=>{},()=>{})
}
}