Day1

Vue前台项目

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

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

Vue后台项目

技术架构:vue+webpack+vuex+vue-router-axios-scss+elmentUI

  • elementUI
  • 菜单权限
  • 按钮权限
  • 数据可视化

2、项目开始

创建一个文件夹

利用cmd加载vue create +名称

D:\项目\project-hph>vue create app

  vue create is a Vue CLI 3 only command and you are using Vue CLI 2.9.6.
  You may want to run the following to upgrade to Vue CLI 3:

  npm uninstall -g vue-cli
  npm install -g @vue/cli

出现这个先卸载,再重新安装

node_modules文件夹放置的是项目的依赖
public文件夹放置的是静态资源(图片),webpack进行打包的时候,会原封不动的打包到dist文件夹
src源代码文件夹:
	assets文件夹:一般放置的也是静态资源(多个组件公用的静态资源),需要注意的是,放置在assets文件夹里面的静态资源,在webpack打包的时候,会将静态资源当作一个模块,打包到JS文件里面。
	component:非路由组件,全局组件。
	app.vue :根组件
	main.js : 程序的入口文件
	babel.config.js 配置文件,es6翻译到es5
	package.json 记录项目叫什么,项目依赖,怎么运行
	package-lock.json 
	
	
	
	结构层<template>
	样式层<style>
	行为层<script>

2.1 项目运行时,浏览器自动打开。

--package.json

  "scripts": {
    "serve": "vue-cli-service serve --open",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
在vue.config.json中添加下面代码,就不会出现0.0.0.8080了
devServer: { host: 'localhost', port: 8080, }

2.2 eslint校验功能关闭

vue.config.js

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave:false/*关闭校验功能*/
})

2.3 src文件夹简写方法,配置别名@

创建 js.config.json文件

