Vue learning --- basado en componentes en vue2, comunicación de componentes, ref.

Vue learning - basado en componentes en vue2

Este artículo se basa en vue2.x el entorno de desarrollo.

1. Componentes

1.1 Registrar componentes

Un archivo .vue creado en la carpeta de componentes, en la carpeta src, en la carpeta del proyecto, es un componente. Se utiliza en el script del componente y representa la instancia del componente actual.

registro parcial

Primero importe el componente a través del nombre del componente de importación desde 'ruta del componente'; registre el componente con componentes en exportación predeterminada

Código de muestra:

Escribir en el archivo App.vue

<template>
  <!-- 一个.vue文件就是一个组件, 一个项目中只有一个根组件 App.vue -->
  <!-- 一个.vue文件内部一般是由三部分组成: template , script , style -->
  <!-- template 内部写标签 , 只能有一个根元素 -->
  <!-- script 内部写js逻辑 , 内部需要 export default {}, 所有的js代码都需要写在这里 -->
  <!-- style 内部写css样式 , 可以通过lang='xx'指定style内部的css语法 , 可以通过设置 scoped 属性 让多个.vue文件之间的样式互不影响 -->
  <div id="app">
    <!-- 搜索框 -->
    <Search></Search>

    <!-- 轮播图 -->
    <Swiper></Swiper>

    <!-- 列表 -->
    <List></List>

    <!-- Tabbar -->
    <Tabbar></Tabbar>

  </div>
</template>

<script>
//导入组件
import Search from './components/Search.vue'
import Swiper from './components/Swiper.vue'
import List from './components/List.vue'
import Tabbar from './components/Tabbar.vue'

export default {
  components:{ //负责注册组件( 局部组件 , 只能在当前注册的文件中使用 )
    // Search,
    Swiper,
    List,
    Tabbar
  }
}
</script>

<style lang="scss">
// 这里不加scoped , 因为 这里一般写全局样式
*{
  margin: 0;
  padding: 0;
}
</style>

registro mundial

Todavía importe el componente primero, luego registre el componente a través de vue.component ('nombre del componente', nombre del componente de importación)

Código de muestra:

en el archivo main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

// 导入Search组件
import Search from './components/Search.vue'
// 注册组件(全局组件,可以在所有的.vue文件中使用)
Vue.component('Search', Search);

//实例化Vue对象
new Vue({
    
    
  render: h => h(App),
}).$mount('#app')

Uso de componentes

Uso de componentes (pueden ser componentes globales o componentes locales)

Usado en el archivo App.vue: <nombre del componente/> o <nombre del componente> <nombre del componente/>

1.2 Importación y exportación de módulos (un módulo es un archivo js)

Cree un archivo utils debajo de la carpeta src debajo de la carpeta del proyecto para colocar el archivo js creado

El primer tipo: exportación predeterminada

Exportar: exporte el nombre de la variable predeterminada para exportar

Importar: importar el nombre de la variable exportada desde 'ruta'

Código de muestra:

El archivo js recién creado se exporta:

//定义函数
function add(a,b){
    
    
    return a+b;
}

//默认抛出(导出)
export default add;

Importación del archivo main.js:

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false
// 默认导入 可以给默认导入的数据改名
// 默认导出和默认导入 配合使用
import abc from './utils/a'
console.log( abc(10,20) );

//实例化Vue对象
new Vue({
    
    
  render: h => h(App),
}).$mount('#app')

El segundo tipo: exportación con nombre

Exportar: exportar {nombre de variable 1, nombre de variable 2,...}

Importar: importar { nombre de variable 1, nombre de variable 2, ... } desde 'ruta'

Código de muestra:

exportación de archivos js:

function sub(a,b){
    
    
    return a-b;
}
function mul(a,b){
    
    
    return a*b;
}

//命名导出
export {
    
    
    sub,
    mul
};

importación de archivos main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

// 命名导入
// 命名导入导出是对应的配合使用的,命名变量名字要相同

