Vue 组件通信 - Ref组件通信

Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - Vue组件通信 - Ref组件通信

 

目录

Ref组件通信

创建表单

绑定组件

定义组件中的状态

修改组件中的状态

说明

组件注意

解决方式

v-once的作用

总结


Ref组件通信

Ref绑定dom节点,拿到的就是dom对象

Ref绑定组件,拿到的就是组件对象

Ref是固定的,作用是引用。

创建表单

创建一个表单,获取组件实例,不通过父子通信,直接拿状态和赋值状态。

Ref是固定的,作用是引用。

示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../lib/vue.js"></script>
</head>
<body>
<div id="box">
    <input type="text" ref="mytext">
    <input type="password" ref="mypassword">
    <div ref="mydiv">1111111</div>
    <button @click="handleAdd">Add</button>
    <child></child>
</div>
<script>
    let vm = new Vue({
        el: "#box",
        methods: {
            handleAdd() {
                console.log(this.$refs.mytext, this.$refs.mypassword, this.$refs.mydiv)
            }
        }
    })
</script>
</body>
</html>

绑定组件

因为还没有定义组件,所以控制台会抛出异常。

下面开始设置全局组件,并在绑定事件中打印组件对象。

示例如下:

<div id="box">
    <input type="text" ref="mytext">
    <input type="password" ref="mypassword">
    <div ref="mydiv">1111111</div>
    <button @click="handleAdd">Add</button>
    <child ref="mychild"></child>
</div>
<script>
    Vue.component("child", {
        template:`
        <div>
        child
        </div>`
    })
    let vm = new Vue({
        el: "#box",
        methods: {
            handleAdd() {
                console.log(this.$refs.mytext, this.$refs.mypassword, this.$refs.mychild)
            }
        }
    })
</script>

效果:

定义组件中的状态

在组件内部定义状态,并渲染出来。

示例如下:

Vue.component("child", {
    data() {
      return {
          myname: "child-222222"
      }
    },
    template:`
    <div>
    child--{{myname}}
    </div>`
})

 

修改组件中的状态

首先拿到组件中定义的状态,然后修改组件中的状态。

示例如下:

let vm = new Vue({
    el: "#box",
    methods: {
        handleAdd() {
            //console.log(this.$refs.mytext, this.$refs.mypassword, this.$refs.mychild)
            console.log(this.$refs.mychild.myname)
            this.$refs.mychild.myname="parent-111111"
        }
    }
})

效果:

说明

这样的修改方式虽然简单,但是容易造成混乱和出现问题且不易排查和扩展;

容易造成数据流紊乱。

组件注意

属性:父组件传给你的属性,只有父组件可以重新传,但不允许子组件随意修改。

示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../lib/vue.js"></script>
</head>
<body>
<div id="box">
    {{title}}
    <child :mytitle="title"></child>
</div>
<script>
    Vue.component("child", {
        props:["mytitle"],
        template:`
        <div>
        child-{{mytitle}}
        <button @click="handleClickc">click</button>
        </div>`,

        methods: {
            handleClickc() {
                this.mytitle="2222222222"
            }
        }
    })
    let vm = new Vue({
        el:"#box",
        data:{
            title:"1111111111111"
        }
    })
</script>
</body>
</html>

效果:

页面警告 不要直接去修改组件传递过来的属性;因为修改了,下次再传属性还是会被覆盖。

会造成子属性和父属性不统一,数据流紊乱,会出现不可预期的错误。

属性 --父组件传给你的属性,只有父组件可以重新传,但不允许子组件随意修改.

状态 -- 组件内部的状态,可以随意修改

解决方式

v-once 只修改一次,然后缓存状态。

示例如下:

Vue.component("child", {
    props:["mytitle"],
    template:`
    <div v-once>
    child-{{mytitle}}
    <button @click="handleClickc">click</button>
    </div>`,

    methods: {
        handleClickc() {
            this.mytitle="2222222222"
        }
    }
})

v-once的作用

渲染普通的HTML元素在Vue中时非常快速的,但有的时候你可能有一个组件,这个组件包含了大量静态内容。在这种情况下,你可以在根元素上添加v-once attribute 以确保这些内容只计算一次然后缓存下来,就像这样:

总结

Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - Vue组件通信 - Ref组件通信

### Vue3 祖孙组件通信的方法 在 Vue 3 中,祖孙组件之间的通信可以通过多种方式进行。其中较为常见的方式有提供/注入 (`provide` / `inject`) 和 使用事件总线(如 mitt)。这两种方式都能有效地解决跨层级组件间的通信需求。 #### 方法一:使用 provide/inject 进行祖孙组件通信 这种方式适用于祖父组件向其所有的子孙后代传递数据或函数的情况。祖先组件通过 `provide` 提供属性给它的所有子树中的任何后代组件访问;而这些后代则可通过 `inject` 接收并使用这些被提供的资源[^1]。 ```javascript // 爷爷组件 GrandParent.vue <template> <div> <h2>Grand Parent Component</h2> <p>{{ message }}</p> <Child /> </div> </template> <script setup> import Child from './Child.vue' import { ref, provide } from 'vue' const message = ref('Hello from grand parent') provide('sharedMessage', message) // 将message作为可注入项暴露出去 </script> ``` ```html <!-- 孙子组件 GrandChild.vue --> <template> <div> <h3>Grand Child Component</h3> <span>Inherited Message: {{ inheritedMessage }}</span> </div> </template> <script setup> import { inject } from 'vue' const inheritedMessage = inject('sharedMessage') // 注入来自祖先的消息 </script> ``` 这种方法简单易懂,并且不会破坏组件的封装性,因为只有明确声明要接收的数据才会被接收到。 #### 方法二:利用第三方库如 mitt 创建全局事件中心 对于更复杂的场景或者当不想让多个层次嵌套的组件之间形成紧密耦合时,则可以选择创建一个独立于应用之外的事件管理器来处理这种关系。这里推荐使用轻量级的 [mitt](https://github.com/developit/mitt),它可以很好地模拟原来 Vue 2.x 的 `$bus` 功能,在不引入额外依赖的情况下完成多层甚至平级组件间的交互[^4]。 ```bash npm install mitt --save ``` ```typescript // main.ts 或者单独建立 eventBus 文件夹下 index.ts 导出 bus 对象 import mitt from 'mitt'; export const emitter = mitt(); ``` ```javascript // 爷爷组件 GrandParent.vue 发送事件 <template> <div> <button @click="sendMessage">Send Message to Grandchild</button> </div> </template> <script setup> import { onMounted } from 'vue' import { emitter } from '@/eventBus' function sendMessage() { emitter.emit('grandparent-event', { data: 'This is a message from the grandparent component.' }) } </script> ``` ```javascript // 孙子组件 GrandChild.vue 监听事件 <template> <div> <p v-if="receivedData">{{ receivedData }}</p> </div> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue' import { emitter } from '@/eventBus' let receivedData = ref(null) emitter.on('grandparent-event', ({data}) => { receivedData.value = data; }) onUnmounted(() => { emitter.off('grandparent-event'); }) </script> ``` 上述两种方法都可以有效实现祖孙组件间的通信,具体选择取决于项目的实际需求和个人偏好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JSON_L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值