组件插槽,生命周期,轮播图组件的封装,自定义指令的封装等详解以及axios的卖座案例

news2024/12/23 9:48:09

3.组件插槽

3-1组件插槽

在这里插入图片描述

注意

插槽内容可以访问到父组件的数据作用域,因为插槽内容本身就是在父组件模版中定义的

插槽内容无法访问子组件的数据.vue模版中的表达式只能访问其定义时所处的作用域,这和JavaScript的词法作用域是一致的,换言之:

父组件模版的表达式只能访问父组件的作用域,子组件模版中的表达式只能访问子组件的作用域

3-2具名插槽

具名思意:就是给插槽取一个相同的名字,使它到相应的位置

在这里插入图片描述

案例

App.vue

<template>
	<div>
        <!-- 使用具名插槽的使用,使用template进行包裹-->
        <!--v-slot:left,记住没有引号-->
        <template v-slot:left>
            <i>左边</i>
		</template>
  <!-- 可以省略写成# -->
	 <template #center>
            <div>中间</div>
		</template>
 <template>
            <i>右边</i>
		</template>
    </div>
</template>

Child.vue

<template>
	<div>
            <!-- name:是插槽的名字,与父组件的slot要一致 -->
        <slot name="left"></slot>
         <slot name="center"></slot>
         <slot name="right"></slot>
    </div>
</template>
3-3作用域插槽

在某些场景下,如果想要同时使用父组件和子组件区域内的数据,要做到这一点,就需要让子组件在渲染的时候,把数据提供给插槽,这就是作用域插槽

在这里插入图片描述

案例:通过axios获取猫眼的数据

注意点:

  1. v-slot=“scope” 不能写在Film组件里面,如果写在Film里面就需要删掉template包装元素
  2. v-slot=“{scope}”:还可以使用对象解析,因为传过来的是一个对象

App.vue(方式一)

<template>
	<Film>
    	<template v-slot="scope">
            <ul>
               <li v-for="data in scope.list" :key="data.id">
                     <img :src="data.img" style="width: 100px;">  
                  {{ data.nm }}
    			</li> 
   			 </ul>
		</template>
    </Film>
</template>

Film.vue