// {sub,mul}解构赋值,解析出你想要导入的文件
// 命名导入,必须以{}的形式导入解构时不能改名字要和导出中的名字一样
import {
    
    sub,mul} from './utils/b';

console.log(sub(10,20),mul(10,20));

console.log(abc(10,20));

//实例化Vue对象
new Vue({
    
    
  render: h => h(App),
}).$mount('#app')

1.3 Ganchos de ciclo de vida de componentes

Los enlaces de ciclo de vida son métodos definidos que se ejecutan en una determinada etapa del ciclo de vida de una instancia de componente de Vue. Un objeto de instancia sigue diferentes etapas de vida desde la inicialización hasta que se destruye. Este es un diagrama muy conocido que representa el orden en que se ejecutan las funciones de enlace.

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

  • beforeCreate: después de inicializar la instancia y antes de que se complete la creación , se llama al observador de datos (observador de datos) y a la configuración de evento/evento del observador antes
  • created: se llama inmediatamente después de que se crea la instancia . En este paso, la instancia ha completado las siguientes configuraciones: observador de datos, operación de atributos y métodos, devolución de llamada de evento/ver evento. Sin embargo, la fase de montaje aún no ha comenzado y la propiedad $el no está visible actualmente.
  • beforeMount: se llama antes de que comience el montaje: la función de representación correspondiente se llama por primera vez.
  • montado: este enlace se llama después de que el se reemplaza por el recién creado vm.$ely se monta en la instancia. Si la instancia raíz monta un elemento en el documento, vm.$eltambién está en el documento cuando se llama al montaje.
  • beforeUpdate: se llama cuando se actualizan los datos, antes de que se parchee el DOM virtual. Esto es adecuado para acceder al DOM existente antes de actualizar, como eliminar manualmente el detector de eventos agregado.
  • actualizado: este enlace se llamará después de que el DOM virtual se vuelva a renderizar y parchear debido a cambios en los datos.
  • beforeDestroy: se llama antes de que se destruya la instancia. En este paso, la instancia aún está completamente disponible.
  • destruido: cuál se llama después de que se destruye la instancia de Vue. Después de llamar, todo lo indicado por la instancia de vue se desvinculará, se eliminarán todos los detectores de eventos y se destruirán todas las instancias secundarias.

Aviso:

  1. Las funciones anteriores son todas funciones periódicas del componente y se llamarán automáticamente en un momento específico durante la vida útil del componente.
  2. El método en el período de creación de instancias solo se ejecutará para esta parte
  3. El método en el período de montaje solo se ejecutará una vez; para lo cual los componentes deben ejecutarse antes de que se complete el montaje y solo se pueden ejecutar una vez, el código se puede escribir en la función montada, donde se pueden enviar las solicitudes ajax, se pueden configurar los temporizadores. creado, y el monitoreo de eventos se puede hacer.
  4. Los dos métodos en el período de actualización se ejecutarán repetidamente a medida que se actualice el componente.
  5. El período de destrucción solo se ejecutará una vez; si se realizan operaciones como el envío de solicitudes ajax, la creación de temporizadores y la supervisión de eventos (salida de la barra de desplazamiento, eventos de teclado, eventos de clic vinculante) y otras operaciones en la función de ciclo de vida montada, estas operaciones ocupan la memoria de la computadora, y en el componente Si la memoria no se libera a tiempo antes de la destrucción, causará una pérdida de memoria.
  6. $destroy(): El método de destrucción del componente.La destrucción del componente no significa necesariamente que el componente desaparezca, sino que el componente no se puede utilizar.

Código de muestra:

Archivo App.vue

<template>
  <!-- 一个.vue文件就是一个组件, 一个项目中只有一个根组件 App.vue -->
  <!-- 一个.vue文件内部一般是由三部分组成: template , script , style -->
  <!-- template 内部写标签 , 只能有一个根元素 -->
  <!-- script 内部写js逻辑 , 内部需要 export default {}, 所有的js代码都需要写在这里 -->
  <!-- style 内部写css样式 , 可以通过lang='xx'指定style内部的css语法 , 可以通过设置 scoped 属性 让多个.vue文件之间的样式互不影响 -->
  <div id="app">
    <h1>count:{
   
   {count}}</h1>
    <button @click="$destroy()">销毁当前组件</button>
  </div>
