vue项目实战尚品汇前台01

概述

技术架构:vue + webpack+vuex + vue-router+ axios+less…

  • 封装通用组件
  • 登录注册
  • token
  • 守卫
  • 购物车
  • 支付
  • 项目性能优化

vue-cli 初始化项目

安装的版本是vue2

D:\ranan\vue>vue create project
# 选择vue2
  • node_modules文件夹:项目依赖文件
  • public文件夹:放置静态资源(图片),webpack打包时会原封不动打包到dist文件夹中,不会当成模块打包到JS文件中
  • src文件夹:源码文件
    • assets文件夹:放置多个组件共用的静态资源,wepack打包时会当作模块,打包到JS文件中
    • components文件夹:非路由组件或者全局组件
    • pages|views文件夹: 放置路由组件
    • App.vue 根组件
    • main.js 程序的入口组件
  • babel.config.js:babel配置文件
  • package.json文件:项目管理文件

项目的其他配置

  1. 项目运行的时候,让浏览器自动打开
    package.json 里修改
"scripts": {
    "serve": "vue-cli-service serve --open"
    //....
}

报错
打开是http://0.0.0.0:8080/?原因是为了让别人的电脑在同一个网络下访问自己的项目,设置了host:‘0.0.0.0’
解决办法1:https://blog.csdn.net/Xl4277/article/details/109378795
解决办法2:https://blog.csdn.net/qq_43757586/article/details/124032757

  1. 关闭eslint
    在根目录下创建vue.config.js新增如下代码
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  //....
  lintOnSave:true,
})
  1. 配置src文件夹别名@,方便书写
    根目录下创建jsconfig.json文件配置@别名,我的脚手架已经配置好了
{
  "compilerOptions": {
   	//......
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
   //...
  }
}

项目路由分析vue-router

前端的路由:kv键值对
key:URL
value:响应的路由组件
在这里插入图片描述
头部Head.vue和底部Footer.vue可以设计成非路由组件
中间展示的区域设计成路由组件 (具体有哪些?编写边分析,因为我感觉这里没图不好说,应该有一个设计图的?)

重置默认样式

最好每个项目开始前都清除默认样式

1.复制reset.css到public中
2.在index.html中引入reset.css

 <link rel="stylesheet" href="<%= BASE_URL %>reset.css">

Header.vue和Footer.vue组件 静态页面

1.静态界面抽离

说明
1.浏览器不识别less样式,需要安装less,less-loader6版本

这里的依赖需要安装在开发依赖里,仅开发的时候使用
1.devDependencies开发环境依赖,安装时使用 --save-dev
2.dependencies生产环境依赖(开发环境能使用),安装时使用 --save

D:\ranan\vue\vue_project>cnpm install --save-dev less less-loader@6

2.style标签里添加lang属性

<style scoped lang="less">

2.在根组件中使用Header组件
1.引入组件
2.注册组件
3.使用组件

<template>
<div>
<!--3.使用组件-->
  <MyHeader />
  <MyFooter/>
</div>
</template>

<script type='text/ecamscript-6'>
//1.引入组件
import MyHeader from './components/Header'
//....
export default {
name:'App',
components:{ //2.注册组件
      MyHeader ,
//....
    }
}
</script>

结果展示
在这里插入图片描述

路由组件搭建

1.安装vue-router3版本

D:\ranan\vue\vue_project>cnpm install --save vue-router@3

2.配置路由 - src/router/index.js文件夹中

vue-router 是插件,需要先引入vue-router,再使用vue-router

import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);

3.配置路由

路由的跳转有两种形式
声明式导航router-link(需要有to属性),可以进行路由的跳转
编程式导航利用组件实例的$router.push/replace,可以进行路由跳转

//引入路由组件
import Home from '@/pages/Home'
//....
//配置路由
export default new VueRouter({
    rountes:[
        {
            path:"/home",
            name:'Home',
            component:Home
        },
      //......
     	{	
            path:"/",
            redirect:Home,//使用route的name
		}
    ]
})

4.vm上注册路由,修改main.js文件

注册路由后,所有组件(包括非路由组件)身上有$route和$router属性
$route:每个路由的信息,如路径、query、params等
$router:路由器信息,一般进行编程式导航进行路由跳转[push|repalce]

//引入路由
import router from '@/router'
new Vue({
  render: h => h(App),
  router //注册路由
}).$mount('#app')

5.在App.vue中展示

<div>
  <MyHeader/>
  <!--路由组件出口的地方-->
  <router-view></router-view> 
  <MyFooter/>
</div>

6.修改静态页面中的某些链接为声明式导航<router-link>

会被解析成a标签,点击a标签实现跳转。
如果使用button实现的跳转功能此时就不再适用了,可以使用编程式导航实现

<button type="button" @click="goSearch">搜索</button>

//vue
methods:{
   goSearch(){
       //搜索按钮的回调函数:需要向search路由进行跳转
       this.$router.push("/search")
   }    
}   
Footer组件的显示和隐藏 路由元信息的使用

