• ① 尚品汇的前台开发笔记【尚硅谷】【Vue】


    文章目录

    一、采用vue-cli去初始化项目

    1. 准备这些: node √+ webpack + 淘宝镜像√

    2. 进入到项目文件夹 输入 cmd

      输入 vue create app 去初始化项目

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uff6tmgp-1662169470928)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20220726164002117.png)]

    3. 介绍目录project-SPH/app

      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:说明性文件

    二、项目的其他配置

    1. eslint校验功能关闭

      — 在根目录下,创建一个vue.config.js的文件,加入这行代码lintOnSave:false

      在这里插入图片描述

    2. src文件夹简写方式,配置别名

      jsconfig.json 配置别名 @ 提示 【@代表的时候src文件夹,这样将来文件过多,找的时候方便很多】
      在这里插入图片描述

    三、项目路由的分析

    vue-router

    前端所谓路由:key-value键值对

    key:URL(地址栏中的路径)

    value:相应的路由组件

    注意:该项目是 上中下结构 ---- 跟品优购一样…

    非路由组件:Header,Footer(首页,搜索页)

    路由组件:Home首页路由组件,Search路由组件,login登录路由组件(无Footer),register路由组件(无Footer)

    四、完成非路由组件Header与Footer业务

    开发项目的步骤

    1. 书写静态页面(HTML,CSS)
    2. 拆分组件
    3. 获取服务器的数据动态展示
    4. 完成相应的动态业务逻辑

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

    注意2:咱们项目采用的是less样式,浏览器不识别less样式,需要通过less,less-loader【安装 六 版本的】进行处理less,把less样式变为css样式,浏览器才可以识别npm i less-loader@6

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

    • 创建或定义组件
    • 引入组件
    • 注册组件
    • 使用组件

    在这里插入图片描述

    完成路由组件的搭建

    1. 安装vue-router插件 npm i vue-router@3

      路由组件具体学习–> Vue | 路由

      路由组件有四个:Home,Search,Login,Register(注册)

    • components文件夹:经常放置 非路由组件 (公用全局组件)
    • pages|views文件夹:经常放置 路由组件
    1. 编写router配置项:src/router/index.js
    // 配置路由的地方
    import Vue from 'vue';
    import VueRouter from 'vue-router';
    // 使用插件
    Vue.use(VueRouter);
    
    // 引入路由组件
    import Home from '../pages/Home'
    import Login from '../pages/Login'
    import Register from '../pages/Register'
    import Search from '../pages/Search'
    
    // 配置路由
    export default new VueRouter({
       
        // 配置路由
        routes:[
            {
       
                path:'/home',
                component:Home
            },
            {
       
                path:'/login',
                component:Login
            },{
       
                path:'/segister',
                component:Register
            },{
       
                path:'/search',
                component:Search
            },
        ]
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    1. 引入和注册路由在 src/main.js
      在这里插入图片描述

    2. 使用路由组件 指定展示位置
      在这里插入图片描述

    3. 总结:

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

      1. 路由组件一般放置在pages|views文件夹,非路由组件一般放置在components文件夹中
      2. 路由组件一般需要在router文件夹中进行注册(使用的为组件名字),非路由组件在使用的时候,一般都是以标签的形式使用
      3. 注册完路由,不管是路由组件还是非路由组件,身上都有 $route,$router属性

      $route:一般获取路由信息【路径,query,params等等】

      $router:一般进行编程式导航进行路由跳转【push|replace】

    4. 重定向:在项目跑起来的时候,访问/,立马让他定向到首页 写在 src/router/index.js

            // 重定向:在项目跑起来的时候,访问/,立马让他定向到首页
            {
       
                path:'*',
                redirect:'/home'
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    1. 路由的跳转?

      路由的跳转有两种形式:

      1. 声明式导航router-link
      2. 编程式导航 push| replace

      声明式路由导航可以做的事情 编程式导航都能做,除此之外,编程式导航还能做一些其他的业务

    Footer组件显示与隐藏

    显示或隐藏组件:v-if | v-show

    Footer组件在 Home,Search中是显示的,在登录和注册页面中是隐藏的

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

      在这里插入图片描述
      在这里插入图片描述

    2. 路由元信息

      配置路由的时候,可以给路由添加路由元信息【meta】,路由需要的配置对象不能瞎写胡写
      在这里插入图片描述


      在这里插入图片描述


      在这里插入图片描述

    路由传参

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

      声明式导航:router-link(务必要有to属性)

      编程式导航:利用的是组件实例的$router.push | replace 方法

    2. 路由传参,参数有几种写法?

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

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

      **特别注意:**路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置!params需要去占位!

          // 搜索按钮的回调函数,需要向Search路由进行跳转
          goSearch(){
       
            // 路由传递参数
            this.$router.push({
       
                
              // 第一种:字符串形式
              // path:'/search' + this.keyWord + "?k="+ this.keyWord.toUpperCase(),
                
              // 第二种:模板字符串
              // path:`/search/${this.keyWord}?k=${this.keyWord.toUpperCase()}`
                
              // 第三种:对象写法
              name:'sousuo',
              // params参数
              params:{
       
                keyWord:this.keyWord,
              },
              // query参数
              query:{
       
                k:this.keyWord.toUpperCase()
              }
            })
          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    路由传参相关面试题

    1. 路由传递参数(对象写法) path是否可以结合params参数一起使用?

      不可以。

      路由跳转传参的时候,对象的写法可以是name,path的形式,但需要注意的是,path这种写法不能与params参数一起使用

    2. 如何指定params参数可传可不传?

      在配置路由的时候,给params占位 的后面加上?,代表可传递也可以不传递
      在这里插入图片描述

      比如:配置路由的时候,已经给params参数占位了,但是路由跳转的时候就不传递参数,路径会出现问题

      你跳转的本来是 http://localhost:8081/#/search/k=QWE 这个位置,结果你跳转的是 http://localhost:8081/#/k=QWE 这个位置

    3. params参数可传递也可以不传递,但是如果传递是空串,如何解决?

      传递的是空串的话,路径有问题(和上面路径问题一样)

      使用undefined解决:params参数可传递不可传递的时候,传递是空串路径 有问题的错误

                params:{
           
                  keyWord:'' || undefined,
                },
      
      • 1
      • 2
      • 3
      • 4
    4. 路由组件能不能传递props数据?

      可以的。

      关于路由相关详细笔记---->路由的props配置

      配置props写在 src/router/index.js 里

      第一种写法props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件

      在这里插入图片描述

      第二种写法:值为布尔值,若布尔值为真,就会把该路由组件收到的params参数,以props的形式传给Detail组件 -------缺点:query参数不能用这个


      在这里插入图片描述

      写法三:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
      个人认为这个挺好

      在这里插入图片描述

    解决问题

    :编程式路由跳转到当前路由(参数不变),多次执行会抛出NavigationDuplicated的警告错误?

    ​ 路由跳转有两种形式:声明式导航,编程式导航

    ​ 声明式导航没有这类问题,因为vue-router底层已经处理好了

    1. 为什么编程式导航进行路由跳转的时候,就有这种警告错误?

      “vue-router”: “^3.5.4”:最新的vue-router引入promise,promise有两个形参,成功返回的函数和失败返回的函数

    2. 通过push方法传递相应的成功,失败的回调函数,可以捕获到当前错误,可以解决

    3. 通过底部的代码可以实现解决错误

      this.$router.push({
           
                // 第三种:对象写法
                name:'sousuo',
                // params参数
                params:{
           
                  keyWord:'' || undefined,
                },
                // query参数
                query:{
           
                  k:this.keyWord.toUpperCase()
                }
              },()=>{
           },()=>{
           })
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

      这种写法治标不治本,将来在别的组件当中 push | replace,编程式导航还是有类似错误

    4. 重写push 与 replace 方法

      // src/router/index.js
      
      // 先把VueRouter原型对象的push,先保存一份
      const originalPush = VueRouter.prototype.push
      const originalReplace = VueRouter.prototype.replace
      
      // 重写push | replace
      // 参数:告诉原来的push方法,你往哪里跳转(传递哪些参数)
      VueRouter.prototype.push = function push(location) {
           
        return originalPush.call(this, location).catch(err => err)
      }
      VueRouter.prototype.replace = function replace(location) {
           
        return originalReplace.call(this, location).catch(err => err)
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16

    五、完成Home首页模块业务

    开发项目的步骤

    1. 书写静态页面(HTML,CSS)
    2. 拆分组件
    3. 获取服务器的数据动态展示
    4. 完成相应的动态业务逻辑

    Home拆分为7个组件

    完成Home首页拆分静态组件

    完成TypeNav 三级联动组件–全局组件

    三级联动Home,Search,Detail组件都在使用,可以把它注册为全局组件

    好处:只需要注册一次,就可以在项目任意地方使用

    • 创建组件
      在这里插入图片描述

    • 引入组件,注册组件
      在这里插入图片描述

    • 使用组件

    完成其余静态组件–局部组件

    • 创建组件

      导入结构 样式 查看图片位置有无错误进行修改

    • 引入组件

    • 注册组件

    • 使用组件
      在这里插入图片描述

    POSTMAN测试接口是否正常

    我用的是Vscode插件【 Postcode】

    在这里插入图片描述

    刚刚经过测试,接口没有问题

    ​ 如果服务器返回的数据code是200,代表服务器返回数据成功

    ​ 整个项目,接口前缀都有/api

    最新接口地址:

    http://gmall-h5-api.atguigu.cn

    后台文档swagger地址:
    http://39.98.123.211:8510/swagger-ui.html#/

    首页三级联动的请求地址是: /api/product/getBaseCategoryList

    请求方式是 GET

    axios二次封装

    向服务器发请求的方式有:XMLHttpRequest,fetch,JQ,axios

    这里用axios

    1. :为什么需要二次封装axios

      因为要用到 请求和响应拦截器。

      请求拦截器:可以在发请求之前处理一些业务

      响应拦截器:当服务器数据返回以后,可以处理一些事情

    在终端里安装axiosnpm i axios

    1. 在项目当中经常会出现 api 文件夹,一般是放关于【axios】请求的

      baseURL:'/api',:基础路径,发请求的时候,路径当中会出现基础api

      timeout:5000,: 代表请求超时的时间5s,在5s之内没有响应就失败了

    2. axios基础不好,可以参考 git | axios 文档

    // src/api/request.js
    
    // 对于axios进行二次封装
    import axios from 'axios';
    
    // 1. 利用axios对象的方法create,去创建一个axios实例
    // 2. request就是axios,只不过稍微配置一下
    const requests = axios.create({
       
        // 配置对象
        // 基础路径,发请求的时候,路径当中会出现基础api
        baseURL:'/api',
        // 代表请求超时的时间5s,在5s之内没有响应就失败了
        timeout:5000,
    });
    
    // 请求拦截器:在发请求之前,请求拦截器可以检测到,可以在请求发出去之前做一些事情
    requests.interceptors.request.use((config)=>{
       
        // config:配置对象,对象立马有一个属性很重要,headers请求头
        return config;
    })
    
    // 响应拦截器
    requests.interceptors.response.use((res)=>{
       
        // 成功的回调函数:服务器相应数据回来以后,相应拦截器可以检测到,可以做一些事情
        return res.data;
    },(error)=>{
       
        // 服务器响应失败的回调函数
        return Promise.reject(new Error('failed'))
    })
    
    // 对外暴露
    export default requests;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    接口统一管理

    项目很小:完全可以在组件的生命周期函数中发请求

    项目大,有很多接口:axios.get(‘xxx’)

    // src/api/index.js
    
    // 当前这个模块:api进行统一管理
    import requests from "./request";
    
    // 三级联动接口
    // /api/product/getBaseCategoryList   GET  无参数
    
    export const reqCategoryList = ()=>{
         // 要请求数据的时候直接调用reqCategoryList这个函数就可以了
        // 发请求:axios发请求返回结果是Promise对象
       return requests({
       url:'/product/getBaseCategoryList',method:'GET',})
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 跨域问题

      什么是跨域:协议,域名,端口号不同的请求,称之为跨域

      从这里http://localhost:8081/#/home ----前端项目本地服务器

      向这里发请求 http://gmall-h5-api.atguigu.cn ---- 后台服务器

    2. 跨域的解决方案:JSONP,CROS,数据代理

      // Vue.config.js 
      
      const {
            defineConfig } = require('@vue/cli-service')
      module.exports = defineConfig({
           
        transpileDependencies: true,
        // 关闭eslint
        lintOnSave: false,
        // 代理跨域
        devServer: {
           
          proxy: {
           
            '/api': {
           // 匹配所有以 '/api'开头的请求路径
              target: 'http://gmall-h5-api.atguigu.cn',// 获取数据的目标地址
              changeOrigin: true,
            },
          }
        }
      })
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22

    具体跨域看这里—>解决开发环境Ajax跨域问题

    nprogress进度条的使用

    安装nprogress插件 npm i nprogress

    只要项目当中发请求,进度条就开始往前动,服务器数据返回之后,进度条就结束

    用在 请求和响应拦截器 src/api/request.js

    nprogress.start方法:进度条开始

    nprogress.done方法:进度条结束
    在这里插入图片描述

    vuex状态管理库

    1. vuex是什么?

      vuex是官方提供的一个插件,状态管理库,集中式管理项目中组件共用的数据。

      切记,并不是全部项目都需要vuex

      如果项目很小,完全不需要vuex

      如果项目很大,组件很多,数据很多,数据维护很费劲,需要vuex

    安装vuex npm i vuex@3

    1. vuex基本使用

      看这个 -->Vue | vuex【理解 vuex + vuex开发者工具的使用 + vuex的基本使用和API + 四个map方法的使用+多组件共享数据 +模块化+命名空间 】_不爱吃菜的蔡菜的博客-CSDN博客

    在这里插入图片描述

    1. vuex实现模块化开发

      如果项目过大,组件过多,接口也很多,数据也很多,可以让vuex实现模块化开发

      1. 创建模块化开发的小仓库,每一个组件都可以有一个小仓库

        在这里插入图片描述

      2. 引入小仓库

        在这里插入图片描述

      3. 在入口文件引入总仓库并注册

        注册仓库,组件实例的身上会多一个$store属性

    完成TypeNav三级联动

    完成TypeNav三级联动展示数据业务

    当TypeNav挂载完毕就开始请求数据然后展示数据

    这里模块化记得给每个组件开启命名空间!!!namespace:true

    在这里插入图片描述

    让TypeNav组件挂载,挂载的时候通知vuex发请求,将数据存储于 home仓库中,用dispatch,于是要书写actions

    actions执行的时候,要通过api里面的接口函数调用,向服务器发请求,获取服务器的数据

    ​ 需要把之前的api引入进来,在这里发请求就是要调用这个reqCategoryList函数

    发请求后返回的是一个promise函数,当里面的code是200,代表成功,我们要修改仓库里面的数据

    我们要解构commit,提交给mutations

    result.data是一个数组形式

    mutations里面开始更改数据

    传入的参数是state是数据,categoryList这个参数就是服务器返回的result.data

    仓库当中应该有个起始值,于是让state中的数据类型为服务器返回的数据类型

    在这里插入图片描述

    result 数据是
    在这里插入图片描述

    这个时候home仓库已经有了相应的数组,但是我们需要在TypeNav组件中拿到数据并进行展示

    进入到TypeNav组件当中,用mapState去获取组件中的数据

    • TypeNav组件获取数据

      在这里插入图片描述

    • 获得数据,然后渲染到页面上

    对页面的三级联动进行分析

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    完成一级分类动态添加背景颜色

    1. 采用样式完成

      .item:hover{
           
      	background:skyblue;
      }
      
      • 1
      • 2
      • 3
      • 4
    2. 通过JS完成

      给一级分类添加鼠标经过和鼠标离开事件

                <div
                  class="item"
                  v-for="(c1, index) in categoryList"
                  :key="c1.categoryId"
                  :class="{ cur: currentIndex == index }"
                >
                
                  <h3 @mouseenter="changeIndex(index)" @mouseleave="leaveIndex">
                    <a href="">{
          { c1.categoryName }}a>
                  h3>
                    ....
      		  div>
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      先设置一个响应式属性,存储用户鼠标移上哪一个一级分类currentIndex = -1 ;代表鼠标谁都没有移上去

      然后鼠标进入和移出 修改响应式数据currentIndex属性

      当data中的currentIndex==该item中的index时添加cur属性

        data() {
           
          return {
           
            // 响应式属性,存储用户鼠标移上哪一个一级分类
            currentIndex: -1, // 代表鼠标谁都没有移上去
          };
        },
        methods: {
           
          // 鼠标进入修改响应式数据currentIndex属性
          changeIndex(index) {
           
            // index 鼠标移上某一个一级分类的元素的索引值
            this.currentIndex = index;
          },
          // 一级分类鼠标移出的事件回调
          leaveIndex(){
           
            // 鼠标移出currentIndex=-1
            this.currentIndex =-1;
          }
        },
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23

    通过JS控制二三级商品分类的显示与隐藏

    1. 通过CSS样式display:block|none;来控制二三级商品分类的显示与隐藏

    2. 通过JS控制二三级商品分类的显示与隐藏

                  
             
      .....
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    函数的防抖和节流

    正常:事件触发的非常频繁,而且每一次的触发,回调函数都要去执行(如果时间很短,而函数内部有计算,那么很可能出现浏览器卡顿)

    节流:在规定的时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发

    防抖:前面的所有的触发都被取消,最后一次执行在规定的事件之后才会触发,也就是说如果连续的快速触发,只会执行一次 ----------------------当事件被触发后,延迟 n 秒后再执行回调

    具体看这个笔记---->防抖和节流

    lodash插件:里面封装函数的防抖与节流的业务【闭包+延迟期】

    npm i lodash

    1. lodash函数库对外暴露的是 _函数-----------比如:JQ暴露的是$函数

    2. lodash.debounce | Lodash 中文文档 | Lodash 中文网 (lodashjs.com)防抖函数

    3. lodash.throttle | Lodash 中文文档 | Lodash 中文网 (lodashjs.com)节流函数

    完成三级联动节流的操作

    鼠标来回滑动的时候,把频繁触发变成少量触发,进行节流

    // 这种引入的方式,是把lodash全部功能函数引入
    import _ from 'lodash';
    // 最好的引入方式:按需加载
    import {
       throttle} from 'lodash/throttle'
    ...
    
        // 鼠标进入修改响应式数据currentIndex属性
        changeIndex:throttle(function(index){
       
          // index 鼠标移上某一个一级分类的元素的索引值
           this.currentIndex = index;
        },50),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这里的throttle回调函数别用箭头函数,可能出现上下文this问题

    完成三级联动组件的路由跳转与传递参数

    • 当你点击分类的时候,会从home模块跳转到search模块,并且把分类的名字categoryName和ID传递给search模块

    • 然后search模块拿到这些参数向服务器发请求展示相应数据

    路由跳转:

    声明式导航 :router-llink

    编程式导航 :push | replace

    最好的解决方案:编程式导航+事件委派

    利用事件委派存在一些问题:

      1. 你怎么知道点击的是a标签 
           1. 事件委派,是把全部的子节点【h3,dt,dl,em】的事件委派给父亲节点
           2. 点击a标签的时候,才会进行路由跳转
    
    • 1
    • 2
    • 3
    1. 如何获取参数【1,2,3级分类的产品的名字和ID】

    给a标签加上自定义属性:data-categoryName="c3.categoryName",如果有这个自定义属性就是a标签

    利用event.target获取事件对象的子节点

        goSearch(event){
       
          // 最好的解决方案:编程式导航+事件委派
          // 利用事件委派存在一些问题:1. 你怎么知道点击的是a标签 2. 如何获取参数【1,2,3级分类的产品的名字和ID】
          console.log(event.target);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    注意:这里的自定义属性时全小写的,我加上的是驼峰写法!

    节点有一个属性dataset属性,它可以获取节点的自定义属性与属性值

        goSearch(event){
       
          // 最好的解决方案:编程式导航+事件委派
          // 利用事件委派存在一些问题:1. 你怎么知道点击的是a标签 2. 如何获取参数【1,2,3级分类的产品的名字和ID】
          let element = event.target;
          console.log(element.dataset);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

        goSearch(event){
       
          // 最好的解决方案:编程式导航+事件委派
          // 利用事件委派存在一些问题:1. 你怎么知道点击的是a标签 2. 如何获取参数【1,2,3级分类的产品的名字和ID】
          let element = event.target;
          console.log(element.dataset); // 返回的是一个对象
          // 解构对象
          let {
       categoryname} = element.dataset;
          // 如果标签身上有categoryname属性,一定是a标签
          if(categoryname){
       
            alert(123)
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 上面已经知道了点击的是否是a标签

    • 下面解决怎么知道是一级分类还是二级分类的a标签

    和上面一样,给a标签添加自定义属性:data-category1Id="c1.categoryId"

    另外路由要进行跳转和传参,我们这里选择编程式导航携带query参数

    1. 首先location 是要跳转的路由是哪里,携带什么参数,这里携带参数是根据一级分类二级分类来看的,所以先不写携带的query参数,光写上跳转的路由组件name
    2. query参数另定义,根据解构 element.dataset对象来获得a标签的分类ID,根据if语句来判断他在哪一级分类,如果是第一级分类,就在query参数里面添加一级分类的ID…
    3. 最后整理参数,让location里面有query,然后实现路由的跳转
        goSearch(event) {
       
          // 最好的解决方案:编程式导航+事件委派
          // 利用事件委派存在一些问题:1. 你怎么知道点击的是a标签 2. 如何获取参数【1,2,3级分类的产品的名字和ID】
          let element = event.target;
          console.log(element.dataset); // 返回的是一个对象
          // 解构对象
          let {
        categoryname, category1id, category2id, category3id } =
            element.dataset;
          // 如果标签身上有categoryname属性,一定是a标签
          if (categoryname) {
       
            // 整理路由跳转的参数
            let location = {
        name: "sousuo"};
            let query = {
       categoryName:categoryname}; 
            // 怎么知道一级分类还是二级分类的a标签
            if (category1id) {
       
              query.category1Id = category1id;
            } else if (category2id) {
       
              query.category2Id = category2id;
            } else if (category3id) {
       
              query.category3Id = category3id;
            }
            // 整理完参数,现在location和query是两个参数
            location.query = query;
            // 实现路由的跳转
            this.$router.push(location);
          }
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    Search模块中商品分类的显示与隐藏

    1. 开发search模块中的TypeNav商品分类菜单(过渡动画)

      • 用一个响应式属性来控制 从Home进入到Search的时候 显示与隐藏
        在这里插入图片描述
        在这里插入图片描述

    当从Home进入到Search的时候,TypeNav会再一次挂载,所以当进入的时候,让自定义属性show变成false

    判断当前路由是不是search

      mounted() {
       
        // 通知Vuex发请求,获取数据,存储于仓库当中,当前三级联动在home组件当中!!!
        this.$store.dispatch("home/categoryList");
        // 当组件挂载完毕,让show的属性变为false
        // 如果不是home路由组件,将TypeNav进行隐藏
        if(this.$route.path !== '/home'){
       
          this.show = false;
        }
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 显示隐藏效果:当鼠标移进移出的时候

    这里用到事件委派

    在这里插入图片描述

    当鼠标移入的时候,让商品分类列表进行展示,让 this.show = true;

    鼠标移出的时候,隐藏,让this.show = false;

    注意!如果在首页的话就不用隐藏了
    在这里插入图片描述

    • 过渡动画效果-------->http://t.csdn.cn/On1U6

    过渡动画:前提是 组件 | 元素 必须要有 v-if | v-show指令才可以进行过渡动画

    加上过渡动画,需要用transition包裹,取名字为sort

    在这里插入图片描述

    在CSS样式里书写过渡动画 -------注意:动画样式和.sort是同一级别的

        // 过渡动画的样式
        // 过渡动画开始状态(进入)
        .sort-enter,.sort-leave-to{
       
          height: 0;
        }
        .sort-enter-to,.sort-leave{
       
          height
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    云计算:掌控未来,一触即发!
    mac 下载使用sshpass+命令起别名
    模拟警车发声
    Unity DOTS技术(八)状态组件
    《逆向工程核心原理》学习笔记(五):64位 & Windows 内核6
    Oracle LiveLabs实验:Configure network environment for Oracle Database 21c
    用Java写PTA7-10 InputMismatchException异常
    你的游戏项目有这些问题吗?
    C语言--每日五道练习题--Day13
    计算机组成原理(六)
  • 原文地址:https://blog.csdn.net/muziqwyk/article/details/126673908