Vue Shangpinhui Mall Project-day02 [15. Visualización dinámica de enlace de menú de tres niveles]

inserte la descripción de la imagen aquí

15. Visualización dinámica de enlace de menú de tres niveles

Pregunta 1:

inserte la descripción de la imagen aquí

código:

<script>
export default {
  name: "TypeNav",
  computed:{
    ...mapState({categoryList:state=>state.home.categoryList})
  }
}
</script>

Análisis de la razón: debido a la falta de importación de mapState, el error mapState no lo sabe, solo agregue la importación

import { mapState } from "vuex";

15.1 Pasos del menú de tres niveles de visualización dinámica de llamadas

Un breve resumen de los pasos a utilizar:

  1. Definir funciones en acciones y mutaciones de submódulos.
  2. Activar la llamada en App.vue
  3. Escriba las propiedades calculadas para que los últimos datos ya estén guardados en el estado
  4. Atravesando el empalme dinámico de los datos más recientes en el código de plantilla para su visualización

Pasos de uso detallados:

  • Paso 1: /store/home/index.js presenta métodos para definir funciones en acciones y mutaciones.
import {getCategoryList} from '@/api'
//Home模块的小仓库
//actions代表一系列动作,可以书写自己的业务逻辑,也可以处理异步
const actions = {
    //getCategoryList返回的是一个Promise对象
    //需要用await接受成功返回的结果,await必须要结合async一起使用(CP)
    async getCategoryList(context) {
        let response = await getCategoryList();
        if (response.code == 200) {
            context.commit("GETCATEGORYLIST", response.data)
        }
    }
}
//mutations代表维护,操作维护的是state中的数据,且state中数据只能在mutations中处理
const mutations = {
    GETCATEGORYLIST(state, categoryList) {
        state.categoryList = categoryList
    }
}
//state代表仓库中的数据
const state = {
    //home仓库中存储三级菜单的数据
    categoryList:[]
}
//getters理解为计算属性,用于简化仓库数据,让组件获取仓库的数据更加方便
const getters = {}

//创建并暴露store
export default {
    actions,
    mutations,
    state,
    getters
}
  • Paso 2: defina la función de gancho montado en App.vue, envíe una acción y obtenga los datos de la lista de tres niveles de clasificación de productos básicos.
mounted() {
    //派发一个action||获取商品分类的三级列表的数据
    this.$store.dispatch("getCategoryList")
  }
  • Paso 3: /components/TypeNav/index.vue, use mapState para generar funciones de cálculo donde se van a usar los datos de estado y luego recorra los datos usados ​​en la plantilla.
<div class="item bo" v-for="(c1,index) in categoryList" :key="c1.categoryId">
    <h3>
        <a href="">{
   
   {c1.categoryName}}</a>
    </h3>
</div>

computed:{
    ...mapState({categoryList:state=>state.home.categoryList})
  }

Pregunta 2: ¿Por qué la función getCategoryList definida por acciones usa async+await?

Respuesta: Debido a que la función getCategoryList finalmente devuelve un objeto de promesa, como se muestra en la figura, y lo que queremos directamente es una función de devolución de llamada exitosa, entonces podemos obtenerla directamente con async+await.

inserte la descripción de la imagen aquí

15.2 Complete el mouse del menú de primer nivel en el color de fondo de la pantalla

El efecto es el siguiente:

inserte la descripción de la imagen aquí

Hay 2 formas:

  • Método 1: css usa directamente: pasar el mouse para agregar color de fondo, punto de conocimiento: el estilo especial agregado por pasar el mouse cuando el mouse se mueve sobre el enlace
//方式1::hover
.item:hover {
 	background: skyblue;
}
  • Método 2: agregue el color de fondo definiendo el evento mouse-in. La idea muestra que cada elemento tiene su propio índice. Inicializamos currentIndex a -1 y modificamos el valor de currentIndex cuando el mouse está adentro. Al juzgar ese currentIndex == índice, será dinámico Vincule el estilo y haga coincidir @mouseenter y @mouseleave al mismo tiempo para lograr el efecto de fondo de deslizamiento hacia adentro y hacia afuera.
