【Vue入门】scoped与组件通信

发布时间:2026/7/31 4:09:31

【Vue入门】scoped与组件通信 欢迎来到我的CSDN博客Optimistic _ chen✨一名热爱技术与分享的全栈开发者在这里记录成长专注分享编程技术与实战经验助力你的技术成长之路与你共同进步我的专栏推荐专栏内容特色适合人群C语言从入门到精通系统讲解基础语法、指针、内存管理、项目实战零基础新手、考研党、复习Java基础语法系统解释了基础语法、类与对象、继承Java初学者Java核心技术面向对象、集合框架、多线程、网络编程、新特性解析有一定语法基础的开发者Java EE 进阶实战Servlet、JSP、SpringBoot、MyBatis、项目案例拆解想快速入门Java Web开发的同学Java数据结构与算法图解数据结构、LeetCode刷题解析、大厂面试算法题面试备战、算法爱好者、计算机专业学生Redis系列从数据类型到核心特性解析项目必备我的承诺✅ 文章配套代码每篇技术文章都提供完整的可运行代码示例✅ 持续更新专栏内容定期更新紧跟技术趋势✅ 答疑交流欢迎在文章评论区留言讨论我会及时回复支持互粉 关注我解锁更多技术干货⏳ 每天进步一点点未来惊艳所有人✍️ 持续更新中记得⭐收藏关注⭐不迷路 ✨ 标签:#技术博客 #编程学习 #Java #C语言 #算法 #程序员文章目录scopedscoped原理组件通信父子间通信父传子子接父传子传父props数据和响应式数据的区别非父子间通信完结撒花scoped前面忘记说style标签中的scoped属性我们在vue文件中使用vbase快捷键(安装 Vue VSCode Snippets 插件即可)生成的Vue 组件的初始模板代码中style默认会携带scoped属性。scoped通常指的是一种样式作用域使用 scoped 样式可以确保 CSS 只对当前组件生效从而防止全局样式污染让样式只作用于当前组件的标签。父组件templatedivclassboxp父组件的段落/p!--引入子组件--Child//div/templatescriptimportChildfrom./Child.vueexportdefault{components:{Child}}/scriptstyle scoped/* 这里也加了 scoped样式仅作用于当前组件 */.box{border:2px solid red;/* 红色边框 */padding:10px;}p{color:red;/* 红色文字 */}/style子组件templatedivclasschild-boxp子组件的段落/p/div/templatestyle scoped/* 这里加了 scoped样式仅作用于当前组件 */.child-box{border:2px solid blue;/* 蓝色边框 */padding:10px;margin:10px;}p{color:blue;/* 蓝色文字 */font-weight:bold;}/stylescoped原理上面的例子佐证了scoped的作用观察F12开发者工具Vue给父组件里的所有元素包括最外层的 div添加了一个类似data-v-7a7a37b1的特殊属性。同时它把父组件的style scoped里的所有 CSS 选择器都改成了类似.box[data-v-7a7a37b1]的形式。父组件的样式规则就只能匹配到带有data-v-f3f3eg9这个属性的元素而无法影响到子组件内部的元素因为子组件内部的元素拥有的是另一个不同的属性。这就实现了样式的隔离。组件通信在上篇博客中我们探讨了组件和组件化的概念。当项目被拆分为多个独立组件后数据是否也需要拆分呢显然不行。为了实现组件间的数据共享当一个组件需要访问另一个组件的数据时就需要用到组件通信机制。进行组件通信首要明确两个组件之间的关系进而选择不同的通信方案。比如父子关系谁被使用谁就是子组件当前组件就是父组件非父子关系跨组件通信父子间通信父子间通信分为两部分父传子 与 子传父Props声明一个组件需要显式声明它所接受的 props这样 Vue 才能知道外部传入的哪些是props。使用组合式API的script setup单文件组件中props可以使用defineProps()来声明script setup//数组方法constpropsdefineProps([foo])console.log(props.foo)/script在选项式API的组件中props使用props选项来声明exportdefault{props:[foo],setup(props){// setup() 接收 props 作为第一个参数console.log(props.foo)}}上述使用数组方法声明我们更多的时候使用对象来声明//完整语法constpropsdefineProps({属性名:{type:类型,// Number String Boolean ...required:true,// 是否必填default:默认值,// 默认值// value: ⽗传⼦的值validator(value){//⾃定义校验逻辑return布尔值}}})//对象方法defineProps({title:String,likes:Number})以对象形式声明的每个属性key 是 prop 的名称而值则是该 prop 预期类型的构造函数。一句话总结props 就是子组件声明它可以接收哪些数据然后父组件通过自定义属性的形式把这些数据传进去父传子子接父传传递步骤子组件通过defineProps接收数据子接父组件通过自定义属性传递数据父传父组件templatedivclassparenth3父组件/h3!--传递 props--!--自定义属性message age user--Child messageHello from parent:age25:user{ name: 张三, age: 18 }//div/templatescript setupimportChildfrom./Child.vue/script子组件templatedivclasschildh3子组件/h3p收到的消息{{message}}/pp年龄{{age}}/pp用户信息{{user.name}}-{{user.age}}/p/div/templatescript setup// 定义 props不需要引入直接使用constpropsdefineProps({message:String,age:Number,user:{type:Object,default:()({})}})/script总结所有的 props 都遵循着单向绑定原则props 因父组件的更新而变化自然地将新的状态向下流往子组件而不会逆向传递。也就是说数据还是属于父组件的子组件只能“看”而不能写。子传父想要修改数据子组件通知emit父组件让父组件修改后重新传递数据子组件重新渲染即可⽗组件内⼦组件标签上绑定监听⾃定义事件⾃定义事件⽗修改数据的函数⽗绑定⼦组件恰当时机触发⽗组件的⾃定义事件,emit(⾃定义事件, 携带的参数...), 从⽽导致⽗组件修改函数的时候⼦触发父组件templatedivclassparenth3父组件/h3p从子组件接收到的消息{{receivedMessage}}/pp从子组件接收到的计数{{childCount}}/p!--监听子组件的事件--Child send-messagehandleMessageupdate-counthandleCount//div/templatescript setupimport{ref}fromvueimportChildfrom./Child.vueconstreceivedMessageref()constchildCountref(0)consthandleMessage(msg){receivedMessage.valuemsg}consthandleCount(count){childCount.valuecount}/script子组件templatedivclasschildh3子组件/h3p当前计数{{count}}/pbutton clicksendToParent发送数据给父组件/buttonbutton clickupdateCount更新内部计数/button/div/templatescript setupimport{ref}fromvue// 定义要触发的事件constemitdefineEmits([send-message,update-count])// 子组件自己的数据constcountref(0)// 触发事件传给父组件constsendToParent(){emit(send-message,这是子组件传来的数据)}constupdateCount(){count.value// 把最新的 count 传给父组件emit(update-count,count.value)}/scriptprops数据和响应式数据的区别角度响应式数据props谁的数据组件自己的父组件的能否修改能✅不能❌定义方式组件内部父组件传递更新方式随数据变化父组件更新才会更新APIref()reavtive()defineProps()非父子间通信当两个组件不是直接的父子关系时比如兄弟组件、隔代组件、无关联组件就需要用其他方式通信。方案一安装第三方库mittnpmi mitt创建事件中间人// utils/eventBus.jsimportmittfrommittconstemittermitt()exportdefaultemitter组件A发送数据templatedivh3组件A/h3button clicksendMessage发送消息/button/div/templatescript setupimporteventBusfrom../utils/eventBusconstsendMessage(){// 发送事件任何地方都能监听eventBus.emit(message,你好我是组件A)}/script组件B接收数据templatedivh3组件B/h3p收到的消息{{message}}/p/div/templatescript setupimport{ref,onMounted,onUnmounted}fromvueimporteventBusfrom../utils/eventBusconstmessageref()// 监听事件onMounted((){eventBus.on(message,(msg){message.valuemsg})})// 组件销毁时取消监听重要onUnmounted((){eventBus.off(message)})/script方法二状态管理Pinia )当应用复杂很多组件需要共享状态时用专门的状态管理库所有数据都写到管理库其他组件直接去调用接口安装npmi pinia创建store// stores/counter.jsimport{defineStore}frompiniaexportconstuseCounterStoredefineStore(counter,{state:()({count:0,user:{name:张三}}),actions:{increment(){this.count},setUser(name){this.user.namename}}})使用templatedivp计数{{counter.count}}/pp用户{{counter.user.name}}/pbutton clickcounter.increment()增加/button/div/templatescript setupimport{useCounterStore}from../stores/counterconstcounteruseCounterStore()// 直接使用任何组件都能访问同一个状态/script总结mitt 是广播 而 Pinia 集中管理完结撒花如果这篇博客对你有帮助不妨点个赞支持一下吧你的鼓励是我创作的最大动力✨想获取更多干货欢迎关注我的专栏 →optimistic_chen收藏本文下次需要时不迷路我们下期再见 持续更新中……悄悄说点击主页有更多精彩内容哦

相关新闻