草庐IT

Vue3.0 基础学习自我理解provide 和 inject(六)

coderhzc 2023-09-28 原文

一.Vue3.0生命周期对照表

image.png

二. 在setup中使用provide 和 inject

事实上之前还学过的Provide和Inject,Composition API也可以替代之前的 Provide 和 Inject 的选项。

image.png

二.一.在父组件/爷爷组建中使用provide

<template>
  <div>
    <h1>我是父组件</h1>
    <hr>

    <Son />
  </div>
</template>

<script>
// 1.引入vue 内置的provide函数
import { provide } from "vue";

import Son from "./Son.vue"
export default {
  name:"fatherCom",
  components:{
    Son
  },
  setup() {
    const name = "huzhenchu";
    let counter = 100;

    // 2. 使用的provide函数的他有两个参数: 参数一key, 参数二: 父组件中定义的数据名称
    provide("name",name)
    provide("counter",counter)
  },
};
</script>

<style>
</style>

二.二 在子组件/孙子组件使用inject

<template>
  <div>
    <h1>从父组件/爷爷组件使用provide传递过来的数据:{{ name }}</h1>

  </div>
</template>

<script>
//  1. 父组件/爷爷组件中使用provide传值,然后这边子组件/孙子组件使用inject来接收
import { inject } from "vue";
export default {
  name: "SonCom",

  setup() {
    // 2.取值
    const name = inject("name");
    return {
      name,
    };
  },
};
</script>

<style>
</style>

实际截图

image.png

总结: Provide 和 inject 这两个函数传值和接收值的话:
第一,如果使用的普通的ES6 定义的数据那么他不是响应式的,
第二:如果使用ref/reactive定义的数据的话,他就是响应式了


image.png

三. setup 书写计数器demo和逻辑抽离

三.一.在setup中直接写业务逻辑

<template>
  <div>
    <h1>当前计数:{{ counter }}</h1>
    <h1>当前计数*2:{{doubleCounter}}</h1>
    <button @click="add">+1</button>
    <button @click="jian">-1</button>
  </div>
</template>

<script>
import { computed, ref } from "vue";
export default {
  setup() {
    let counter = ref(0);
    const doubleCounter = computed(() => counter.value * 2);

    const add = () => counter.value++;
    const jian = () => counter.value--;

    return {
      counter,
      doubleCounter,
      add,
      jian,
    };
  },
};
</script>

<style>
</style>

实际截图

image.png

三.二.在setup中数据抽离的写法:

App-vue3.0hook抽取.vue

<template>
  <div>
    <h1>当前计数:{{ counter }}</h1>
    <h1>当前计数*2:{{ doubleCounter }}</h1>
    <button @click="add">+1</button>
    <button @click="jian">-1</button>
  </div>
</template>

<script>
import userCounter from "./hooks/useCounter.js";
export default {
  setup() {
    const { counter, doubleCounter, add, jian } = userCounter();
    return {
      counter,
      doubleCounter,
      add,
      jian,
    };
  },
};
</script>

<style>
</style>

useCounter.js

import { computed, ref } from "vue";

export default function() {
  let counter = ref(0);
  const doubleCounter = computed(() => counter.value * 2);

  const add = () => counter.value++;
  const jian = () => counter.value--;

  return {
    counter,
    doubleCounter,
    add,
    jian,
  };
} 

实际截图

image.png

三.三.或者直接结构这个函数也是可以的

image.png

四. useTitle的使用:

需求我想修改如下图文字该怎么办呢?


image.png

四.一 实现方式一:

image.png

四.二实现方式二:(封装一个hook实现)

image.png

五. Vue 3.0 滚动 实现在浏览器的右下角永远实现scrollX scrollY的坐标值

实现方式一:(直接在setup函数中实现)

image.png

实现方式二:(抽离代码出去在hook中书写):

image.png

六. 实现浏览器鼠标经过坐标值

实现方式一:(直接在setup函数中实现)

鼠标在浏览器中移动时,scrollX scrollY 显示对应的值


image.png

实现方式二:(抽离代码出去在hook中书写):

image.png

六.获取或者存储回话的Hooks

image.png

七. setup顶层编写方式

什么意思呢? 就是说不需要 setup函数的包裹,然后直接像写原生JS那种写代码,怎么做到那种呢?


image.png

七.一.setup顶层编写方式--导入组件

image.png

七.二.setup顶层编写方式--在父组件传值给子组件的使用

