前端技术Vue学习笔记--005

news2024/11/19 7:40:12

Vue学习笔记

一、非父子通信-event bus 事件总线

作用:非父子组件之间,进行简易消息传递。(复杂场景用----Vuex)

使用步骤:

请添加图片描述

  1. 创建一个都能访问的事件总线 (空Vue实例)-----utils/EventBus.js
// 1.创建一个都能访问你的时间总线(空闲的Vue实例)
import Vue from "vue"

const Bus = new Vue()

export default Bus
  1. A组件(接受方),监听Bus的 $on事件
<script>
import Bus from '../utils/EventBus'
export default {
  created(){
    // 2.在A组件(接收方),进行监听Bus的事件(订阅消息)
    Bus.$on('sendMsg',(msg) => {
       consloe.log(msg)
    })
  }
}
</script>
  1. B组件(发送方),触发Bus实例的事件
<script>
//导入事件总线
import Bus from '../utils/EventBus'
export default {
  methods:{
    clickSend(){
      // 3.B组件(发送方)触发事件的方式来传递参数(发布消息)
      Bus.$emit('sendMsg','今日天气不错')
    }
  }
}
</script>

二、非父子通信(拓展)----provide&indect(跨层级共享数据)

provide&indect作用:跨层级共享数据

语法:

  1. 父组件 provide提供数据
export default {
  provide () {
    return {
       // 普通类型【非响应式】
       color: this.color, 
       // 复杂类型【响应式】
       userInfo: this.userInfo, 
    }
  }
}
  1. 子/孙组件 inject获取数据
export default {
  inject: ['color','userInfo'],
  created () {
    console.log(this.color, this.userInfo)
  }
}

注意:

  • provide提供的简单类型的数据不是响应式的复杂类型数据是响应式推荐提供复杂类型数据
  • 子/孙组件通过inject获取的数据,不能在自身组件内修改

三、子组件与父组件之间的双向绑定

3.1、原理介绍

v-model本质上是一个 语法糖(语法的简写)。例如应用在输入框上,就是value属性 和 input事件 的合写(不同的表单元素会有所不同)

作用:提供数据的双向绑定

  1. 数据发生改变,页面就会自动变 :value(v-bind:value=‘实例中的数据’)
  2. 页面输入改变,数据会自动变化 @input

注意:$event 用于在模板中,获取事件的形参

下面两种写法等价:

<template>
  <div class="app">
        1:<input v-model="msg1"  type="text"/><br>
        <!-- 模版中获取事件的形参  ->  $event获取 -->
       2:<input :value="msg2" @input=" msg2 = $event.target.value" type="text"/>
  </div>
</template>

不同的表单元素, v-model在底层的处理机制是不一样的。比如给checkbox使用v-model
底层处理的是 checked属性和change事件。

3.2、表单类组件封装&v-model简化代码

  1. 表单类组件封装—>实现了子组件和父组件数据的双向绑定
    • 父传子数据 应该是父组件props传递过来的,v-model拆解绑定数据
    • 子传父监听输入,子传父值给父组件修改

在这里插入图片描述
App.vue

<template>
  <div class="app">
    <!-- $event就可以拿到当前子传父的形参 -->
       <BaseSelect :cityId="selectId" @changeId=" selectId = $event"></BaseSelect>
  </div>
</template>

<script>
import BaseSelect from './components/BaseSelect.vue'
export default {
    data(){
        return{
            selectId: '102'
        }
    },
    components:{
        BaseSelect:BaseSelect
    }
}

BaseSelect

<template>
  <div>
    <!-- 父传子 ::value="cityId" -->
    <select :value="cityId" @change="handlerChange" >
      <option value="101">北京</option>
      <option value="102">上海</option>
      <option value="103">武汉</option>
      <option value="104">广州</option>
      <option value="105">深圳</option>
    </select>
  </div>
</template>

<script>
export default {
  props:{
    cityId: String 
  },
  methods:{
    handlerChange(e){
      //e.target.value 获取下拉菜单的值
      // alert(e.target.value)
      this.$emit('changeId',e.target.value)
    }
  }
  
}
</script>