<div @mouseleave="leaveIndex" >
<h3 @mouseenter="changeIndex(index)" :class="{cur: currentIndex == index }">

methods: {
    //用于修改组件实例身上的currentIndex的属性值
    //当用户鼠标移入到h3身上的时候就会立即出发一次
    changeIndex(index) {
      this.currentIndex = index;
    },
    //当鼠标离开的时候,让商品分类列表进行隐藏
    leaveIndex() {
      this.currentIndex = -1;
    }
}
  
.cur {
    background: skyblue;
}

注意点1:mouseenter: cuando el mouse se mueve dentro del elemento en sí (sin incluir los elementos secundarios del elemento), el evento se activará y no se superpondrá. El evento de eliminación correspondiente es mouseleave.

注意点2: Ahora quiero lograr un nuevo efecto. El color de fondo no se eliminará cuando el mouse se mueva del primer elemento a "Todas las categorías de productos". La lógica de control es envolver "todas las categorías de productos" y la primera- menú de nivel con un div, y dibuje el control en el exterior.

15.3 Control de visualización y ocultación de las categorías de productos de segundo y tercer nivel

Hay 2 formas:

  • Método 1: controle el bloque | ninguna visualización y oculte la visualización a través de: pasar el mouse sobre css
.item-list {
            display: none;
            ...
}
&:hover {
    .item-list {
        display: block;
    }
}
  • Método 2: controlar la visualización y ocultar la visualización a través de js
 <div class="item-list clearfix" :style="{display: currentIndex == index ? 'block' : 'none'}">

Pregunta: ¿Qué significa &: hover en css?

Respuesta:

Pegue un código CSS para explicar

.box{
		&:before{
			border-color: red;
		}
		&:after{
			border-color: green;
		}
	}

& significa retroceder una capa en la jerarquía anidada, es decir, &:before es equivalente a .box:before

15.4 Demostración del fenómeno de atascamiento, introducción de anti-vibración y estrangulamiento

Normal: el evento se activa con mucha frecuencia, y cada vez que se activa, se debe ejecutar la función de devolución de llamada (si el tiempo es corto y hay un cálculo dentro de la función de devolución de llamada, entonces el navegador puede congelarse), el efecto normal se muestra en Figura 1, y los efectos de error como, 2.

inserte la descripción de la imagen aquí

Figura 1

inserte la descripción de la imagen aquí

Figura 2

Limitación: la devolución de llamada no se activará repetidamente dentro del rango de tiempo de intervalo especificado, y la devolución de llamada solo se activará si el intervalo de tiempo es mayor que este intervalo de tiempo, convirtiendo las activaciones frecuentes en una pequeña cantidad de activaciones [darle al navegador tiempo suficiente para analizar el código].

Anti-vibración: Se cancelan todos los disparos anteriores, y la última ejecución solo se disparará después del tiempo especificado, es decir, si los disparos se disparan de forma continua y rápida, solo se ejecutarán una vez.

Advertencia 0:

安装命令:cnpm install --save lodash

Cómo utilizar:

//引入lodash:是把lodash全部封装好的函数全都引入进来了
//按需引入:只是引入节流函数,其他的函数没有引入(模块),这样做的好处是,当你打包项目的时候体积会小一些
import throttle from "lodash/throttle";

changeIndex: throttle(function(index) {
      //修改当前currentIndex索引值
      //函数节流:在20MS时间之内只能执行一次
      this.currentIndex = index;
    }, 20),

注意点1: Puede usar el complemento lodash: el método comercial anti-vibración y estrangulamiento de la función encapsulada [cierre + retardador]

注意点2: ¿Cuál es la diferencia entre antivibración y estrangulamiento?

Respuesta: "Aceleración" se ejecuta solo una vez dentro del tiempo especificado, y "antivibración" es la última ejecución sin importar cuánto tiempo lleve.

注意点3: sitio web oficial de lodash: https://www.lodashjs.com/