<template>
	<div>
        <ul>
            <!-- 把数据通过作用域插槽,传到父组件去(可以传多个,传过去的是一个对象-->
           <slot :list="dataList">
    				 <li v-for="data in dataList" :key="data.id">
                   {{ data.nm }}
    		</li>
    		</slot>
    	</ul>
    </div>
</template>
<script>
    //引入axios模块,需要先下载 npm i axios
	import axios from "axios";
    export defalut{
        data(){
            return {
                dataList:[]
            }
        },
           //钩子函数,mounted,页面一加载就显示数据
            mounted(){
                 //json文件,记得放在public文件夹下面,否则访问不到
                axios.get("../../../public/js/hot.json").then(res => {
                console.log(res.data.data.hot);
                this.dataList = res.data.data.hot;
            })
            }
    }
</script>

''方式二

具名插槽与作用域联合使用

App.vue

<Film>
	 <!-- 具名插槽与作用域插槽联合使用 -->
           <!--#Film:就是子组件定义了一个name="Film"  -->
           <!--  v-slot:Film===#Film-->
           <!-- <template  v-slot:Film="{list,a}"> -->
            <!-- 使用default默认插槽,则页面显示的是子组件的内容,不再是父组件的内容 -->
           <!-- <template  #default="{list,a}"> -->
           <template  #Film="{list,a}">
            {{ a }}
            <ul>
                <li v-for="data in list" :key="data.id">
                  <img :src="data.img" style="width: 100px;">  
                  {{ data.nm }}
                </li>
              </ul>
           </template>     
</Film>

Film.vue

 <!-- 还可以使用具名插槽配合作用域插槽一起使用 -->
      <slot :list="dataList" :a="1" :b="2" name="Film">
        <ul >
            <li v-for="data in dataList" :key="data.id">
                {{ data.nm }}
                
            </li>
        </ul>
      </slot>

4.生命周期

每个Vue组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到DOM,以及在数据改变时更新DOM.在此过程中,它也会运行被称为生命周期钩子函数,让开发者有机会再特定阶段运行自己的代码

在这里插入图片描述

(1) beforeCreate()会在实例初始化完成、props 解析之后、data()computed 等选项处理之前立即调用。(无法访问状态以及methods)

(2)created() 当这个钩子被调用时,以下内容已经设置完成:响应式数据、计算属性、方法和侦听器。然而,此时挂载阶段还未开始,因此 $el 属性仍不可用。(能访问到初始化,并且能做初始化)

(3)beforeMount()当这个钩子被调用时,组件已经完成了其响应式状态的设置,但还没有创建 DOM 节点。它即将首次执行 DOM 渲染过程。(第一次创建最后能修改状态的地方)

(4)mounted()所有同步子组件都已经被挂载。这个钩子通常用于执行需要访问组件所渲染的 DOM 树相关的副作用("挂载dom节点,初始化轮播,Echarts,setInterval,ajax)

只要状态改变,5和6函数就会被调用

(5)beforeUpdate()这个钩子可以用来在 Vue 更新 DOM 之前访问 DOM 状态。在这个钩子中更改状态也是安全的。(能访问到最新的状态,无法访问到更新后的dom)

(6)updated()这个钩子会在组件的任意 DOM 更新后被调用,这些更新可能是由不同的状态变更导致的。如果你需要在某个特定的状态更改后访问更新后的 DOM,请使用 nextTick() 作为替代。(访问到更新之后的dom)

(7)beforeUnmount()当这个钩子被调用时,组件实例依然还保有全部的功能。

(8)unmounted()在一个组件实例被卸载之后调用。

Echarts案例

npm i echars

<template>
    
    <!-- 必须要有宽度和高度,否则显示不出来 -->
    <div>
        <button @click="small">小图</button>
        <div id="main" :style="styleObj"></div>
    </div>
</template>
<script>
import * as echarts from 'echarts';
export default {
    data() {
        return {
            styleObj: {
                width: "600px",
            height: "400px"
            }
        }
    },
    methods: {
        small() {
            this.styleObj.width = "400px"
            // this.styleObj.height = "100px"
            //----------------方法二,改变大小-----------------
            // setTimeout(() => {
            //    this.myChart.resize() 
            // },0)
            //----------------方法三.直接使用提供的方法-----------------
            // 在 Vue 中,DOM 更新不是同步的,而是异步执行的,而 $nextTick 则提供了一种在 DOM 更新后执行代码的方式。
            this.$nextTick(() => {
                this.myChart.resize()
            })
        },

    },
    mounted() {
        // 基于准备好的dom,初始化echarts实例
  this.myChart = echarts.init(document.getElementById('main'));
// 绘制图表
this.myChart.setOption({
  title: {
    text: 'ECharts 入门示例'
  },
  tooltip: {},
  xAxis: {
    data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
  },
  yAxis: {},
  series: [
    {
      name: '销量',
      type: 'bar',
      data: [5, 20, 36, 10, 10, 20]
    }
  ]
});
    },
    updated() {
        // 改方法是控制点击按钮之后,使值生效
        // 任何状态更新,都会触发该生命周期函数
        // this.myChart.resize();
    },
}

</script>
//----------------跟随窗口,大小随着改变-----------------
    window.onresize = () => {
             this.myChart.resize()
      }
    },
    unmounted() {
        // 销毁实例
        window.onresize = null
   }

挂载在window上的东西,记得要销毁,使用unmound

5.组件的封装

轮播组件

App.vue

<template>
    <div>
        <MySwiper v-if="dataList.length" @event="handleEvent" :loop="false">
         <MySwiperItem v-for="data in dataList" :key="data" >
            {{ data.nm }}
            <img :src="data.img" alt="" srcset="" style="width: 600px; height:300px" >
         
         </MySwiperItem>
        
            </MySwiper>
            {{ info }}
    </div>
</template>
<script>
    import MySwiper from "./MySwiper.vue";
import MySwiperItem from "./MySwiperItem.vue";
    import axios from "axios";
export default {
    data() {
        return {
            dataList: [],
            info:""
        }
    },
    methods: {
        handleEvent(index) {
            console.log(index,);
         this.info=this.dataList[index].videoName

        }
    },
    mounted() {
        axios.get("../../../public/js/hot.json").then(res => {
            console.log(res.data.data.hot);
            this.dataList = res.data.data.hot;
            this.info=this.dataList[0].videoName
       })
    },
    components: {
        MySwiper,
        MySwiperItem
        }
    }
</script>

MySwiper.vue

<template>
<div class="swiper">
  <div class="swiper-wrapper">
    <slot></slot>
  </div>
  <!-- If we need pagination -->
  <div class="swiper-pagination"></div>

  <!-- If we need navigation buttons -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>

</div>
</template>
<script>
import Swiper from 'swiper/bundle';
import 'swiper/css/bundle';
export default {
  props: {
    loop: {
      type: Boolean,
      default: true
  }
},
    mounted() {
        var mySwiper = new Swiper('.swiper', {

          loop: this.loop,

  // If we need pagination
  pagination: {
    el: '.swiper-pagination',
  },

  // Navigation arrows
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },

          on:{
            slideChange:  ()=> {
                    console.log('改变了,activeIndex为' + mySwiper.activeIndex);

                this.$emit("event",mySwiper.activeIndex)
                },
  },
});
   }
}
</script>
<style>
.swiper {
  width: 600px;
  height: 300px;
}
</style>