</template>

<script>
export default {
  data(){
    return {
      count:0,
      timerid:null
    }
  },
  computed:{

  },
  // 以下这些函数都是 组件的生命周期函数,它们在组件生命过程中会在特定时刻自动调用。

  // 实例化期,这里的方法只会执行一次
  beforeCreate(){
    console.log('组件-创建(实例化)前');
  },
  created(){
    console.log('组件-创建(实例化)完成');
  },
  // 挂载期,这里的方法只会执行一次
  beforeMount(){
    console.log('组件-挂载前');
  },
  mounted(){
    // 对于哪些在组件挂载完成前 必须执行而且只能执行一次的代码可以写在这里
    console.log('组件-挂载完成');
    // 在这里可以发送ajax请求,创建定时器,事件监听
    this.timerid = setInterval(()=>{
      this.count++;
    },1000)
  },

  // 更新期,这里的两个方法会随着组件更新  反复执行
  beforeUpdate(){
    console.log('组件-更新前');
  },
  updated(){
    console.log('组件-更新完成');
  },

  // 销毁期,只会执行一次
  beforeDestroy(){

    console.log('组件-销毁前');
    // 如果在 mounted 生命周期函数中做了  发送ajax请求,创建定时器,事件监听 等操作,这些操作会占用计算机内存,在组件销毁前如果没有及时释放这些内存,就会导致内存泄漏。
    clearInterval(this.timerid);
  },
  destroyed(){
    console.log('组件-销毁完成');
  }
}
</script>

<style lang="scss" scoped>

</style>

2. Comunicación de componentes

La llamada comunicación de componentes, es decir, la transferencia de datos entre componentes, incluye dos aspectos:

Ø Transferencia de datos entre componentes padre e hijo con relación anidada;

Ø Transferencia de datos entre componentes hermanos;

En concreto se puede dividir en:

  • Pasar valor del componente principal al componente secundario
  • Pasar valor del componente secundario al componente principal
  • Valor de aprobación del componente de nivel cruzado
  • Pasar valores entre componentes hermanos

2.1 Los componentes principales pasan valores a los componentes secundarios

Cuando los datos existen en el componente principal, los datos del componente principal deben pasarse al componente secundario

El componente principal pasa el valor a través del atributo personalizado en el componente secundario, y el componente secundario recibe el valor a través de accesorios dentro

componente padre:

<div id="app">
    <div class="tabs">
      <!-- App.vue与渲染的组件之间是父子关系 -->
      <!-- 所有数据都存在于父组件中,需要将父组件中的数据传到子组件中进行渲染 -->

      <!-- 父组件向子组件传值:父组件在子组件身上通过自定义属性传值,子组件内部通过props接收值 -->
      <!-- 子组件向父组件传值:父组件提前在子组件身上绑定自定义事件,子组件内部通过$emit触发 -->

      <!-- 渲染左侧分类 -->
      <TabLeft :tabs="tabs" ></TabLeft>

      <!-- 渲染右侧分类 -->
      <TabRight ></TabRight>
    </div>
  </div>