Anti vibración:debounce(func, [wait=0], [options=])

Estrangulamiento:throttle(func, [wait=0], [options=])

15.5 Parámetros de salto y transferencia de Reuters de componentes de enlace de tres niveles

Los usuarios de enlaces de tres niveles pueden hacer clic: clasificación de primer nivel, clasificación de segundo nivel y clasificación de tercer nivel. Al hacer clic, el módulo Inicio saltará al módulo de búsqueda. El primer nivel colocará el producto (nombre del producto, ID) seleccionado por el usuario en el enrutamiento Al saltar, pásalo.

Salto de enrutamiento:

  • Navegación declarativa: enlace de enrutador

  • Navegación programática: empujar|reemplazar

Pregunta 1: ¿Debe elegir "navegación declarativa" o "navegación programática"?

Respuesta: Se debe utilizar la navegación programática. Si usa el enlace de enrutador de navegación declarativa, puede realizar los parámetros de salto y paso de enrutamiento, pero debe prestar atención, habrá un fenómeno de congelación, porque el menú de enlace de tres niveles se genera mediante un recorrido cíclico, si el cíclico el recorrido es 1000 veces, tendrá que generarse recientemente / Las pestañas ocupan mucha memoria y definitivamente se congelarán.

Pregunta 2: dado que se seleccionó "navegación programática", ¿la etiqueta / está vinculada al evento de clic? ¿O utilizar otros métodos?

Respuesta: No puede usar el método de evento de vinculación de etiquetas, debe usar el método de "evento de delegación de elemento principal". Debido a que solo necesita definir la función una vez, pero con la etiqueta a, tengo que recorrer y definir la función 1000 veces.

Pregunta 3: Queremos que el efecto sea hacer clic en la etiqueta para saltar a la ruta ¿Cómo confirmar la etiqueta?

Respuesta: Vincule los atributos personalizados a la etiqueta y use event.target.dataset para obtener el nombre del atributo personalizado. El que puede obtener el nombre del atributo personalizado debe ser la etiqueta que queremos.

Pregunta 4: después de adoptar el método de "evento de delegación del elemento principal", habrá un efecto de error como se muestra en la figura: al hacer clic en el menú de primer nivel -> primero salta a la página de búsqueda -> luego salta automáticamente a la página de inicio página

Respuesta: El atributo href de la etiqueta / debe eliminarse

Pregunta 5: ¿Cuál es el nombre del atributo personalizado denominado data-xxx? Los nombres de los conjuntos de datos de salida e impresos están todos en minúsculas, pero ¿por qué faltan los datos de enfrente? Por ejemplo, el nombre del atributo personalizado es: data-categoryName. ¿Por qué el último nombre obtenido por el conjunto de datos es categoryname, el prefijo obvio data- desapareció e inexplicablemente está en minúsculas?

inserte la descripción de la imagen aquí

Respuesta: Si desea utilizar un conjunto de datos para obtener atributos personalizados en JS, el nombre del atributo personalizado debe ser "data-xxx" en la plantilla HTML.

El siguiente es un extracto del blog de otra persona:

HTML5 ha agregado el método data-* para personalizar los atributos, de hecho, solo agregue el prefijo data- antes del nombre del atributo personalizado y use esta estructura para almacenar datos. El uso de data-* puede resolver la situación actual de atributos personalizados desordenados y no administrados.

Una vez que una costumbre tiene el prefijo data-, este atributo se puede obtener a través de elementNodeObject.dataset en JS, obviamente, el conjunto de datos es un subconjunto de la colección de atributos.
El valor del atributo del conjunto de datos es una instancia de DOMStringMap, que es un mapa de pares de nombre y valor. En este mapeo, cada atributo del formulario data-name tendrá un atributo correspondiente, pero sin el prefijo data-.

Código completo src/components/TypeNav/index.vue

