不知道各位对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方法类似,都是封装成一个库,在引入调用。