前端系列十四:Vue3获取DOM跟传值

本文详细介绍了如何在Vue3中通过ref获取DOM元素,父子组件间的数据传递方法,并对比了v-model在Vue3中的新变化。涵盖了响应式数据ref的使用、props传递和自定义事件emit的应用。

Vue3里获取dom

获取单个元素
    先定义一个空的响应式数据ref定义的
    setup中返回数据,你想获取那个dom元素, 在改元素上使用red属性

    setup( ) {
    const dom = ref( null )
    onMounted( ( ) => {
    console.log( dom.value )
    } )
    }

Vue3里获取父子props传过来的值,并打印出来

写法:
    props:{
        money: {
         type:Number,
         default: 0
       }
    }
    
    setup( props ) {
    //获取父组件数据money
    console.log( props.monery )
    }


        子传父
    触发自定义事件的时候emit来自 setup( props,( emit ) ){ emit就是触发事件函数 }

区别五:

    在Vue2中的另外一种实现双向绑定方式 v-model和.sync,在Vue3里已经合并,
    成v-mdeol指令

<think>我们正在讨论Vue3中组件之间的方式。根据提供的引用,我们可以总结出几种常见的方式: 1. 使用Props(父子):父组件通过属性绑定向子组件递数据,子组件通过props接收。 2. 使用自定义事件(子父):子组件通过触发自定义事件,父组件监听该事件并更新数据。 3. 使用`useAttrs`(父子):Vue3中提供了`useAttrs`函数,可以获取父组件递的所有属性(包括事件),类似于Vue2中的`$attrs`和`$listeners`。 4. 通过父组件作为中介(兄弟组件通信):例如,子组件A通过事件将数据给父组件,父组件再通过props将数据递给子组件B。 此外,Vue3还有其他方式,比如: 5. 使用provide/inject(祖先组件向后代组件):适用于跨层级组件通信。 6. 使用Vuex/Pinia(状态管理):全局状态管理,任意组件之间都可以通信。 7. 使用事件总线(Event Bus):但Vue3中移除了$on、$off等方法,可以使用第三方库如mitt来实现。 8. 使用ref获取子组件实例:父组件通过ref获取子组件的实例,然后直接调用子组件的方法或访问数据。 下面我们根据引用中的示例,详细说明几种方式: 一、Props(父子) 引用[2]和引用[3]都展示了Props的用法。父组件在子组件标签上绑定属性,子组件通过props选项接收。 父组件: ```vue <template> <son :isShow="data.isShow"></son> </template> <script> import son from &#39;../components/son.vue&#39; import { reactive } from &#39;vue&#39; export default { components: { son }, setup() { let data = reactive({ isShow: false }); return { data } } } </script> ``` 子组件: ```vue <template> <div class="menu">{{ isShow }}</div> </template> <script> export default { props: { isShow: Boolean }, setup(props) { // 使用props.isShow } } </script> ``` 二、自定义事件(子父) 引用[5]展示了子组件触发事件,父组件监听事件并处理。 子组件A(ChildA): 假设在ChildA中触发一个事件,递数据给父组件: ```vue <script setup> import { defineEmits } from &#39;vue&#39; const emits = defineEmits([&#39;value-changed&#39;]) // 某个方法中触发事件 function changeValue() { emits(&#39;value-changed&#39;, &#39;new value&#39;) } </script> ``` 父组件: ```vue <template> <ChildA @value-changed="handleValueChanged" /> <ChildB :value="valueFromChildA" /> </template> <script> import { ref } from &#39;vue&#39; export default { setup() { const valueFromChildA = ref(&#39;&#39;) function handleValueChanged(value) { valueFromChildA.value = value } return { handleValueChanged, valueFromChildA } } } </script> ``` 三、useAttrs(父子) 引用[1]提到,在Vue3中可以使用`useAttrs`来获取父组件递的属性和事件(包括自定义事件和原生事件)。 子组件: ```vue <script setup> import { useAttrs } from &#39;vue&#39; const attrs = useAttrs() // attrs包含了父组件递过来的所有属性和事件(除了子组件已声明的props) </script> ``` 四、provide/inject(跨层级) 没有在引用中直接出现,但也是Vue3中常用的方式。 祖先组件: ```vue <script setup> import { provide } from &#39;vue&#39; provide(&#39;key&#39;, &#39;value&#39;) </script> ``` 后代组件: ```vue <script setup> import { inject } from &#39;vue&#39; const value = inject(&#39;key&#39;) </script> ``` 五、兄弟组件通信(通过父组件中转) 如引用[5]所示,子组件A通过事件给父组件,父组件再通过props给子组件B。 六、使用ref获取子组件实例 父组件可以通过ref获取子组件的实例,然后直接访问子组件的属性或方法。 父组件: ```vue <template> <Child ref="childRef" /> </template> <script setup> import { ref } from &#39;vue&#39; const childRef = ref(null) // 在需要的时候访问子组件 function callChildMethod() { childRef.value.childMethod() } </script> ``` 子组件需要暴露方法: ```vue <script setup> import { defineExpose } from &#39;vue&#39; function childMethod() { // ... } defineExpose({ childMethod }) </script> ``` 七、使用事件总线(Event Bus) 可以使用第三方库mitt: 安装mitt:`npm install mitt` 创建事件总线(eventBus.js): ```js import mitt from &#39;mitt&#39; const emitter = mitt() export default emitter ``` 组件A(发送事件): ```js import emitter from &#39;./eventBus&#39; emitter.emit(&#39;event-name&#39;, data) ``` 组件B(接收事件): ```js import emitter from &#39;./eventBus&#39; emitter.on(&#39;event-name&#39;, (data) => { // 处理数据 }) ``` 八、使用状态管理(Vuex或Pinia) 这里以Pinia为例(Vue3官方推荐的状态管理库): 创建store,然后在任何组件中导入使用。 以上是Vue3中组件的常见方式,根据不同的场景选择合适的方式。 相关问题: 1. Vue3中如何实现跨层级组件? 2.Vue3中,如何通过ref获取子组件实例并调用其方法? 3. Vue3中如何使用事件总线(Event Bus)进行组件通信? 4. Vue3的Props和Vue2有什么不同之处? 5.Vue3的setup语法糖中,如何定义props和emits? </think>在 Vue 3 中,组件主要有以下 7 种方式,结合引用内容说明如下: ### 一、Props 父子(最常用) ```vue <!-- 父组件 Parent.vue --> <template> <Child :msg="message" /> </template> <script setup> import Child from &#39;./Child.vue&#39; const message = ref(&#39;Hello from parent&#39;) </script> <!-- 子组件 Child.vue --> <template> <div>{{ msg }}</div> </template> <script setup> defineProps({ msg: { type: String, default: "" } }) </script> ``` **特点**:单向数据流,类型验证,需显式声明接收[^3][^4] ### 二、自定义事件(子父) ```vue <!-- 子组件 Child.vue --> <template> <button @click="sendData">递数据</button> </template> <script setup> const emit = defineEmits([&#39;data-change&#39;]) const sendData = () => emit(&#39;data-change&#39;, { value: 123 }) </script> <!-- 父组件 Parent.vue --> <template> <Child @data-change="handleData" /> </template> <script setup> const handleData = (payload) => console.log(payload.value) // 123 </script> ``` **特点**:通过`defineEmits`声明事件,`emit()`触发[^5] ### 三、useAttrs(透属性/方法) ```vue <!-- 父组件 --> <Child @click="handleClick" title="提示文本" /> <!-- 子组件 --> <script setup> import { useAttrs } from &#39;vue&#39; const attrs = useAttrs() console.log(attrs.title) // "提示文本" // 可访问所有透属性和事件(含原生DOM事件) </script> ``` **特点**:获取未在 props 中声明的属性和事件,类似 Vue2 的`$attrs`[^1] ### 四、v-model 双向绑定 ```vue <!-- 父组件 --> <Child v-model:name="userName" /> <!-- 子组件 --> <script setup> defineProps([&#39;name&#39;]) defineEmits([&#39;update:name&#39;]) const update = () => emit(&#39;update:name&#39;, &#39;newValue&#39;) </script> ``` **特点**:Vue3 支持多个`v-model`绑定(如`v-model:first-name`) ### 五、provide/inject(跨级通信) ```vue <!-- 祖先组件 --> <script setup> import { provide } from &#39;vue&#39; provide(&#39;globalToken&#39;, &#39;auth_key&#39;) </script> <!-- 后代组件 --> <script setup> import { inject } from &#39;vue&#39; const token = inject(&#39;globalToken&#39;) // &#39;auth_key&#39; </script> ``` **特点**:解决多级组件数据递问题 ### 六、ref 获取组件实例 ```vue <!-- 父组件 --> <template> <Child ref="childRef" /> </template> <script setup> import { ref } from &#39;vue&#39; const childRef = ref(null) childRef.value.childMethod() // 调用子组件方法 </script> <!-- 子组件 Child.vue --> <script setup> defineExpose({ // 暴露方法 childMethod: () => console.log(&#39;方法被调用&#39;) }) </script> ``` **特点**:需子组件用`defineExpose`显式暴露 ### 七、状态管理(Pinia/Vuex) ```js // store.js import { defineStore } from &#39;pinia&#39; export const useStore = defineStore(&#39;main&#39;, { state: () => ({ count: 0 }) }) // 任意组件 const store = useStore() store.count++ // 全局共享状态 ``` **特点**:复杂应用推荐方案 --- ### 选择建议 1. **父子组件**:Props + 自定义事件 2. **兄弟组件**:通过共同父组件中转 或 Pinia 3. **跨层级**:provide/inject 4. **模板透**:useAttrs 5. **双向绑定**:v-model 6. **全局状态**:Pinia > 注:Vue3 移除`$listeners`,相关功能已整合到`useAttrs`中[^1]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值