<!--1级联动菜单-->
        <div class="sort">
          <div class="all-sort-list2" @click="goSearch">
            <div class="item bo" v-for="(c1,index) in categoryList" :key="c1.categoryId">
              <h3 @mouseenter="changeIndex(index)" :class="{cur: currentIndex == index }">
                <a :data-categoryName="c1.categoryName" :data-category1Id="c1.categoryId">{
   
   {c1.categoryName}}</a>
              </h3>
              <!--方式2:通过js的方式控制display的显示与隐藏-->
              <div class="item-list clearfix" :style="{display: currentIndex == index ? 'block' : 'none'}">
                <div class="subitem">
                  <!--2级联动菜单-->
                  <dl class="fore" v-for="(c2,index) in c1.categoryChild" :key="c2.categoryId">
                    <dt>
                      <a :data-categoryName="c2.categoryName" :data-category2Id="c2.categoryId">{
   
   {c2.categoryName}}</a>
                    </dt>
                    <dd>
                      <!--3级联动菜单-->
                      <em v-for="(c3,index) in c2.categoryChild" :key="c3.categoryId">
                        <a :data-categoryName="c3.categoryName" :data-category3Id="c3.categoryId">{
   
   {c3.categoryName}}</a>
                      </em>
                    </dd>
                  </dl>
                </div>
              </div>
            </div>
          </div>
        </div>
------------------------------------------------------------------------------------------------------
//进行路由跳转的回调函数
    goSearch(event) {
      //最好的解决方案:编程式导航+事件委派
      //存在一些问题:事件委派,是把全部的子节点【h3、dt、dl、em】的事件委派给父亲节点
      //问题1:点击a标签的时候,才会进行路由跳转【怎么能确认点击的一定是a标签?】
      //答案:给a标签绑定自定义data-categoryName属性,只要能获取到自定义属性就代表是a标签
      //event.target:获取到的是触发事件的元素(div、h3、a、em、dt、dl)
      let element = event.target;
      //节点有一个属性dataset,可以过去节点的自定义属性与属性值
      let {categoryname, category1id, category2id, category3id} = element.dataset;
      //如果标签身上带有categoryname一定是a标签,且当前这个if语句:一定是a标签才会进入
      if (categoryname) {
        //准备路由跳转的参数对象
        let location = {name: 'search'}
        let query = {categoryName: categoryname}
        //一级目录
        if(category1id) {
          query.category1Id = category1id
          //二级目录
        } else if (category2id) {
          query.category2Id = category2id
          //三级目录
        } else {
          query.category3Id = category3id
        }
        //动态给location配置对象添加query属性
        location.query = query;
        //路由跳转
        this.$router.push(location);
      }
    }

Pregunta 6: cuando se inicia el proyecto Vue, se abre http://0.0.0.0:8080 de forma predeterminada y el navegador muestra que no se puede acceder, pero se puede mostrar la página ingresando http://localhost:8080

inserte la descripción de la imagen aquí

Solución: agregue una nueva línea en el archivo vue.config.js: host: 'localhost'.

module.exports = {
  productionSourceMap:false,
  // 关闭ESLINT校验工具
  lintOnSave: false,
  devServer: {
    //代理服务器解决跨域
    proxy: {
      "/api": {
        target: "http://39.98.123.211:8510"
      },
    },
    //解决默认打开浏览器,会出现0.0.0.0:8080,浏览器显示无法访问
    host: 'localhost'
  }
};

Enlaces a mis otros artículos relacionados

1. Proyecto del centro comercial Vue Shangpinhui-día 02 [9. División de componentes del hogar + 10. Interfaz de prueba del cartero]
2. Proyecto del centro comercial Vue Shangpinhui-día 02 [complemento vue-13. Uso de la barra de progreso nprogress]
3. Proyecto del centro comercial Vue Shang Pinhui -day02【11. Empaquetado secundario de axios + 12. Gestión de interfaz unificada】
4. Vue Shangpinhui Mall Project-day02【14.vuex status management library】
5. Vue Shangpinhui Mall Project-day02【 15. Visualización dinámica del menú de tres niveles enlace]

Supongo que te gusta

Origin blog.csdn.net/a924382407/article/details/129893255
Recomendado
Clasificación