首页 > 编程语言 >vue2源码-十七、Vue组件间传值的方式及之间区别

vue2源码-十七、Vue组件间传值的方式及之间区别

时间:2023-04-28 22:14:58浏览次数:45  
标签:Vue const vm cbs 源码 vue2 props 组件 event

Vue组件间传值的方式及之间区别

  1. 通过props传递:父组件传递数据给子组件

    • 使用

      // chilid,vue
      props:{  
          // 字符串形式  
       name:String // 接收的类型参数  
          // 对象形式  
       age:{    
          type:Number, // 接收的类型为数值  
          defaule:18,  // 默认值为18  
          require:true // age属性必须传递  
       }  
      }  
      // father.vue
      <Children name="jack" age=18 />  
      
    • 源码:

      vm._propKeys = []
      const props = vm.$options.props
      for (const key in props) {
        vm._propKeys.push(key)
        const value = props[key]
        const hyphenatedKey = hyphenate(key)
        defineReactive(props, key, value)
        if (!(key in vm)) {
          proxy(vm, `_props`, key)
        }
      }
      
      • 首先,通过$options.props获取到组件定义的props属性。
      • 然后通过hyphenate()方法将驼峰命名转换为连字符分割的字符串
      • 使用defineReactive()方法将每个prop对应的值变成响应式的,并且当prop对应的改变时,会触发重新渲染
      • 最后,使用proxy()方法把prop对象上的属性代理到Vue实例(props)上
  2. 通过$emit触发自定义事件:子组件传递数据给父组件。

    • 使用

      // child.vue
      this.$emit('add', good)  
      // father.vue
      <Children @add="cartAdd($event)" />  
      
    • 源码

      Vue.prototype.$emit = function (event: string): Component {
        // 获取当前实例this
        const vm: Component = this
      
        // 在非生产环境下检查事件名是否大小写正确
        if (process.env.NODE_ENV !== 'production') {
          const lowerCaseEvent = event.toLowerCase()
          if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
            tip(
              `Event "${lowerCaseEvent}" is emitted in component ` +
              `${formatComponentName(vm)} but the handler is registered for "${event}". ` +
              `Note that HTML attributes are case-insensitive and you cannot use ` +
              `v-on to listen to camelCase events when using in-DOM templates. ` +
              `You should probably use "${hyphenate(event)}" instead of "${event}".`
            )
          }
        }
      
        // 获取所有监听器
        let cbs = vm._events[event]
      
        // 如果有监听器,执行它们,并将事件参数传递给它们
        if (cbs) {
          // 如果监听器是数组,复制一份新数组,否则就用原来的
          cbs = Array.isArray(cbs) ? cbs.slice() : cbs
      
          // 获取除event参数之外的其他所有参数
          const args = toArray(arguments, 1)
      
          // 定义错误信息
          const info = `event handler for "${event}"`
      
          //遍历该事件所有监听器,并一个个执行
          for (let i = 0, l = cbs.length; i < l; i++) {
            invokeWithErrorHandling(cbs[i], vm, args, vm, info)
          }
        }
      
        // 返回当前Vue实例以支持链式调用
        return vm
      }
      
  3. ref:父组件在使用子组件的时候设置ref

    • 使用

      <Children ref="foo" />  
          
      this.$refs.foo  // 获取子组件实例,通过子组件实例我们就能拿到对应的数据  
      
  4. EventBus:兄弟组件传值

  5. $attrs$listeners:祖先传递给子孙

    • 使用

      // child:并未在props中声明foo  
      <p>{{$attrs.foo}}</p>  
        
      // parent  
      <HelloWorld foo="foo"/>  
      
      // 给Grandson隔代传值,communication/index.vue  
      <Child2 msg="lalala" @some-event="onSomeEvent"></Child2>  
        
      // Child2做展开  
      <Grandson v-bind="$attrs" v-on="$listeners"></Grandson>  
        
      // Grandson使⽤  
      <div @click="$emit('some-event', 'msg from grandson')">  
      {{msg}}  
      </div>  
      