{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "baseUrl": "./",
    "moduleResolution": "node",
    "paths": {
      "@/*": [
        "src/*"       @代表的是src文件夹  
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "exclude": [
    "node_modules",       //在这两个文件夹中是不能使用的
    "dist"
  ]
}

3、项目路由的分析

前端路由:KV键值对

key:URL地址栏中的路径

value:相应的路由组件

路由组件:home首页路由组件,search路由组件,login登陆路由,Register注册路由

非路由组件:header footer【首页和搜索页】

4、完成非路由组件header与footer业务

业务逻辑

1、书写静态页面,HTML和css

2、拆分组件

3、获取服务器数据的动态数据

4、完成相应的动态的业务逻辑

注意:1、创建组件的时候,组件结构,组件的样式,图片资源

2、项目采用less样式,浏览器不识别less样式,需要通过less,less-loader进行处理less,把less变成css样式。安装依赖。

D:\项目\project-hph\app>cnpm install --save less less-loader@5

3、如果想让组件识别less样式,需要在style标签身上加上 lang=“less”

<template>
  <header class="header">
    <!-- 头部的第一行 -->
    <div class="top">
      <div class="container">
        <div class="loginList">
          <p>尚品汇欢迎您!</p>
          <p>
            <span>请</span>
            <a href="#">登录</a>
            <a href="#" class="register">免费注册</a>
          </p>
        </div>
        <div class="typeList">
          <a href="#">我的订单</a>
          <a href="#">我的购物车</a>
          <a href="#">我的尚品汇</a>
          <a href="#">尚品汇会员</a>
          <a href="#">企业采购</a>
          <a href="#">关注尚品汇</a>
          <a href="#">合作招商</a>
          <a href="#">商家后台</a>
        </div>
      </div>
    </div>
    <!--头部第二行 搜索区域-->
    <div class="bottom">
      <h1 class="logoArea">
        <a class="logo" title="尚品汇" href="#" target="_blank">
          <img src="./images/logo.png" alt="">
        </a>
      </h1>
      <div class="searchArea">
        <form action="###" class="searchForm">
          <input type="text" id="autocomplete" class="input-error input-xxlarge" />
          <button class="sui-btn btn-xlarge btn-danger" type="button">搜索</button>
        </form>
      </div>
    </div>
  </header>
</template>

<script>
export default {
  name: "index"
}
</script>

<style scoped lang="less">
.header {
  &>.top {
    background-color: #eaeaea;
    height: 30px;
    line-height: 30px;

    .container {
      width: 1200px;
      margin: 0 auto;
      overflow: hidden;

      .loginList {
        float: left;

        p {
          float: left;
          margin-right: 10px;

          .register {
            border-left: 1px solid #b3aeae;
            padding: 0 5px;
            margin-left: 5px;
          }
        }
      }

      .typeList {
        float: right;

        a {
          padding: 0 10px;

          &+a {
            border-left: 1px solid #b3aeae;
          }
        }

      }

    }
  }

  &>.bottom {
    width: 1200px;
    margin: 0 auto;
    overflow: hidden;

    .logoArea {
      float: left;

      .logo {
        img {
          width: 175px;
          margin: 25px 45px;
        }
      }
    }

    .searchArea {
      float: right;
      margin-top: 35px;

      .searchForm {
        overflow: hidden;

        input {
          box-sizing: border-box;
          width: 490px;
          height: 32px;
          padding: 0px 4px;
          border: 2px solid #ea4a36;
          float: left;

          &:focus {
            outline: none;
          }
        }

        button {
          height: 32px;
          width: 68px;
          background-color: #ea4a36;
          border: none;
          color: #fff;
          float: left;
          cursor: pointer;

          &:focus {
            outline: none;
          }
        }
      }
    }
  }
}
</style>

4.1 使用组件的步骤(非路由组件)

-创建或者定义:components文件夹—>Header文件夹—>index.vue-上面的代码

-引入:在App.vue中引入

-注册

<script>
//引入头部组件,之后注册
import Header from './components/Header'
//在export default中注册
export default {
  name: 'App',
  components: {
    Header
  }
}
</script>

-使用

<template>
  <div>
      <Header></Header>
  </div>
</template>
<script>
//引入头部组件,之后注册
import Header from './components/Header'
//在export default中注册
export default {
  name: 'App',
  components: {
    Header
  }
}
</script>
<style>
</style>

在静态资源public中的index.html中引入清除默认样式reser.css,reser.css放置在public中

<!--引入清除默认的样式-->
      <link rel="stylesheet" href="./reset.css">

4.2 footer

1、在footer文件夹中创建index.vue

<template>
  <!-- 底部 -->
  <div class="footer">
    <div class="footer-container">
      <div class="footerList">
        <div class="footerItem">
          <h4>购物指南</h4>
          <ul class="footerItemCon">
            <li>购物流程</li>
            <li>会员介绍</li>
            <li>生活旅行/团购</li>
            <li>常见问题</li>
            <li>购物指南</li>
          </ul>

        </div>
        <div class="footerItem">
          <h4>配送方式</h4>
          <ul class="footerItemCon">
            <li>上门自提</li>
            <li>211限时达</li>
            <li>配送服务查询</li>
            <li>配送费收取标准</li>
            <li>海外配送</li>
          </ul>
        </div>
        <div class="footerItem">
          <h4>支付方式</h4>
          <ul class="footerItemCon">
            <li>货到付款</li>
            <li>在线支付</li>
            <li>分期付款</li>
            <li>邮局汇款</li>
            <li>公司转账</li>
          </ul>
        </div>
        <div class="footerItem">
          <h4>售后服务</h4>
          <ul class="footerItemCon">
            <li>售后政策</li>
            <li>价格保护</li>
            <li>退款说明</li>
            <li>返修/退换货</li>
            <li>取消订单</li>
          </ul>
        </div>
        <div class="footerItem">
          <h4>特色服务</h4>
          <ul class="footerItemCon">
            <li>夺宝岛</li>
            <li>DIY装机</li>
            <li>延保服务</li>
            <li>尚品汇E卡</li>
            <li>尚品汇通信</li>
          </ul>
        </div>
        <div class="footerItem">
          <h4>帮助中心</h4>
          <img src="./images/wx_cz.jpg">
        </div>
      </div>
      <div class="copyright">
        <ul class="helpLink">
          <li>关于我们
            <span class="space"></span>
          </li>
          <li>联系我们
            <span class="space"></span>
          </li>
          <li>关于我们
            <span class="space"></span>
          </li>
          <li>商家入驻
            <span class="space"></span>
          </li>
          <li>营销中心
            <span class="space"></span>
          </li>
          <li>友情链接
            <span class="space"></span>
          </li>
          <li>关于我们
            <span class="space"></span>
          </li>
          <li>营销中心
            <span class="space"></span>
          </li>
          <li>友情链接
            <span class="space"></span>
          </li>
          <li>关于我们</li>
        </ul>
        <p>地址:北京市昌平区宏福科技园综合楼6层</p>
        <p>京ICP备19006430号</p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Footer"
}
</script>

<style scoped>

</style>

2、在根组件App.vue中引入Footer组件

<template>
  <div>
        <Header></Header>
        <Footer></Footer>
  </div>
</template>
<script>
//引入头部组件,之后注册
import Header from './components/Header'
import Footer from './components/Footer'

//在export default中注册
export default {
  name: 'App',
  components: {
    Header,
    Footer
  }
}
</script>

3、引入footer的样式,在index.vue中

<template>
  <!-- 底部 -->
  <div class="footer">
    <div class="footer-container">
      <div class="footerList">
        <div class="footerItem">
          <h4>购物指南</h4>
          <ul class="footerItemCon">
            <li>购物流程</li>
            <li>会员介绍</li>
            <li>生活旅行/团购</li>
            <li>常见问题</li>
            <li>购物指南</li>
          </ul>

        </div>
        <div class="footerItem">
          <h4>配送方式</h4>
          <ul class="footerItemCon">
            <li>上门自提</li>
            <li>211限时达</li>
            <li>配送服务查询</li>
            <li>配送费收取标准</li>
            <li>海外配送</li>
          </ul>
        </div>
        <div class="footerItem">
          <h4>支付方式</h4>
          <ul class="footerItemCon">
            <li>货到付款</li>
            <li>在线支付</li>
            <li>分期付款</li>
            <li>邮局汇款</li>
            <li>公司转账</li>
          </ul>
        </div>
        <div class="footerItem">
          <h4>售后服务</h4>
          <ul class="footerItemCon">
            <li>售后政策</li>
            <li>价格保护</li>
            <li>退款说明</li>
            <li>返修/退换货</li>
            <li>取消订单</li>
          </ul>
        </div>
        <div class="footerItem">
          <h4>特色服务</h4>
          <ul class="footerItemCon">
            <li>夺宝岛</li>
            <li>DIY装机</li>
            <li>延保服务</li>
            <li>尚品汇E卡</li>
            <li>尚品汇通信</li>
          </ul>
        </div>
        <div class="footerItem">
          <h4>帮助中心</h4>
          <img src="./images/wx_cz.jpg">
        </div>
      </div>
      <div class="copyright">
        <ul class="helpLink">
          <li>关于我们
            <span class="space"></span>
          </li>
          <li>联系我们
            <span class="space"></span>
          </li>
          <li>关于我们
            <span class="space"></span>
          </li>
          <li>商家入驻
            <span class="space"></span>
          </li>
          <li>营销中心
            <span class="space"></span>
          </li>
          <li>友情链接
            <span class="space"></span>
          </li>
          <li>关于我们
            <span class="space"></span>
          </li>
          <li>营销中心
            <span class="space"></span>
          </li>
          <li>友情链接
            <span class="space"></span>
          </li>
          <li>关于我们</li>
        </ul>
        <p>地址:北京市昌平区宏福科技园综合楼6层</p>
        <p>京ICP备19006430号</p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Footer"
}
</script>

