# 1.provide & inject 基本使用
vue | // App |
| <template> |
| <div> |
| <h2>-------------App--------------</h2> |
| <h2>App name: {{ name }}</h2> |
| <h2>App age: {{ age {{</h2> |
| <h2>-------------Home--------------</h2> |
| <home /> |
| </div> |
| </template> |
| |
| <script> |
| import { provide } from "vue"; |
| |
| import Home from "./Home.vue"; |
| |
| export default { |
| components: { |
| Home, |
| }, |
| setup() { |
| const name = "Nekoaimer"; |
| let age = 16; |
| |
| provide("name", name); |
| provide("age", age); |
| |
| return { |
| name, |
| age, |
| }; |
| }, |
| }; |
| </script> |
| |
| <style scoped></style> |
vue | // Home |
| <template> |
| <div> |
| <h2>Home:{{ name }}</h2> |
| <h2>Home:{{ age }}</h2> |
| </div> |
| </template> |
| |
| <script> |
| import { inject } from "vue"; |
| |
| export default { |
| setup() { |
| const name = inject("name"); |
| let age = inject("age"); |
| |
| return { |
| name, |
| age, |
| }; |
| }, |
| }; |
| </script> |
| |
| <style scoped></style> |
参考结果:
# 2. 不是响应式
vue | // App |
| <template> |
| <div> |
| <h2>-------------App--------------</h2> |
| <h2>App name: {{ name }}</h2> |
| <h2>App age: {{ age }}</h2> |
| <button @click="appIncrement">App+1</button> |
| <h2>-------------Home--------------</h2> |
| <home /> |
| </div> |
| </template> |
| |
| <script> |
| import { provide } from "vue"; |
| |
| import Home from "./Home.vue"; |
| |
| export default { |
| components: { |
| Home, |
| }, |
| setup() { |
| const name = "Nekoaimer"; |
| let age = 16; |
| const appIncrement = () => { |
| age++; |
| console.log("App", age); |
| }; |
| provide("name", name); |
| provide("age", age); |
| |
| return { |
| name, |
| age, |
| appIncrement, |
| }; |
| }, |
| }; |
| </script> |
| |
| <style scoped></style> |
vue | // Home |
| <template> |
| <div> |
| <h2>{{ name }}</h2> |
| <h2>{{ age }}</h2> |
| |
| <button @click="homeIncrement">home+1</button> |
| </div> |
| </template> |
| |
| <script> |
| import { inject } from "vue"; |
| |
| export default { |
| setup() { |
| const name = inject("name"); |
| let age = inject("age"); |
| |
| const homeIncrement = () => { |
| age++; |
| console.log("Home:", age); |
| }; |
| |
| return { |
| name, |
| age, |
| homeIncrement, |
| }; |
| }, |
| }; |
| </script> |
| |
| <style scoped></style> |
参考结果:数据已经改变但页面显示没有变化
# 3. 使用 ref 响应式
vue | // App |
| <template> |
| <div> |
| <h2>-------------App--------------</h2> |
| <h2>App name: {{ name }}</h2> |
| <h2>App age: {{ age }}</h2> |
| <button @click="appIncrement">App+1</button> |
| <h2>-------------Home--------------</h2> |
| <home /> |
| </div> |
| </template> |
| |
| <script> |
| import { provide, ref } from "vue"; |
| |
| import Home from "./Home.vue"; |
| |
| export default { |
| components: { |
| Home, |
| }, |
| setup() { |
| const name = ref("Nekoaimer"); |
| let age = ref(16); |
| const appIncrement = () => { |
| age.value++; |
| console.log("App", age); |
| }; |
| provide("name", name); |
| provide("age", age); |
| |
| return { |
| name, |
| age, |
| appIncrement, |
| }; |
| }, |
| }; |
| </script> |
| |
| <style scoped></style> |
vue | // Home |
| <template> |
| <div> |
| <h2>{{ name }}</h2> |
| <h2>{{ age }}</h2> |
| |
| <button @click="homeIncrement">home+1</button> |
| </div> |
| </template> |
| |
| <script> |
| import { inject } from "vue"; |
| |
| export default { |
| setup() { |
| const name = inject("name"); |
| let age = inject("age"); |
| |
| const homeIncrement = () => { |
| age.value++; |
| console.log("Home:", age); |
| }; |
| |
| return { |
| name, |
| age, |
| homeIncrement, |
| }; |
| }, |
| }; |
| </script> |
| |
| <style scoped></style> |
参考结果:但是不推荐子组件也能改父组件的数据
# 4. 使用 readonly 单向管理
向子组件传值尽量用 readonly
vue | // App |
| <template> |
| <div> |
| <h2>-------------App--------------</h2> |
| <h2>App name: {{ name }}</h2> |
| <h2>App age: {{ age }}</h2> |
| <button @click="appIncrement">App+1</button> |
| <h2>-------------Home--------------</h2> |
| <home /> |
| </div> |
| </template> |
| |
| <script> |
| import { provide, ref, readonly } from "vue"; |
| |
| import Home from "./Home.vue"; |
| |
| export default { |
| components: { |
| Home, |
| }, |
| setup() { |
| const name = ref("Nekoaimer"); |
| let age = ref(16); |
| const appIncrement = () => { |
| age.value++; |
| console.log("App", age); |
| }; |
| provide("name", readonly(name)); |
| provide("age", readonly(age)); |
| |
| return { |
| name, |
| age, |
| appIncrement, |
| }; |
| }, |
| }; |
| </script> |
| |
| <style scoped></style> |
vue | // Home |
| <template> |
| <div> |
| <h2>{{ name }}</h2> |
| <h2>{{ age }}</h2> |
| |
| <button @click="homeIncrement">home+1</button> |
| </div> |
| </template> |
| |
| <script> |
| import { inject } from "vue"; |
| |
| export default { |
| setup() { |
| const name = inject("name"); |
| let age = inject("age"); |
| |
| const homeIncrement = () => { |
| age.value++; |
| console.log("Home:", age); |
| }; |
| |
| return { |
| name, |
| age, |
| homeIncrement, |
| }; |
| }, |
| }; |
| </script> |
| |
| <style scoped></style> |
参考结果: