Vue任意组件间传值

  不知道各位对vue的理解如何,我之前学习vue的时候,就被vue组件间传值给难住了,我发现父向子可以用props,基础课也学过,子向父可以采用emits的方法,创建一个自定义方法调用,难度感觉来了,可爷孙之间呢,兄弟之间呢?

一、父子之间传值

  可以采用props的方法,具体如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@next"></script>

</head>

<body>
    <div id="root">

    </div>
    <p>子组件向父组件通信 $emit 向外传递事件</p>
    <script>
        const app = Vue.createApp({
            data() {
                return {
                    count: 1
                }
            },
            methods: {
                handleAdd( // this.count += param2;
                    count
                ) {
                    // this.count += param2;
                    this.count = count;
                }
            },

            // template: `<div><counter :count = "count"/ @add-one="handleAddOne"></div>`
            template: `<div><counter :count = "count" @add="handleAdd"/></div>`

            // @add-one="" 接收监听并执行
        });


        app.component('counter', {
            props: ['count'],

            // emits:['add','minus'],    //emits可以定义组件  起到提示左右
            emits: {                          //还可以传对象 对象中在包括函数进行更多的操作     
                add: (count) => {
                    if (count < 0) {
                        return true;
                    }
                    return false;
                }
            },

            methods: {
                handleItemClick() {
                    // this.$emit('addOne');
                    // this.$emit('add', 2,3);    //可以额外传参
                    this.$emit('add', this.count + 3);

                    // $emit 向外部传递事件
                }
            },

            template: `<div @click="handleItemClick">{
   
   {count}}</div>`
        });


        const vm = app.mount('#root');
    </script>



    <div id="root1"></div>
    <script>
        const app1 = Vue.createApp({
            data() {
                return {
                    count: 1
                }
            },
            template: `<counter v-model="count"/>`
            // template: `<counter v-model:add="count"/>`  //改名
            // 以v-model做链接 vue专属modelValue进行传值
        });


        app1.component('counter', {
            props: ['modelValue'],   //modelValue 指接收v-model传下的值 想要改命名在v-model后加:名字
            methods: {
                handleClick() {
                    // 以下写法为固定写法 update
                    this.$emit('update:modelValue', this.modelValue + 3);
                }
            },

            template: `<div @click="handleClick">{
   
   {modelValue}}</div>`
        });


        const vm1 = app1.mount('#root1');
    </script>

</body>

</html>

二、vuex传值法(任意组件)

  vuex可以认为是一个公共库,把所有可能都需要的资源保存在这,具体代码如下:

import { createStore } from 'vuex'

// VueX数据管理框架    当数据很多的时候
// VueX创建了一个全局唯一的仓库 用来存放全局的数据  注意是全局的
export default createStore({
  state: {
    name:'dell'
  },
  mutations: {
    // 第四步 mutations感知到change改变 执行改变
    change() {
      // 第五步 改变数据
      this.state.name = 'lee'
    }

  },
  actions: {
    // 第二步 store感知你派发了一个叫做change的action 执行change方法
    change() {
      // 第三步 提交一个commit 来触发一个mutation 即数据改变的请求
      this.commit('change')
    }

  },
  modules: {
    // modules是对store更复杂的拆分
  }
})

三、provide和inject方法

  适用于爷孙,代码如下:

组件一

<template>
	<div class="child">
		<h3>我是Child组件(子)</h3>
		<Son/>
	</div>
</template>

<script>
	import {inject} from 'vue'
	import Son from './Son.vue'
	export default {
		name:'Child',
		components:{Son},
		/* setup(){
			let x = inject('car')
			console.log(x,'Child-----')
		} */
	}
</script>

<style>
	.child{
		background-color: skyblue;
		padding: 10px;
	}
</style>

组件二

<template>
	<div class="son">
		<h3>我是Son组件(孙),{
   
   {car.name}}--{
   
   {car.price}}</h3>
	</div>
</template>

<script>
	import {inject} from 'vue'
	export default {
		name:'Son',
		setup(){
			let car = inject('car')
			return {car}
		}
	}
</script>

<style>
	.son{
		background-color: orange;
		padding: 10px;
	}
</style>

主app

<template>
	<div class="app">
		<h3>我是App组件(祖),{
   
   {name}}--{
   
   {price}}</h3>
		<Child/>
	</div>
</template>

<script>
	import { reactive,toRefs,provide } from 'vue'
	import Child from './components/Child.vue'
	export default {
		name:'App',
		components:{Child},
		setup(){
			let car = reactive({name:'奔驰',price:'40W'})
			provide('car',car) //给自己的后代组件传递数据
			return {...toRefs(car)}
		}
	}
</script>

<style>
	.app{
		background-color: gray;
		padding: 10px;
	}
</style>

方法四、minix或hook函数

  该方法也可以用来组件间传值,即共调用一个方法或数据

  hook

//hook

import {reactive,onMounted,onBeforeUnmount} from 'vue'
export default function (){
	//实现鼠标“打点”相关的数据
	let point = reactive({
		x:0,
		y:0
	})

	//实现鼠标“打点”相关的方法
	function savePoint(event){
		point.x = event.pageX
		point.y = event.pageY
		console.log(event.pageX,event.pageY)
	}

	//实现鼠标“打点”相关的生命周期钩子
	onMounted(()=>{
		window.addEventListener('click',savePoint)
	})

	onBeforeUnmount(()=>{
		window.removeEventListener('click',savePoint)
	})

	return point
}
<-- hook app -->
<template>
	<button @click="isShowDemo = !isShowDemo">切换隐藏/显示</button>
	<Demo v-if="isShowDemo"/>
	<hr>
	<Test/>
</template>

<script>
	import {ref} from 'vue'
	import Demo from './components/Demo'
	import Test from './components/Test'
	export default {
		name: 'App',
		components:{Demo,Test},
		setup() {
			let isShowDemo = ref(true)
			return {isShowDemo}
		}
	}
</script>

  mixin方法类似,都是封装成一个库,在引入调用。

猜你喜欢

转载自blog.csdn.net/qq_63438888/article/details/127112635
今日推荐