<style scoped lang="less">
.footer {
  background-color: #eaeaea;

  .footer-container {
    width: 1200px;
    margin: 0 auto;
    padding: 0 15px;

    .footerList {
      padding: 20px;
      border-bottom: 1px solid #e4e1e1;
      border-top: 1px solid #e4e1e1;
      overflow: hidden;
      padding-left: 40px;

      .footerItem {
        width: 16.6666667%;
        float: left;

        h4 {
          font-size: 14px;
        }

        .footerItemCon {
          li {
            line-height: 18px;
          }
        }

        &:last-child img {
          width: 121px;
        }
      }
    }

    .copyright {
      padding: 20px;

      .helpLink {
        text-align: center;

        li {
          display: inline;

          .space {
            border-left: 1px solid #666;
            width: 1px;
            height: 13px;
            background: #666;
            margin: 8px 10px;
          }
        }
      }

      p {
        margin: 10px 0;
        text-align: center;
      }
    }
  }
}
</style>

5、路由组件的搭建 vue-router

在上面分析的时候,路由组件应该有四个:Home、Search、Login、Register

--components文件夹:经常放置的非路由组件(公用全局组件)

--pages|views文件夹:经常放置路由组件,在src中创建pages文件夹。在pages文件夹中创建Home、Search、Login、Register文件夹,在其中分别创建index.vue文件