export default {
    
    
    data() {
    
    
        return {
    
    
            // 用来保存当前点击的分类下标
            currentIndex: 0,
            tabs: [
                {
    
    
                    tabName: "三文鱼",
                    list: [
                        {
    
     pic: pic1, name: "三文鱼", price: 45 },
                        {
    
     pic: pic1, name: "高级三文鱼", price: 55 },
                        {
    
     pic: pic1, name: "vip三文鱼", price: 65 },
                    ]
                },
                {
    
    
                    tabName: "刺身",
                    list: [
                        {
    
     pic: pic2, name: "刺身", price: 45 },
                        {
    
     pic: pic2, name: "高级刺身", price: 55 },
                        {
    
     pic: pic2, name: "vip刺身", price: 65 },
                    ]
                },
                {
    
    
                    tabName: "大虾",
                    list: [
                        {
    
     pic: pic3, name: "大虾", price: 45 },
                        {
    
     pic: pic3, name: "高级大虾", price: 55 },
                        {
    
     pic: pic3, name: "vip大虾", price: 65 },
                    ]
                },
            ]
        };
    },
    components: {
    
     
      TabRight,
      TabLeft,
     }

Subensamblaje:

export default {
    // 通过props接收从父组件传来的值,该值是只读的(不能修改)
    // props:['tabs','currentIndex']//数组形式
    props:{//对象形式,可以对传来的数据进行类型验证
        tabs:{type:Array, default:[]},
    }
}

2.2 Los subcomponentes pasan valores a los componentes principales

El componente principal vincula eventos personalizados en el componente secundario por adelantado, y el componente secundario se activa internamente a través de $emit

on subscribe, emit publica, on y emit están en el prototipo de Vue, y se puede llamar a cada instancia.

componente padre:

<div id="app">
    <div class="tabs">
      <!-- App.vue与渲染的组件之间是父子关系 -->
      <!-- 所有数据都存在于父组件中,需要将父组件中的数据传到子组件中进行渲染 -->

      <!-- 父组件向子组件传值:父组件在子组件身上通过自定义属性传值,子组件内部通过props接收值 -->
      <!-- 子组件向父组件传值:父组件提前在子组件身上绑定自定义事件,子组件内部通过$emit触发 -->

      <!-- 渲染左侧分类 -->
      <!-- <TabLeft :tabs="tabs" :currentIndex="currentIndex" @deliverIndex="changelist" ></TabLeft> -->
      <TabLeft :tabs="tabs" :currentIndex="currentIndex" @deliverIndex="changelist" ></TabLeft>

      <!-- 渲染右侧分类 -->
      <TabRight :tabs="tabs" :currentIndex="currentIndex"></TabRight>
    </div>
  </div>
  
 export default {
    data() {
        return {
            // 用来保存当前点击的分类下标
            currentIndex: 0,
            tabs: [
                {
                    tabName: "三文鱼",
                    list: [
                        { pic: pic1, name: "三文鱼", price: 45 },
                        { pic: pic1, name: "高级三文鱼", price: 55 },
                        { pic: pic1, name: "vip三文鱼", price: 65 },
                    ]
                },
                {
                    tabName: "刺身",
                    list: [
                        { pic: pic2, name: "刺身", price: 45 },
                        { pic: pic2, name: "高级刺身", price: 55 },
                        { pic: pic2, name: "vip刺身", price: 65 },
                    ]
                },
                {
                    tabName: "大虾",
                    list: [
                        { pic: pic3, name: "大虾", price: 45 },
                        { pic: pic3, name: "高级大虾", price: 55 },
                        { pic: pic3, name: "vip大虾", price: 65 },
                    ]
                },
            ]
        };
    },
    components: { 
      TabRight,
      TabLeft,
     },
     methods:{
    changelist(index){
      this.currentIndex = index;
    }
  }
  
  

Subensamblaje:

 <div class="tab" :class="{active:currentIndex ==index}" @click="$emit('deliverIndex',index)" v-for="(item,index) in tabs" :key="index">{
    
    {
    
    item.tabName}}</div>
<div class="tabright">
    <!-- 渲染多个商品(列表) -->
    <div class="good" v-for="(item,index) in tabs[currentIndex].list" :key="index">
        <div class="imgbox">
            <img :src="item.pic" alt="">
        </div>
        <div class="text">
        <div class="name">{
    
    {
    
    item.name}}</div>
        <div class="price">{
    
    {
    
    item.price}}</div>
    </div>
    </div>
  </div>

**Nota: **El nombre del evento pasado en emit debe estar en minúsculas

2.3 Comunicación entre componentes hermanos

Necesita usar un bus de eventos público (canalización de comunicación) donde un componente vincula el evento por adelantado y el otro componente hermano activa el evento y pasa el valor

Cree una instancia vacía, por ejemplo: vm = new Vue({}); como puente de comunicación;

Use vm.$on() para escuchar eventos personalizados en componentes que necesitan recibir datos (generalmente procesados ​​en la función montada) y procese los parámetros pasados ​​en la función de devolución de llamada (tenga en cuenta este procesamiento en la función de devolución de llamada);

Use vm.$emit() para desencadenar eventos personalizados en componentes que necesitan pasar valores y pasar datos;

Instancia una instancia vacía de Vue:

var vm = new Vue({});

paso:

1. Primero cree una carpeta utils en src, cree un archivo tools.js en esta carpeta, cree una instancia de Vue vacía en este archivo y exporte

import Vue from 'vue'

// 实例化Vue 并导出
export default new Vue()

2. Use vm.$on() para escuchar eventos personalizados en componentes que necesitan recibir datos (generalmente procesados ​​en la función montada)

<div class="list">
        <!-- 渲染多个商品(列表) -->
        <div class="good" v-for="(item,index) in tabs[currentIndex].list" :key="index">
            <div class="imgbox">
            <img :src="item.pic" alt="">
            </div>
            <div class="text">
            <div class="name">{
   
   {item.name}}</div>
            <div class="price">¥{
   
   {item.price}}</div>
            </div>
        </div>
    </div>
    
    import eventbus from '../utils/tools'

export default {
    // 通过props接收从父组件传来的值,该值是只读的(不能修改)
    data(){
        return {
            currentIndex:0
        }
    },
    props:['tabs'],
    mounted(){
        // 绑定事件
        eventbus.$on('deliverIndex',(index=>{
            this.currentIndex = index; //保存接收到的值
        }))
    }
}

3. Use vm.$emit() para activar eventos personalizados en componentes que necesitan pasar valores y pasar datos;

No es necesario pasar un valor para desencadenar un evento, es posible solo desencadenar este evento

Hermano componente a:

<div class="tabbox">
        <!-- 渲染多个分类按钮 -->
        <div class="tab" :class="{active: currentIndex==index }" @click="handleClick(index)" v-for="(item,index) in tabs" :key="index">{
   
   {item.tabName}}</div>
    </div>
    
    // 导入空实例
import eventbus from '../utils/tools'

export default {
    // 通过props接收从父组件传来的值,该值是只读的(不能修改)
    // props:['tabs','currentIndex'] //数组形式
    data(){
        return {
            currentIndex:0
        }
    },
    props:{//对象形式,可以对传来的数据进行类型验证
        tabs:{type:Array,default:[]}
    },
    methods:{
        handleClick(index){
            eventbus.$emit('deliverIndex',index);//触发事件并传值
            this.currentIndex = index;
        }
    }
}

2.4 Pasar valores entre componentes

Los componentes externos pasan valores a través de provide y los componentes internos reciben valores a través de inject.

Ejemplo:

Pase el valor del componente externo al componente Child1, luego pase el valor al componente Child2 a través del componente Child1 y luego pase el valor al componente Child3 a través del componente Child2

Código de muestra:

Archivo App.vue

<template>
  <!-- 一个.vue文件就是一个组件, 一个项目中只有一个根组件 App.vue -->
  <!-- 一个.vue文件内部一般是由三部分组成: template , script , style -->
  <!-- template 内部写标签 , 只能有一个根元素 -->
  <!-- script 内部写js逻辑 , 内部需要 export default {}, 所有的js代码都需要写在这里 -->
  <!-- style 内部写css样式 , 可以通过lang='xx'指定style内部的css语法 , 可以通过设置 scoped 属性 让多个.vue文件之间的样式互不影响 -->
  <div id="app">
    <Child1></Child1>
  </div>
</template>

<script>
import Child1 from './components/Child1.vue';

export default {
  components:{
    Child1
  },
  // 跨组件传值:外层组件通过provide传值,内层组件通过inject接收值
  provide(){//负责传值给内层组件
    return {
      money:8888,
      list:[1,2,3]
    }

  }
}
</script>

<style lang="scss" scoped>

</style>

Archivo Child1.vue

<template>
  <div class="child1">
    <h1>我是子组件1 - {
   
   {money}}</h1>
    <Child2/>
  </div>
</template>

<script>
import Child2 from './Child2.vue'
export default {
    components:{
        Child2
    },
    inject:['money']
}
</script>

<style>

</style>

Archivo Child2.vue

<template>
    <div class="child2">
      <h1>我是子组件2 - {
   
   {money}}</h1>
      <Child3 />
    </div>
  </template>
  
  <script>
  import Child3 from './Child3.vue'
  
  export default {
      components:{
          Child3
      },
      inject:['money']
  }
  </script>
  
  <style>
  
  </style>

Child3.vue documentos

<template>
    <div class="child3">
      <h1>我是子组件3 - {
   
   {money}} - {
   
   {list}} </h1>
    </div>
  </template>
  
  <script>
  export default {
      //inject 接收从外层组件传来的值
      inject:['money','list']
  }
  </script>
  
  <style>
  
  </style>

3.ref

Obtenga el nodo dom:

Establezca la ID (alias) para la etiqueta a través del atributo ref y obtenga el nodo dom correspondiente a la ID a través de this.$refs.xx en el código js

ref se aplica al componente

Obtenga la instancia del componente correspondiente al identificador a través de this.$refs.xx en el código js

Código de muestra:

<template>
  <div id="app">
    <!-- 通过ref属性给标签设置标识( 别名 ) -->
    <!-- 在js代码中 通过 this.$refs.xx 获取标识对应的dom节点 -->
    <input type="text" ref="phone">
    <h1 ref="title">学习ref</h1>

    <!-- ref应用在组件身上 -->
    <!-- 在js代码中 通过 this.$refs.xx 获取标识对应的组件实例 -->
    <Child ref="ch" />
    
  </div>
</template>

<script>
import Child from './components/Child.vue'

export default {
  components:{
    Child
  },
  mounted(){
    console.log( this.$refs.phone );
    console.log( this.$refs.title );
    console.log( this.$refs.ch );

    //调用子组件的add,sub方法
    this.$refs.ch.add();
    this.$refs.ch.sub();
  }
}
</script>

<style lang="scss" scoped>

</style>

Ejemplos de referencias

componente del carrito de compras

<template>
 <div class="shopcart" v-show="visible" @click="changeVisible">
        <!-- @click.事件修饰符 -->
        <!-- @click.stop 阻止事件冒泡 -->
        <!-- @click.ctrl 只有同时按下ctrl键并点击才会触发 -->
        <!-- @click.right 只有按下鼠标右键才会触发 -->
        <!-- @click.native 给子组件绑定原生事件,只有添加active修饰符才会触发 -->
        <div class="content" @click.stop="handleClick">
            <div class="title">
                <span>已选商品</span>
                <span @click="clean">清空</span>
            </div>
            
            <div v-if="list.length != 0" class="list">
                <div v-for="(item,index) in list" :key="index" class="good">
                    <div class="imgbox">
                        <img :src="item.pic" alt="">
                    </div>
                    <div class="text">
                        <div class="name">{
   
   {item.name}}</div>
                        <div class="price">
                            <div>¥{
   
   {item.price}}</div>
                            <div>
                                <span @click="sub(item)">-</span>
                                <span>{
   
   {item.count}}</span>
                                <span @click="add(item)">+</span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div v-else class="empty" >购物车空空如也,去逛逛!</div>
        </div>
    </div>  
</template>

<script>
var pic = 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202102%2F26%2F20210226073347_50f94.thumb.1000_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1668131440&t=6df291a148cdb21289e91211d4daea32';

export default {
    data(){
        return {
            visible:false,
            list:[
                { name:'秋刀鱼',price:88,pic,count:1 },
                { name:'大黄鱼',price:777,pic,count:2 },
                { name:'皮皮虾',price:9,pic,count:3 },
            ]
        }
    },
    methods:{
        /* show(){
            this.visible = true;//让购物车显示
        },
        hide(){
            this.visible = false;//让购物车隐藏
        }, */
        changeVisible(){
            this.visible = !this.visible;//让购物车显示/隐藏
        },
        clean(){

        },
        handleClick(){
            console.log('触发了!');
        }
    }
}
</script>

<style lang='scss' scoped>

.shopcart{
    height: 100%;
    width: 100%;
    position: fixed;
    background-color: rgba(0, 0, 0, 0.3);
}
.content{
    position: absolute;
    bottom: 0;
    background-color: white;
    width: 100%;
    padding: 10px;
    box-sizing: border-box;
}
.content .title{
    display: flex;
    justify-content: space-between;
    font-weight: bold;
}
.content .list .good{
    display: flex;
    margin: 10px 0;
}
.content .list .good .imgbox{
    width: 80px;
    margin-right: 10px;
}
.content .list .good .imgbox img{
    width: 100%;
}
.content .list .good .text{
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}
.content .list .good .text .name{
    font-weight: bold;
}
.content .list .good .text .price{
    display: flex;
    justify-content: space-between;
}
.content .list .good .text .price span{
    display: inline-block;
    width: 14px;
    height: 14px;
    text-align: center;
    line-height: 14px;
    background-color: lightskyblue;
    color: white;
    border-radius: 50%;
}
.content .list .good .text .price span:nth-child(2){
    color: black;
    background-color: white;
}
.empty{
    text-align: center;
    padding: 50px;
}
</style>

componente principal

<template>
  <!-- 一个.vue文件就是一个组件, 一个项目中只有一个根组件 App.vue -->
  <!-- 一个.vue文件内部一般是由三部分组成: template , script , style -->
  <!-- template 内部写标签 , 只能有一个根元素 -->
  <!-- script 内部写js逻辑 , 内部需要 export default {}, 所有的js代码都需要写在这里 -->
  <!-- style 内部写css样式 , 可以通过lang='xx'指定style内部的css语法 , 可以通过设置 scoped 属性 让多个.vue文件之间的样式互不影响 -->
  <div id="app">
    <Shopcart ref="shopcart"></Shopcart>
    <div class="summary">
      <!-- 通过ref设置的标识 获取子组件实例,进而调用子组件的方法 -->
      <span @click="$refs.shopcart.changeVisible()">购物车</span>
      <span>去结算</span>
    </div>
    <Child @click.native="handleChildClick"/>
  </div>
</template>

<script>
import Shopcart from './components/Shopcart.vue'
import Child from './components/Child.vue'

export default {
    components: { Shopcart,Child },
    methods:{
      handleChildClick(){
        console.log('点击了Child组件');
      }
    }
}
</script>

<style lang="scss">
*{
  margin: 0;
  padding: 0;;
}
.summary{
  position: fixed;
  bottom: 0;
  width: 100%;
  background-color: #555;
  color: white;
  display: flex;
  justify-content: space-between;
  padding: 10px 10px;
  box-sizing: border-box;
}
</style>


Modificador @click.event

@click.left: se activa solo cuando se hace clic con el botón izquierdo del mouse

@click.right: se activa solo cuando se hace clic en el botón derecho

@click.middle: se debe hacer clic en la rueda del mouse para activar el evento de clic

@click.prevent: evita el comportamiento predeterminado, por ejemplo: salto de una etiqueta

@click.ctrl: el evento de clic debe presionarse para activar la tecla Ctrl

@click.shift: se activa cuando se presiona la tecla Mayús

@click.native: evento de clic nativo al vincular el evento de clic al componente secundario

Evento personalizado: cuando se usa un componente secundario en el componente principal, el evento vinculado directamente al componente secundario es un evento personalizado, que debe ser activado por el componente secundario vm.$emit() para ejecutar eventos nativos: directamente en el componente secundario componente El evento enlazado en la plantilla se puede activar directamente después de introducir el subcomponente

Supongo que te gusta

Origin blog.csdn.net/m0_53181852/article/details/127598133
Recomendado
Clasificación