<style>
</style>

注意:不是自己的数据不能用v-model实现双向绑定,只能通过将v-model拆解,利用父子通信的手段进行修改。

  1. 父组件v-model简化代码实现子组件和父组件的双向绑定

相比与上述代码并没有大致区别,只是将子组件的一些名字替换为value与input,从而在父组件中利用v-model实现数据绑定

v-model其实就是 :value和@input事件的简写
步骤:

  • 子组件:props通过value接收数据事件触发 input
  • 父组件v-model直接绑定数据
    在这里插入图片描述

输入框子组件通信

App.vue

<template>
  <div class="app">
 
       <!-- <BaseSelect :value="inputValue" @input="inputValue = $event"></BaseSelect> -->
       <!-- :value="inputValue" @input="inputValue = $event" 等价于v-model="inputValue" -->
       <BaseSelect v-model="inputValue"></BaseSelect>
  </div>
</template>

<script>
import BaseSelect from './components/BaseSelect.vue'
export default {
    data(){
        return{
            inputValue: 'i love china'
        }
    },
    components:{
        BaseSelect:BaseSelect
    }

}
</script>

<style>

</style>

BaseSelect

<template>
  <div>
    <!-- 父传子 ::value="cityId" -->
   <input type="text" :value="value" @change="handleChange">
   
  </div>
</template>

<script>
export default {
  props:{
    value: String 
  },
  methods:{
    handleChange(e){
      //e.target.value 获取下拉菜单的值
      // alert(e.target.value)
      this.$emit('input',e.target.value)
    }
  }
  
}
</script>

<style>
</style>

四、.sync修饰符(重要)

作用:可以实现子组件父组件双向绑定,简化代码
特点:prop属性名,可以自定义,非固定为value(用v-model)
场景:封装弹框类的基础组件,visible属性 true显示 false隐藏
本质:就是 :属性名@update:属性名 合写
子父组件的使用方式
在这里插入图片描述
弹出框数据
App.vue

<template>
  <div class="app">
    <button @click=" isShow = true ">退出按钮</button>
    <!-- :visible.sync 等价于  :visible  和@update:visible整合 -->
    <!-- <BaseDialog :visible.sync="isShow"></BaseDialog> -->
    <!-- $event用来接收  this.$emit('update:visible',false)的参数 -->
    <BaseDialog :visible="isShow"  @update:visible=" isShow = $event"></BaseDialog>
  </div>
</template>

<script>
import BaseDialog from './components/BaseDialog.vue'
export default {
  data() {
    return {
      isShow: false,
    }
  },
  components: {
    BaseDialog,
  }
}
</script>

<style>
</style>

BaseDialog

<template>
  <div class="base-dialog-wrap" v-show="visible">
    <div class="base-dialog">
      <div class="title">
        <h3>温馨提示:</h3>
        <button class="close" @click="close">x</button>
      </div>
      <div class="content">
        <p>你确认要退出本系统么?</p>
      </div>
      <div class="footer">
        <button @click="close">确认</button>
        <button @click="close">取消</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    visible: Boolean,
  },
  methods:{
    close(){

      this.$emit('update:visible',false)
    }
  }
}
</script>

<style scoped>
.base-dialog-wrap {
  width: 300px;
  height: 200px;
  box-shadow: 2px 2px 2px 2px #ccc;
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  padding: 0 10px;
}
.base-dialog .title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 2px solid #000;
}
.base-dialog .content {
  margin-top: 38px;
}
.base-dialog .title .close {
  width: 20px;
  height: 20px;
  cursor: pointer;
  line-height: 10px;
}
.footer {
  display: flex;
  justify-content: flex-end;
  margin-top: 26px;
}
.footer button {
  width: 80px;
  height: 40px;
}
.footer button:nth-child(1) {
  margin-right: 10px;
  cursor: pointer;
}
</style>

五、ref和$ref

5.1、获取dom

在这里插入图片描述