5.1 配置路由 cnpm install --save vue-router

项目当中配置的路由一般放置在router文件夹中,在src中创建router文件夹。在router中创建index.js

import Vue from 'Vue';
import VueRouter from 'vue-router'


//使用插件
Vue.use(VueRouter);

//引入路由组件
import Home from '@/pages/Home'
import Search from '@/pages/Search'
import Login from '@/pages/Login'
import Register from '@/pages/Search'

//配置路由,对外暴露
export default new VueRouter({
    //配置路由
    routes:[
        {
          path:'/home',
          component:Home
        },
        {
            path:'/search',
            component:Search
        },
        {
            path:'/login',
            component:Login
        },
        {
            path:'/register',
            component:Register
        },
      //重定向:在项目跑起来的时候,访问 / 的时候,立马让它定向到首页
        {
            path:'*',
            redirect:'/home'
        }
    ]
})
//之后回到入口文件,main.js中去注册,引入路由

在main.js中引入路由

import Vue from 'vue'
import App from './App.vue'
//引入路由
import  router from '@/router'
Vue.config.productionTip = false

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

vue-router版本高的解决方法
(1):卸载原有的Vue_router,并重新下载“^3.5.2”,卸载和按照的两种命令如下。
卸载原有路由:npm uninstall vue-router
安装3.0版本:npm i vue-router@3.5.2
(2):在命名后添加--legacy-peer-deps即可绕过peerDependency自动安装,保证各个引入的依赖之间对自身所使用的不同版本modules共存。
npm i vue-router@3.5.2 -legacy-peer-deps

在App.vue中写路由组件出口的地方

<template>
  <div>
        <Header></Header>
    
          <!--路由组件出口的地方-->
          <router-view></router-view>
    
        <Footer></Footer>
  </div>
</template>

<script>
//引入头部组件,之后注册
import Header from './components/Header'
import Footer from './components/Footer';

//在export default中注册
export default {
  name: 'App',
  components: {
    Header,
    Footer
  }
}
</script>

<style>

</style>

5.2 总结

路由组件和非路由组件的区别?

  • 路由组件一般放置在pages|views文件夹中,非路由组件放置在components文件夹中
  • 路由组件一般需要在router文件夹中的index.js进行注册(使用的即为组件的名字),非路由组件在使用的时候,一般都是以标签的形式使用
  • 注册完路由,不管路由组件还是非路由组件身上都有$route、$router属性
  • 在index.js中重定向
  • //重定向:在项目跑起来的时候,访问 / 的时候,立马让它定向到首页
            {
                path:'*',
                redirect:'/home'
            }
    
  • $route:一般获取路由信息【路径、query、params】
    $router:一般进行编程式导航,进行路由跳转【push|replace】
    