Footer组件:在Home,Search显示Footer组件
Footer组件:在登录、注册时隐藏Footer组件

显示或者隐藏: v-if | v- show
切换频繁所以我们使用v-show

路由的meta属性是给程序员添加一些路由信息的,通过$router.meta获取

//router/index.js
{
      path:"/login",
      component:Login,
      meta: {
          isHideFooter: true
      },
},
Search时将搜索内容传递给路由

先在search路由使用占位

  {
       path:"/search/:keyword",
       component:Search,
       //....
}

路由的传参

goSearch(){
        //路由的传参
        //方式1:字符串形式/模板字符串,小写是params参数,后面的大写是query
       this.$router.push("/search/" + this.keyword +"?k=" + this.keyword.toUpperCase());
       //方式2:对象的形式
       this.$router.push({
		name:'search',//路由记得命名
		params:{keyword:this.keyword},
		query:{keyword:this.keyword.toUpperCase()}
		})
}       

Home组件业务拆分

拆分成7个组件

TypeNav.vue 三级联动组件

在这里插入图片描述
TypeNav.vue组件在Home、Search、Detail都使用了,注册成全局组件
好处:只需要注册一次就可以在项目的任意地方使用

注册全局组件

在main.js中注册

//三级联动组件--全局组件 1.引入
import TypeNav  from '@/pages/Home/TypeNav'

//2.注册为全局组件 第一个参数:全局组件的名字,该组件的name需要设置  第二个参数:哪一个组件
Vue.component(TypeNav.name,TypeNav)

//3.不需要在使用的组件中再注册,直接使用
 <TypeNav></TypeNav>

知识点总结

1.路由跳转有几种方式?

路由的跳转有两种形式
声明式导航router-link(需要有to属性),可以进行路由的跳转
编程式导航利用组件实例的$router.push/replace,可以进行路由跳转

<router-link>会被解析成a标签,点击a标签实现跳转。
如果使用button实现的跳转功能此时就不再适用了,可以使用编程式导航实现

2.vue路由query参数和params参数的区别

区别params传参query传参
传参的写法必须使用命名路由(路由的name属性)的方式既可以使用路由的name属性也可以使用path属性
是否显示在地址栏不会显示在地址栏上,会保存在内存中,刷新会丢失,在配置路由的时候,需要用词来占位,接收路径对应的部分会显示在地址栏上,不会丢失
举例/router1/:id 设置在路由上,成为路由的一部分,刷新页面时就params不会丢失/home? k1=v1 &k2=v2

补充:路由的其他属性
注册路由后,所有组件(包括非路由组件)身上有$route和$router属性**
$route:每个路由的信息,如路径、query、params等
$router:路由器信息,一般进行编程式导航进行路由跳转push|repalce

路由的meta属性是给程序员添加一些路由信息的,通过$router.meta获取

2.1 如何指定params参数可传可不传

比如:配置路由的时候,占位了(params参数),但是路由跳转的时候不传递。
路径会出现问题,搜QWE时:http://localhost:8080/#/?k=QWE根本没有跳转到search http://localhost:8080/#/rsearch

配置路由占位时,设置可选?

{
     path:"/search/:keyword?",
     component:Search,
     name:'search',
     meta: {
         isShowFooter: true
        },
},
2.2 params参数可传可不传,如果传递的params参数是空串怎么办?

此时路径有问题:localhost:8080/#/?k=xx

使用undefinde解决params参数可传可不传时,params是空串的问题

this.$router.push({
	name:'search',//路由记得命名
	params:{keyword:""||undefined},
	query:{keyword:this.keyword.toUpperCase()}
})
2.3 路由组件能不能传递props数据?

组件的props配置:用来接受组件外部传来的参数
路由的props配置:用于给该组件进行传参

  • 写法1:值为对象,该对象中的所有key-value都会以props的形式传给该组件。
  • 写法2:值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给该组件。
  • 写法3,值为函数,返回值为对象,对象中的每一对key-value都会传给组件的props,params和query都可以。(三种写法之中常用,但总体不常用)

3.编程式路由跳转的NavigationDuplicated报错 - 面试时项目遇见的困难

编程式路由重复点击(参数不变),多次执行会怕抛出NavigationDuplicated的警告错误
在这里插入图片描述
为什么会出现这种原因?
因为vue-router引入promise,push返回promise,多次点击错误没有捕获,所以报错

function push(){
	return new Promise((resolve,reject)=>{})
}

解决办法
1.调用 $router.push时,再传两个参数,成功的回调函数,失败的回调函数

    this.$router.push({
		name:'search',//路由记得命名
		params:{keyword:this.keyword},
		query:{keyword:this.keyword.toUpperCase()}
		},()=>{},()=>{})

2.重写VueRouter原型上的push方法
①先保存VueRouter原型上的push方法
②重写push|repalce

let origiPush = VueRouter.prototype.push
VueRouter.prototype.push = function(location,resolve=()=>{},reject=()=>{}){
return origiPush.call(this,location,resolve,reject)
}

vue-router4.0 解决了这个问题

Logo

前往低代码交流专区

更多推荐