image.png

七.三 setup顶层编写方式--在子组件传给父组件的事件

image.png

八.自定义指令的使用:

1. 在Vue中,代码的复用和抽象主要还是通过组件;
    -- 通常在某些情况下,需要对DOM元素进行底层操作,这个时候就会用到自定义指令;
 2. 自定义指令分为两种:
    -- 自定义局部指令:组件中通过 directives 选项,只能在当前组件中使用;
    -- 自定义全局指令:app的 directive 方法,可以在任意组件中被使用;

PS: 需求:我想实现当某个元素挂载完成后可以自定获取焦点(当页面加载完,input自动获取焦点)

实现方式一:

<template>
  <div>
    <input type="text" ref="input" />
  </div>
</template>

<script>
import { onMounted, ref } from "vue";
export default {
  setup() {
    const input = ref(null);
    onMounted(() => {
      console.log(input);
      console.log(input.value);
      input.value.focus()
    });

    return {
      input,
    };
  },
};
</script>

<style>
</style>

实际截图:

image.png

实现方式二:局部自定义指令

<template>
  <div>
    <input type="text" v-focus />
  </div>
</template>

<script>
export default {
  directives: {
    focus: {
      /**
       * 这个生命周期是当组件挂载到界面的时候,会执行的生命周期:
       *   -- 当挂载到页面的时候 focus中的mounted函数中就会对标签元素进行回调了,就会有四个参数:
       *   -- 参数一: el
       *   -- 参数二: bindings
       *   -- 参数三: vnode 虚拟节点
       *   -- 参数四: preVnode 前一次的vnode
       * 
       * **/ 
      mounted(el,bindings,vnode,preVnode) {  
        console.log("focus mounted",el); 
        console.log("focus mounted",bindings); 
        console.log("focus mounted",vnode); 
        console.log("focus mounted",preVnode); 
        el.focus()
      },
    },
  },
};
</script>

<style>
</style>

实际截图

image.png

实现方式三:全局自定义指令

在全局挂载:

import { createApp } from "vue";
import App from "./App.vue";

const app = createApp(App);
/**
 * 全局自定义指令:
 *   -- 参数一: 自定义组件的名称
 *   -- 参数二: 对应的是一个对象
 *
 * **/
app.directive("focus", {
  /**
   * 这个生命周期是当组件挂载到界面的时候,会执行的生命周期:
   *   -- 当挂载到页面的时候 focus中的mounted函数中就会对标签元素进行回调了,就会有四个参数:
   *   -- 参数一: el
   *   -- 参数二: bindings
   *   -- 参数三: vnode 虚拟节点
   *   -- 参数四: preVnode 前一次的vnode
   *
   * **/
  mounted(el, bindings, vnode, preVnode) {
    console.log("focus mounted", el);
    console.log("focus mounted", bindings);
    console.log("focus mounted", vnode);
    console.log("focus mounted", preVnode);
    el.focus();
  },
});

app.mount("#app");

实际截图

image.png

八.一.指令的生命周期

一个指令定义的对象,Vue提供了如下的几个钩子函数:
  -- created:在绑定元素的 attribute 或事件监听器被应用之前调用;
  -- beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用; 
  -- mounted:在绑定元素的父组件被挂载后调用;
  -- beforeUpdate:在更新包含组件的 VNode 之前调用;
  -- updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用;
  -- beforeUnmount:在卸载绑定元素的父组件之前调用;
  -- unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次;

<template>
  <div>
    <h2 @click="changeCounter">当前计数:{{ counter }}</h2>
    <button v-if="counter < 102" v-hzc @click="changeCounter">+1</button>
  </div>
</template>

<script>
import { ref } from "vue";
export default {
  // 局部指令
  directives: {
    // PS: 在我们的每个生命周期回调函数中都会有四个参数: 参数一: el 参数二: bindings,参数三: vnode 虚拟节点 参数四: preVnode 前一次的vnode
    hzc: {
      created(el,bindings,vnode,preVnode) {
        console.log("hzc created");
      },

      beforeMount(el,bindings,vnode,preVnode) {
        console.log("hzc beforeMount");
      },

      mounted(el,bindings,vnode,preVnode) {
        console.log("hzc mounted");
      },
      beforeUpdate(el,bindings,vnode,preVnode) {
        console.log("hzc beforeUpdate");
      },
      updated(el,bindings,vnode,preVnode) {
        console.log("hzc updated");
      },

      beforeUnmount(el,bindings,vnode,preVnode) {
        console.log("hzc beforeUnmount");
      },
      unmount(el,bindings,vnode,preVnode) {
        console.log("hzc unmount");
      },
    },
  },
  setup() {
    let counter = ref(100);
    const changeCounter = () => {
      counter.value++;
    };

    return {
      counter,
      changeCounter,
    };
  },
};
</script>

