vue2源码-十七、Vue组件间传值的方式及之间区别
Vue组件间传值的方式及之间区别
通过
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
)上通过
$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 }
ref:父组件在使用子组件的时候设置
ref
使用
<Children ref="foo" /> this.$refs.foo // 获取子组件实例,通过子组件实例我们就能拿到对应的数据
EventBus
:兄弟组件传值
$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>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!