BaseChart

<template>
  <div class="base-chart-box"  ref="myCharts">子组件</div>
  <!--  -->
</template>

<script>
// yarn add echarts 或者 npm i echarts
import * as echarts from 'echarts'
// import echarts from 'echarts'

export default {
  mounted() {
    // 基于准备好的dom,初始化echarts实例
    // this.$refs.myCharts替代document.querySelector('.base-chart-box')查找范围是当前页面的盒子
    var myChart = echarts.init(this.$refs.myCharts)
    // 绘制图表
    myChart.setOption({
      title: {
        text: 'ECharts 入门示例',
      },
      tooltip: {},
      xAxis: {
        data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
      },
      yAxis: {},
      series: [
        {
          name: '销量',
          type: 'bar',
          data: [5, 20, 36, 10, 10, 20],
        },
      ],
    })
  },
}
</script>

<style scoped>
.base-chart-box {
  width: 400px;
  height: 300px;
  border: 3px solid #000;
  border-radius: 6px;
}
</style>

5.2、获取组件实例

在这里插入图片描述
App.vue

<template>
  <div class="app">
    <h4>父组件 -- <button @click="getData">获取组件实例</button></h4>
    <BaseFromVue ref="fromVue"></BaseFromVue>
      <div>
      <button @click="getData">获取数据</button>
      <button @click="resetData">重置数据</button>
    </div>
  </div>
</template>

<script>
import BaseFromVue from './components/BaseFrom.vue'

export default {
  components: {
    BaseFromVue :BaseFromVue
  },
  data(){

    return{
        user :{
            username : '',
            password : ''
        }
    }
  },
  methods: {
   getData(){
    var user =this.$refs.fromVue.getFromValue()
    // alert(user.username)
    this.user=user
   },
   resetData(){
   this.$refs.fromVue.resetFrom()
   }
  }
}
</script>

<style>
</style>

BaseFrom.vue

<template>
  <div class="app">
    <div>
      账号: <input v-model="username" type="text">
    </div>
     <div>
      密码: <input v-model="password" type="text">
    </div>
  
  </div>
</template>

<script>
export default {
    data(){
        return{
            //定义数据
            username : '',
            password : ''
        }
    },
    methods:{
        //获取到表单数据并返回
        getFromValue(){
            console.log("用户名:"+this.username)

            return{
                username : this.username,
                password : this.password
            }
        },
        resetFrom(){
            this.username=''
            this.password=''
        }
    }
}
</script>

<style scoped>
.app {
  border: 2px solid #ccc;
  padding: 10px;
}
.app div{
  margin: 10px 0;
}
.app div button{
  margin-right: 8px;
}
</style>

六、Vue异步更新、$nextTick

需求:点击编辑按钮,显示编辑框,并让编辑框自动聚焦

this.isShowEdit = true   //控制显示
 this.$refs.inp.focus()  //利用ref得到Dom聚焦

问题:“显示后”,立即获取焦点失败
原因:Vue是异步更新Dom(提升性能)

解决方法:
$nextTick:等Dom更新后,才会触发方法里的函数体
语法:this. $ nextTick

 methods: {
    editFn() {
        // 显示输入框(异步dom更新)---this.$refs.inp获取不到Dom
        this.isShowEdit = true  
        //$nextTick()
       this.$nextTick(()=>{
         // 获取焦点
        this.$refs.inp.focus() 
       })
       //setTimeout等待的时间不精准 -------- 推荐使用 $nextTick()
    //    setTimeout(() => {
    //      this.$refs.inp.focus() 
    //    }, 100);
    }  }

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

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

相关文章

浅谈更糟糕的 CS_CLASSDC 标志位的作用

在上一篇文章中&#xff0c;我们了解了 CS_OWNDC 标志位的历史&#xff0c;也说明了设计它的初衷。 这个标志位一开始看起来是个挺好的设计&#xff0c;但是如果你多琢磨一会儿&#xff0c;就会发现它不是一个好主意。今天我们来看看更糟的。 CS_CLASSDC 标志位有点类似 CS_OW…

