父传子
父组件给子组件传值
App.vue
<template>
<div class="container">
<Son :money="money" />
<h1>App</h1>
{{ money }}
</div>
</template>
<script>
import { ref } from "vue";
import Son from "./Son.vue";
export default {
name: "App",
components: {
Son,
},
setup() {
const money = ref(10);
return { money };
},
};
</script>
Son.vue
<template>
<div class="container">
<h1>Son</h1>
{{ money }}
</div>
</template>
<script>
export default {
name: "Son",
props: {
money: {
type: Number,
default: 0,
},
},
setup(props) {
console.log(props.money);
},
};
</script>
子传父
App.vue
<template>
<div class="container">
<Son @changeMoney="newMoney" />
<h1>App</h1>
{{ money }}
</div>
</template>
<script>
import { ref } from "vue";
import Son from "./Son.vue";
export default {
name: "App",
components: {
Son,
},
setup() {
const money = ref(10);
const newMoney = (change) => {
console.log(change); // 50
};
return { money, newMoney };
},
};
</script>
Son.vue
<template>
<div class="container">
<h1>Son</h1>
{{ money }}
</div>
</template>
<script>
export default {
name: "Son",
props: {
money: {
type: Number,
default: 0,
},
},
setup(props, { emit }) {
emit("change-money", 50);
},
};
</script>
依赖注入
provide
函数提供数据和函数给后代组件使用
inject
函数给当前组件注入provide
提供的数据和函数
App.vue
<template>
<div class="container">
<h1>App {{ money }} <button @click="sendMoney">sendMoney</button></h1>
<Son />
</div>
</template>
<script>
import { provide, ref } from "vue";
import Son from "./Son.vue";
export default {
name: "App",
components: {
Son,
},
setup() {
const money = ref(10);
// 将数据提供给后代组件
provide("CNY", money);
// 修改数据
const changeMoney = (v) => {
money.value = v;
};
provide("changeMoney", changeMoney);
const sendMoney = () => {
money.value += 1;
};
return { money, sendMoney };
},
};
</script>
Son.vue
<template>
<div class="container">
<h2>Son {{ money }}</h2>
<grand-son />
</div>
</template>
<script>
import { inject } from "vue";
import GrandSon from "./GrandSon.vue";
export default {
components: { GrandSon },
name: "Son",
setup() {
const money = inject("CNY");
return { money };
},
};
</script>
GrandSon.vue
<template>
<div class="container">
<h3>GrandSon {{ money }}</h3>
<button @click="fn">9999 money</button>
</div>
</template>
<script>
import { inject } from "@vue/runtime-core";
export default {
setup() {
const money = inject("CNY");
const changeMoney = inject("changeMoney");
const fn = () => {
changeMoney(9999);
};
return { money, fn };
},
};
</script>
v-model 语法糖
v-model在vue2.x中的使用方式
我们首先看一下vue2.x中v-model
的使用。
<ChildComponent v-model = "title />
它实际上是下面这种写法的简写:
<ChildComponent :value = "title" @input = "title = $event" />
也就是说,它实际上是传递一个属性value
,然后接收一个input
事件。
下面这种写法
<Son :modelValue="count" @update:modelValue="count = $event" />
可以简写成
<Son v-model="count" />
App.vue
<template>
<div class="container">
<h1>App {{ count }}</h1>
<!-- <Son :modelValue="count" @update:modelValue="count = $event" /> -->
<Son v-model="count" />
</div>
</template>
<script>
import { ref } from "vue";
import Son from "./Son.vue";
export default {
name: "App",
components: {
Son,
},
setup() {
const count = ref(10);
return { count };
},
};
</script>
Son.vue
<template>
<div class="container">
<h2>Son {{ modelValue }} <button @click="fn">change count</button></h2>
</div>
</template>
<script>
export default {
name: "Son",
props: {
modelValue: {
type: Number,
default: 0,
},
},
setup(props, { emit }) {
const fn = () => {
emit("update:modelValue", 100);
};
return { fn };
},
};
</script>
mixin
混入 (mixin) 提供了一种非常灵活的方式,来分发Vue组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
全局混入
每个组件都会混入
import { createApp } from "vue";
import App from './App.vue';
const app = createApp(App)
app.mixin({
// 在DOM准备好之后打印一句话
mounted() {
// $el 组件的根元素
console.log(this.$el, "DOM准备好了");
}
})
app.mount('#app')
局部混入
实现一个关注功能
mixins.js
// 关注
export const followMixin = {
data() {
return {
loading: false,
_disabled: false
}
},
methods: {
followFn() {
this._disabled = true
// 模拟请求
setTimeout(() => {
this.loading = !this.loading
this._disabled = false
}, 2000)
}
}
}
App.vue
<template>
<div class="container">
<h1>
App
<button @click="followFn" :disabled="_disabled">
{{ loading ? "已关注" : "关注" }}
</button>
</h1>
<Son />
</div>
</template>
<script>
import Son from "./Son.vue";
import { followMixin } from "./mixins";
export default {
name: "App",
components: {
Son,
},
mixins: [followMixin],
};
</script>
Son.vue
<template>
<div class="container">
<h1>
Son
<button @click="followFn" :disabled="_disabled">
{{ loading ? "已关注" : "关注" }}
</button>
</h1>
</div>
</template>
<script>
import { followMixin } from "./mixins";
export default {
name: "Son",
mixins: [followMixin],
};
</script>