MySwiperItem.vue

<template>
    
            <div class="swiper-slide">
                <slot></slot>
            </div>
           
  
</template>

6.自定义指令

6-1指令写法&钩子

除了 Vue 内置的一系列指令 (比如 v-modelv-show) 之外,Vue 还允许你注册自定义的指令 (Custom Directives)。自定义指令主要是为了重用涉及普通元素的底层 DOM 访问的逻辑

全局注册自定义指令

main.js里面

CreateApp(App)
//自定义一个颜色的指令,这里写color就可以,使用指令需要加v-,就是v-color
.directive('color',{
    //挂载在mounted上
    mounted(el){
        //el是dom节点
        console.log(el);
       el.style.backgroundColor = 'red'
    }
})
.mount("#app")

App.vue(局部注册)

<template>
	<div>
        <!--方式1-->
        <h1 v-color="'red'"> </h1>
          <!--方式2:动态绑定-->
         <h1 v-color="myColor"> </h1>
   
    </div>
</template>
<script>
	export defalut{
        data(){
            return {
                myColor:'yellow'
            }
        }
        //自定义指令
        directives:{
            color:{
                mounted(el,binding){
                    el.style.background=binding.value
                },
                    //动态绑定,需要使用更新钩子函数
                    updated(el,binding){
                         el.style.background=binding.value
                    }
            }
        }
    }
</script>

指令可以简写

对于自定义指令来说,一个很常见的情况是仅仅需要在 mountedupdated 上实现相同的行为,除此之外并不需要其他钩子。这种情况下我们可以直接用一个函数来定义指令,如下所示:

<div v-color="color"></div>
color(el, binding) {
            el.style.backgroundColor = binding.value;
            },

指令钩子