shell脚本文本三剑客sed

shell脚本文本三剑客sed 一.Sed编辑器1.1sed概述1.2sed工作流程1.3sed基本法1.4sed常用选项1.5sed命令的常用操作 二.sed命令使用2.1打印内容2.2删除内容示例5&#xff1a;先备份内容在删除2.3插入内容2.4取反2.5搜索替代2.6分组调用 一.Sed编辑器 1.1sed概述 sed编辑器是一种…

Linux 虚拟机Ubuntu22.04版本通过远程连接连接不上,输入ifconfig只能看到127.0.0.1的解决办法

之前给虚拟机配置静态IP之后&#xff0c;可以直接通过主机Vscode远程连接。但是前一段时间把主机的TCP/IPV4静态IP设置了一下之后&#xff0c;再连接虚拟机就连不上了&#xff0c;于是参考解决虚拟机不能上网ifconfig只显示127.0.0.1的问题&#xff0c;又可以连接上了&#xff…

Python “贪吃蛇”游戏,在不断改进中学习pygame编程

目录 前言 改进过程一 增加提示信息 原版帮助摘要 pygame.draw pygame.font class Rect class Surface 改进过程二 增加显示得分 改进过程三 增加背景景乐 增加提示音效 音乐切换 静音切换 mixer.music.play 注意事项 原版帮助摘要 pygame.mixer pygame.mix…

SpringBoot复习:(56)使用@Transactional注解标记的方法的执行流程

首先&#xff0c;如果在某个类或某个方法被标记为Transactional时&#xff0c;Spring boot底层会在创建这个bean时生成代理对象&#xff08;默认使用cglib) 示例&#xff1a; 当调用studentService的addStudent方法时&#xff0c;会直接跳到CglibAopProxy类去执行intercept方…

vscode里配置C#环境并运行.cs文件

vscode是一款跨平台、轻量级、开源的IDE, 支持C、C、Java、C#、R、Python、Go、Nodejs等多种语言的开发和调试。下面介绍在vscode里配置C#环境。这里以配置.Net SDK v5.0&#xff0c;语言版本为C#9.0&#xff0c;对应的开发平台为VS2019&#xff0c;作为案例说明。 1、下载vsc…

vue3小知识点汇总——基础积累

下面的小知识点比较零散&#xff0c;但是脑子不太好使&#xff0c;只能先记录一下啦&#xff0c;后面知识丰富起来后&#xff0c;慢慢就懂了。 1.最新版node.js已经不兼容vue2的项目了&#xff0c;学习vue3势在必行 node.js的安装及vue的搭建详细步骤&#xff1a;http://t.cs…

比特币暴跌的4个原因

作者&#xff1a;秦晋 加密市场每隔一段时间&#xff0c;就会迎来一次「暴跌」&#xff0c;而且每次暴跌原因各不相同。但归根到底都是「恐慌情绪」在作怪。继「312暴跌」、「519暴跌」之后&#xff0c;又迎来一个「8.18暴跌」。相比前两次暴跌&#xff0c;此次暴跌的原因或许略…

想做赴日程序员 有一定技术经验不学日语可以赴日IT吗?

有的小伙伴问&#xff1a;我有一定的IT技术和经验&#xff0c;不学日语的话&#xff0c;能去做赴日IT工作吗&#xff1f;说实话啊&#xff0c;我感觉如果行的话&#xff0c;那只能说明你运气不错&#xff0c;因为日本的IT行业在日本来说&#xff0c;并不是非常高薪的行业&#…

Redis中的有序集合

前言 本文着重介绍Redis中的有序集合的底层实现中的跳表 有序集合 Sorted Set Redis中的Sorted Set 是一个有序的无重复值的集合&#xff0c;他底层是使用压缩列表和跳表实现的&#xff0c;和Java中的HashMap底层数据结构&#xff08;1.8&#xff09;链表红黑树异曲同工之妙…

【深入了解PyTorch】PyTorch实战项目示例:深入探索图像分类、目标检测和情感分析