<style>
</style>

实际截图

image.png

八.三. 指令的参数

<template>
  <div>
    <!-- 1. v-hzc.aaa.bbb 这些aaa.bbb是修饰符 
            v-hzc.aaa.bbb="'coderhzc'":这个值可以在下面的created回调函数的第二个参数中获取到  -->
    <button v-hzc.aaa.bbb="'coderhzc'" @click="add">
      当前计数: {{ counter }}
    </button>
  </div>
</template>

<script>
import { ref } from "vue";
export default {
  directives: {
    hzc: {
      created(el, bindings, vnode, preVnode) {
        console.log(el);
        console.log(bindings);
        console.log(vnode);
        console.log(preVnode);
        console.log(bindings.value);
      },
    },
  },
  setup() {
    const counter = ref(100);
    const add = () => {
      counter.value++;
    };
    return {
      counter,
      add,
    };
  },
};
</script>

<style>
</style>

实际截图

image.png

八.四. 指令的修饰符

image.png

八.五.自定义指令的业务场景

如何在vue项目中去使用全局自定义组件的使用呢?一下步骤是详细的步骤:


image.png

八.六自定义指令的业务场景

假如格式不想使用上面的那样的话,可以让用户传递一个格式来展示


image.png

九.认识Teleport

在Vue 项目中一般是挂载到#app上面的,但是我现在不想挂载到#app上面 我想单独的挂载到一个组件上面,此时就可以使用Teleport内置组件了,,类似于react的Portals;

Teleport它有两个属性:
    -- to:指定将其中的内容移动到的目标元素,可以使用选择器;
    -- disabled:是否禁用 teleport 的功能;

十.认识Vue插件

通常我们向Vue全局添加一些功能时,会采用插件的模式,它有两种编写方式:
-- 对象类型:一个对象,但是必须包含一个 install 的函数,该函数会在安装插件时执行;
-- 函数类型:一个function,这个函数会在安装插件时自动执行;
插件可以完成的功能没有限制,比如下面的几种都是可以的:
-- 添加全局方法或者 property,通过把它们添加到 config.globalProperties 上实现;
-- 添加全局资源:指令/过滤器/过渡等;
-- 通过全局 mixin 来添加一些组件选项;
-- 一个库,提供自己的 API,同时提供上面提到的一个或多个功能;

十.一. 通过注册一个全局的plugins插件--方式一:对象注册

实际截图

image.png

PS: 这种注册了以后 在全局任何页面都可以按照以上方式取值

十.二. 通过注册一个全局的plugins插件--方式二:函数注册

image.png

有关Vue3.0 基础学习自我理解provide 和 inject(六)的更多相关文章

  1. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  2. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  3. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  4. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  5. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  6. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  7. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  8. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  9. ruby - 易于初学者理解的 Ruby 库 - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭3年前。Improvethisquestion我正处于学习Ruby的阶段,我想查看一些小型库的源代码以了解它们是如何构建的。我不知道什么是小型图书馆,但希望SO能推荐一些易于理解的图书馆来学习。因此,如果有人知道一两个非常小的库,这是新手Rubyists学习的好例子,请推荐!我想使用Manveru'sInnatelib,因为它试图保持在2000LOC以下,但我还不熟悉其中经常使用的Ruby速记。也许大约100-5

  10. ruby - 这个 ruby​​ 注入(inject)魔术是如何工作的? - 2

    我今天看到了一个ruby​​代码片段。[1,2,3,4,5,6,7].inject(:+)=>28[1,2,3,4,5,6,7].inject(:*)=>5040这里的注入(inject)和之前看到的完全不一样,比如[1,2,3,4,5,6,7].inject{|sum,x|sum+x}请解释一下它是如何工作的? 最佳答案 没有魔法,符号(方法)只是可能的参数之一。这是来自文档:#enum.inject(initial,sym)=>obj#enum.inject(sym)=>obj#enum.inject(initial){|mem

随机推荐