const myDirective = {
  // 在绑定元素的 attribute 前
  // 或事件监听器应用前调用
  created(el, binding, vnode, prevVnode) {
    // 下面会介绍各个参数的细节
  },
  // 在元素被插入到 DOM 前调用
  beforeMount(el, binding, vnode, prevVnode) {},
  // 在绑定元素的父组件
  // 及他自己的所有子节点都挂载完成后调用
  mounted(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件更新前调用
  beforeUpdate(el, binding, vnode, prevVnode) {},
  // 在绑定元素的父组件
  // 及他自己的所有子节点都更新后调用
  updated(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件卸载前调用
  beforeUnmount(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件卸载后调用
  unmounted(el, binding, vnode, prevVnode) {}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1223708.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码示例:基于JAX-WS和JAXB,其中http请求和响应的报文体都是xml数据

说明 基于JAX-WS编写了RESTful的web服务端点。 http请求和响应的报文体都是xml数据&#xff0c;服务端分别对应了用JAXB注解的请求和响应类。 只实现了服务端的代码示例 客户端使用了Postman 示例 要实现的目标&#xff1a;http请求和响应报文体的xml数据 http请求报文体的…

Idea安装完成配置

目录&#xff1a; 环境配置Java配置Maven配置Git配置 基础设置编码级设置File Header自动生成序列化编号配置 插件安装MyBtisPlusRestfulTooklkit-fix 环境配置 Java配置 Idea右上方&#xff0c;找到Project Settings. 有些版本直接有&#xff0c;有些是在设置下的二级菜单下…

【Linux系统编程十九】:(进程通信)--匿名管道/模拟实现进程池

【Linux系统编程十九】&#xff1a;匿名管道原理/模拟实现进程池 一.进程通信理解二.通信实现原理三.系统接口四.五大特性与四种情况五.应用场景--进程池 一.进程通信理解 什么是通信&#xff1f; 通信其实就是一个进程想把数据给另一个进程&#xff0c;但因为进程具有独立性…

小程序授权获取头像

wxml <view class"header"><text>头像</text><button class"butt" plain"true" open-type"chooseAvatar" bind:chooseavatar"chooseAvatar"><image src"{{HeadUrl}}" mode"&quo…

Java - 位运算的基本原理和用途

Java - 位运算的基本原理和用途 前言一. Java 位运算基本操作1.1 按位与 &1.2 按位或 |1.3 按位异或 ^1.4 按位取反 ~1.5 位移运算1.5.1 左移运算符 <<1.5.2 右移运算符 >>1.5.3 无符号右移运算符 >>> 二. 位运算实际运用2.1 判断奇偶性&#xff08;&…

DB9串口引脚介绍

一、公头和母头 图片示意源于网络: 二、 每个引脚的功能定义 公头&#xff1a;所有排针式的接头&#xff08;5针朝上&#xff0c;从左到右序号依次是1~9&#xff09; 母头&#xff1a;所有插槽式的接孔&#xff08;5孔朝上&#xff0c;从右到左序号依次是1~9&#xff09; 针…

计算机毕业设计选题推荐-掌心办公微信小程序/安卓APP-项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

Web与DNS综合实验

目录 题目&#xff1a; 步骤一&#xff1a;准备工作 步骤二&#xff1a;在server端搭建简单网页 步骤三&#xff1a;node1端的DNS解析配置 步骤五&#xff1a;node2端进行测试。 题目&#xff1a; 1.打开3个主机&#xff0c;server、node1、node2 2.server为web主机建立网…

typora使用PicGo自动上传图片到chevereto图床

typora使用PicGo自动上传图片到chevereto图床 近期发现&#xff0c;gitee图床不能用了。github又涉及科学上网。搜索了开源图床方案&#xff0c;找到了chevereto&#xff0c;使用起来还不错。分享给大家。 文章目录 typora使用PicGo自动上传图片到chevereto图床chevereto图床安…

轻量级 Java 日志组件

日志记录功能在开发中很常用&#xff0c;不仅可以记录程序运行的细节&#xff0c;方便调试&#xff0c;也可以记录用户的行为&#xff0c;是框架中不可或缺的组件。为最大程度复用现有的组件&#xff0c;我们就地取材使用了 JDK 自带的 JUL&#xff08;java.util.logging&#…

Linux--初识和几个简单的指令(1)

目录 前言 0.什么是操作系统 0.1 搭建 Linux 环境 0.2搭建 Linux 环境小结 1.使用 XShell 远程登录 Linux 1.1关于 Linux 桌面 1.2下载安装 XShell 1.3查看 Linux 主机 ip 1.4XShell 下的复制粘贴 2.Linux下基本指令 2.1 pwd命令 2.2 ls命令 2.3 mkdir指令 2.4 cd…

Linux上编译和安装SOFA23.06

前言 你可以直接使用编译安装好的SOFA版本Installing from all-included binaries (v23.06.00)&#xff1a; 如果你想自己编译&#xff0c;可以看我下面写的内容&#xff0c;不过绝大多数是从官网来的&#xff0c;如果和官网有出入&#xff0c;建议还是以官网为准。 在Linux下…

josef约瑟 时间继电器 ST3PA-A AC220V 带插座PF085A

ST3P系列时间继电器适用于交流50Hz或60Hz,额定电压380V及以下或直流24V的控制电路中作廷时元件,按预定的时间接通或分断电路。具有体积小,精度高,延时范围宽,可与JSZ3系列继电器等同互换使用。 系列型号 ST3PF-2Z(JSZ3F-2Z) 5s AC110V ST3PF(JSZ3F) 10s AC48V ST3PC-1(AH3-3)…

IJ中配置TortoiseSVN插件:

文章目录 一、报错情况&#xff1a;二、配置TortoiseSVN插件&#xff1a; 一、报错情况&#xff1a; 由于公司电脑加密&#xff0c;TortoiseSVN菜单没有提交和更新按钮&#xff0c;所以需要使用IJ的SVN进行代码相关操作 二、配置TortoiseSVN插件&#xff1a; 需要设置一个svn.…

Go 之 captcha 生成图像验证码

目前 chptcha 好像只可以生成纯数字的图像验证码&#xff0c;不过对于普通简单应用来说也足够了。captcha默认将store封装到内部&#xff0c;未提供对外操作的接口&#xff0c;因此使用自己显式生成的store&#xff0c;可以通过store自定义要生成的验证码。 package mainimpor…

LINUX入门篇【6】----第一个LINUX小程序---进度条及相关知识讲解

前言&#xff1a; 本篇我们将开始尝试构建我们的第一个LINUX的小程序----进度条作为一个十分常见的程序&#xff0c;在我们之后的工程实践中也是需要多次运用&#xff0c;但是介于我们目前还没有去学习网络等方面的知识&#xff0c;没法独立的去利用程序去下载一个真正的程序&…

【Proteus仿真】【Arduino单片机】LM35温度计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用PCF8574、LCD1602液晶、LM35传感器等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示传感器检测温度。 二、软件设计 /* 作者&a…

场景交互与场景漫游-路径漫游(7)

路径漫游 按照指定的路径进行漫游对一个演示是非常重要的。在osgViewer中&#xff0c;当第一次按下小写字母“z”时&#xff0c;开始记录动画路径;待动画录制完毕&#xff0c;按下大写字母“Z”&#xff0c;保存动画路径文件;使用osgViewer读取该动画路径文件时&#xff0c;会回…

Cadence virtuoso drc lvs pex 无法输入

问题描述&#xff1a;在PEX中的PEX options中 Ground node name 无法输入内容。 在save runset的时候也出现无法输入名称的情况 解决办法&#xff1a; copy一个.bashrc文件到自己的工作目录下 打开.bashrc文件 在.bashrc中加一行代码&#xff1a;unset XMODIFIERS 在终端sour…