【深入了解PyTorch】PyTorch实战项目示例:深入探索图像分类、目标检测和情感分析 PyTorch实战项目示例:深入探索图像分类、目标检测和情感分析项目一:图像分类数据集准备构建模型训练模型模型评估和预测项目二:目标检测数据集准备构建模型训练模型模型评估和预测项目三:情…

记录因暴露阿里最高权限的Accesskey和secretKey导致的反弹shell攻击过程

Accesskey和SecretKey的泄露的原因 说到这个最高权限的key的泄露&#xff0c;绝对是低级的设计导致的。为了减少服务端的压力&#xff0c;直接让app直连oss服务&#xff0c;而且把最高权限的Accesskey和secretKey 下发到客户端&#xff0c;那么结果就是只要安装了该app的人&am…

js判断用户当前网络状态和判断网速

前端判断用户当前网络状态和判断网速 一、第一种是通过 HTML5 提供的 navigator 去检测网络(1)、原理介绍:(2)、兼容性 二、监听window.ononline和window.onoffline事件:三、通过ajax进行请求判断(兼容性好-推荐)(1)、原理介绍:(2)、注意: 四、navigator.connection方法监听网络…

PP-TS基于启发式搜索和集成方法的时序预测模型,使预测更加准确

时间序列数据在各行业和领域中无处不在&#xff0c;如物联网传感器的测量结果、每小时的销售额业绩、金融领域的股票价格等等&#xff0c;都是时间序列数据的例子。时间序列预测就是运用历史的多维数据进行统计分析&#xff0c;推测出事物未来的发展趋势。 为加快企业智能化转型…

Vue elementui 实现表格selection的默认勾选,翻页记录勾选状态

需求&#xff1a;当弹出一个列表页数据&#xff0c;对其进行筛选选择。 列表更新&#xff0c;填充已选数据 主要使用toggleRowSelection 代码如下&#xff1a; <el-table v-loading"loading" :data"drugList" selection-change"handleSelection…

安卓手机跑 vins slam (1)

一直是手机拍照&#xff0c;用RealityCapture重建三维模型。因为他是靠特征点去把拍摄的多个图像进行对齐的。需要拍摄的足够多&#xff0c;且有特征才能对齐&#xff0c;要不然会生成多个组件&#xff0c;还得手动拼。 而且重建的三维模型有尺度问题&#xff0c;自动重建的模…

四、内存管理

1、为什么需要自己实现内存管理 (1)RTOS涉及的内核对象&#xff1a;task、queue、semaphores和event group等。为了让FreeRTOS更容 易使用&#xff0c;这些内核对象一般都是动态分配&#xff1a;用到时分配&#xff0c;不使用时释放。使用内存的动态管理功能&#xff0c;简化了…

使用yolov5进行安全帽检测填坑指南

参考项目 c​​​​​​​​​​​​​​GitHub - PeterH0323/Smart_Construction: Base on YOLOv5 Head Person Helmet Detection on Construction Sites&#xff0c;基于目标检测工地安全帽和禁入危险区域识别系统&#xff0c;&#x1f680;&#x1f606;附 YOLOv5 训练自己的…

Unity导入google.protobuf失败,无法找到google命名空间

问题&#xff1a; 1.刚开始把protobuf的文件夹直接从其他项目里(unity2021)里复制到unity(2020)版本&#xff0c;当时报错protobuf.dll的依赖项system.memory版本不对。 2.没有使用原来的protobuf文件了。使用vs2019的NuGet管理包来下载Google.Protobuf &#xff0c;仍然报错找…

爬虫学得好,然后呢?最新Python人工智能就业班课程

课程链接&#xff1a; 私信&#xff1a;达内 课程介绍&#xff1a; 【达内最新Python人工智能就业班课程目录】 &#x1f4da; 1. Python核心 &#x1f9e0; 2. 面向对象程序设计 &#x1f52e; 3. Python高级 &#x1f4bb; 4. 阶段项目实战 &#x1f427; 5. Linux操作系…