标签:Vue,const,vm,cbs,源码,vue2,props,组件,event
From: https://www.cnblogs.com/dgqp/p/17363263.html

相关文章

  • 深入探讨源码--ArrayList
    持续推送技术干货目录深入探讨源码之ArrayListArrayList类图ArrayList的数据结构ArrayList的关键属性ArrayList构造方法ArrayList常用方法add方法ArrayList中的fast-fail机制add(i,o)方法set(i,o)方法get(i)方法remove(index)方法remove(Object)方法clear方法indexOf(o)方法深......
  • Vue实战案例
    Vue项目案例结合之前学习的vue.js、脚手架、vuex、vue-router、axios、elementui等知识点,来开发前端项目案例(仅前端不含后端)。1.项目搭建其实就是将我们项目需要用到的组件都安装并配置好,需要做的事有:创建项目&运行项目vuecreate项目名称npmrunserveWebStorm集......
  • Vue——renderMixin【十八】
    前言经过lifecycleMixin再接下来就到了renderMixin,接下来咱们就看看renderMixin中到底有什么;内容renderMixin位于src/core/instance/render.ts下;exportfunctionrenderMixin(Vue:typeofComponent){//installruntimeconveniencehelpers//挂载各种私有方法......
  • Java重写源码中的方法
    重写步骤:1.找到你所要重写的方法的所在类,查看其中的路径;2.在我们的src目录下新建一个同包名同类名的类;3.将jar包中的重写方法所在类的所有代码复制到我们新建的同包名同类名的类中;4.在我们新建的同包名同类名的类中修改对应的方法中的代码,注意要保持方法中的参数不要发生改变,也......
  • vue3 ts 网易云信 未读数 手动设置已读已废弃
    vue3ts网易云信未读数//未读数清空$uikit.resetSessionUnread(store.sessionId.value);调用接口nim.resetSessionUnread('sessionId')重置会话未读数。将此会话未读数置为0,之后收到消息重新计算未读数。调用接口nim.setCurrSession('sessionId')设置当前会话。将此会......
  • vue3 获取asset文件夹下所有资源文件列表
     参考链接:https://www.jianshu.com/p/0f4386d19c07importpathfrom"path"; constgetLayerBgs=function(){ constimgs:any=[]; //获取所有背景图层 //读取文件的路径是否遍历文件的子目录匹配文件正则表达式 constfiles=require.context("@/a......
  • Vue项目如何配置、切换主题颜色(mixin + scss方式,简单高效)
    Action一.首先,引入scss依赖(node-sass,sass-loader)npminstallnode-sasssass-loader--save-dev1二.项目样式文件目录介绍1.此处我将项目中的公共样式文件放到了src/style目录下,其中index.scss是以供全局使用的一些基本样式,在main.js文件中引入即可全局使用(图2)。_theme.scs......
  • vue3 + ts + vite 封装 request
    npmiaxios目录 request.ts (直接复制可用)importaxiosfrom"axios";import{showMessage}from"./status";//引入状态码文件import{ElMessage}from"element-plus";//引入el提示框,这个项目里用什么组件库这里引什么//设置接口超时时间axios.defa......
  • Spring源码分析之BeanFactory
    概述以XmlBeanFactory为例分析Xml描述的Bean被Reasource加载到内存,先解析为Document对象,再解析为BeanDefinition注册到BeanDefinitionRegistry,再通过BeanFactory创建名词解释Resource是Spring对资源的抽象,主要是用来读取文件输入流Document是java本身的API进行解析的,得到......
  • vue3自定义指令实现el-select下拉加载更多
    1.新建js文件exportdefault(app)=>{app.directive('loadmore',{beforeMount(el,binding){constelement=el.querySelector('.t-select__dropdown');element.addEventListener('scroll',()=>{co......