5.3 路由的跳转

路由的跳转有两种形式:

  • 声明式导航router-link,可以进行路由的跳转
  • 编程式导航push|replace,进行路由的跳转(编程式导航可以做声明式导航的功能,还可以做一些其他的业务逻辑)

在component中的Header的index.vue

<div class="loginList">
          <p>尚品汇欢迎您!</p>
          <p>
            <span>请</span>
            <!--声明式导航:务必要有to属性-->
            <router-link to="/login">登录</router-link>|
            <router-link class="register" to="/register">免费注册</router-link>
          </p>
 </div>

<div class="searchArea">
        <form action="#" class="searchForm">
          <input type="text" id="autocomplete" class="input-error input-xxlarge" />
          <button class="sui-btn btn-xlarge btn-danger" type="button" @click="goSearch">搜索</button>
        </form>
 </div>

<script>
export default {
  name: "Header",
  methods:{
    //搜索按钮的回调函数:需要向search进行跳转
    goSearch(){
      this.$router.push('/search')
    }
  }
}
</script>

6、footer组件的显示与隐藏

显示和隐藏组件:v-if v-show

footer:在home、search显示footer组件

footer组件:在登录和注册时隐藏

<!--在Home、Search 显示,在登录、注册隐藏。-->
        <Footer v-show="$route.path=='/home'||$route.path=='/search'"></Footer>

面试题:v-show与v-if区别?
v-show:通过样式display控制
v-if:通过元素上树与下树进行操作
面试题:开发项目的时候,优化手段有哪些?
1:v-show|v-if
2:按需加载

6.1 我们可以根据组件身上的$route获取当前的路由信息,通过路由路径判断Footer显示与隐藏

在router中的index.js 的配置路由中 添加路由元信息

meta:{show:true }

//配置路由的地方

//引入vue和vueRouter
import Vue from 'vue';
import VueRouter from 'vue-router';

//使用插件
Vue.use(VueRouter);

//引入路由组件
import Home from '@/pages/Home/index'
import Search from '@/pages/Search'
import Login from '@/pages/Login'
import Register from '@/pages/Register'

//配置路由,对外暴露
export default new VueRouter({
    //配置路由
    //在配置路由中添加meta:{show:true|false}
    routes:[
        {
          path:'/home',
          component:Home,
            meta:{
              show:true
            }
        },
        {
            path:'/search',
            component:Search,
            meta:{
                show:true
            }
        },
        {
            path:'/login',
            component:Login,
            meta:{
                show:false
            }
        },
        {
            path:'/register',
            component:Register,
            meta:{
                show:false
            }
        },
        //重定向:在项目跑起来的时候,访问 / 的时候,立马让它定向到首页
        {
            path:'*',
            redirect:'/home'
        }
    ]
})
//之后回到入口文件,main.js中去注册,引入路由

在App.vue中配置footer

<Footer v-show="$route.meta.show"></Footer>
meta:路由元信息
根据当前路由的信息:route.meta.show
进行判断:show的值为true还是false

6.2 配置路由的时候可以添加路由元信息meta

7、路由传参

7.1 路由跳转的方式

  • 声明式导航:router-link(务必要有to属性),可以实现路由的跳转
  • <router-link to="#"></router-link>
    
  • 编程式导航:利用的是组件实例的 $route.push|replace 方法
  • 编程式导航更好用:因为可以书写自己的业务逻辑

7.2 路由传参,参数有几种写法

params参数:属于路径当中的一部分,在配置的路由的时候需要占位

query参数:不属于路径当中的一部分,类似于AJAX中的queryString /home?k=v&kv= 不需要占位

7.2.1 路由传递参数-字符串形式

1、在Header.vue中,先获取表单数据,也就是搜索框里面输入的值。

<script>
export default {
  name: "Header",
  //获取表单数据
  data(){
    return{
      keyword:''
    }
  },
  methods:{
    //搜索按钮的回调函数:需要向search进行跳转
    goSearch(){
      this.$router.push('/search')
    }
  }
}
</script>

2、收集文本框里面的值

  <!--收集文本框的数据,v-model="keyword" 双向数据绑定-->
  <input type="text" id="autocomplete" class="input-error input-xxlarge"  v-model="keyword"/>

3、在index.js 中配置路由

routes[
  {
     path:'/search/:keyword',       占位
            component:Search,
            meta:{
                show:true
            }
  }
]

4、传递搜索框里面的函数到search中

<script>
export default {
  name: "Header",
  //获取表单数据
  data(){
    return{
      keyword:''
    }
  },
  methods:{
    //搜索按钮的回调函数:需要向search进行跳转
    goSearch(){
      //路由传递参数:
      //第一种:字符串形式
      this.$router.push('/search/'+this.keyword+"?k="+this.keyword.toUpperCase());
      //
    }
  }
}
</script>

$route
path:"/search/abc"
query:Object
k:"ABC"
params:Object
keyword:"abc"
fullPath:"/search/abc?k=ABC"

在search中展示出来

7.2.2 模板字符串

 //第二种:模板字符串
      //this.$router.push('/search/${this.keyword}?k=${this.keyword.toUpperCase}')

7.2.3 **(常用的形式)对象的写法

先在配置路由中给Search路由取个名字

{
            path:'/search/:keyword',
            component:Search,
            meta:{
                show:true
            },
            name:"search"
        },

 methods:{
    //搜索按钮的回调函数:需要向search进行跳转
    goSearch(){
      //路由传递参数:
      //第一种:字符串形式
      //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()}})
    }
  }

8、路由相关的面试题

 1:路由传递参数(对象写法)path是否可以结合params参数一起使用?
 this.$router.push({path:"/search",params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}})
 答:路由传参的时候,对象的写法可以是name、path形式,但是需要注意的是,path和params不能一起用。
 
 2:如何指定params参数可传可不传? 
 答:配置路由的时候,占位了(params参数),但是路由跳转的时候就不传递。
 路径会出现问题:localhost:8080/#/?k=QWE
 							localhost:8080/#/search?k=QWE
 							
 如何指定params参数可传可不传,在配置路由的时候,在占位的后面加上一个问号?
 this.$router.push({name:"search",query:{k:this.keyword.toUpperCase()}})
 path:'/search/:keyword?'
 
 3:params参数可以传递也可以不传递,但是如果传递是空串,如何解决?
 this.$router.push({name:"search",params:{keyword:''},query:{k:this.keyword.toUpperCase()}})
 
 使用undefined解决:params参数可以传递,可以不传递(空的字符串)
 this.$router.push({name:"search",params:{keyword:''||undefined},query:{k:this.keyword.toUpperCase()}})
 
 4: 路由组件能不能传递props数据? 可以的:三种写法
   1、布尔值写法:在路由配置中
        {
            path:'/search/:keyword',
            component:Search,
            meta:{
                show:true
            },
            name:"search",
            //路由组件能不能传递props数据
            //布尔值写法
            props:true
        },
        在搜索的index.vue中
 <script>
	export default {
  name: "Search"
  props:['keyword']
}
</script>

  //对象写法:额外的给路由组件传递一些props
            //props:{a:1,b:2}
            
            
            
            
     //函数写法:可以把params参数、query参数,通过props传递给路由组件
            props:($route)=>{
                return{keyword:$route.params.keyword(),k:$route.query.k};
            }       
posted @ 2022-09-27 16:34  孤舟蓑衣客  阅读(24)  评论(0)    收藏  举报