ref引用信息

理想状态下并不需要访问实例,只要关心数据就行了

但是当项目越来越复杂,难免会有访问组件实例的场景


<!-- `vm.$refs.p` 是DOM节点 -->
<p ref="p">hello</p>

<!-- `vm.$refs.child` 是子组件实例 -->
<child-component ref="child"></child-component>

不要通过层层递归向上或向下引用的方式去访问实例

更建议通过 callback ref 的方式去访问实例

  • 主动通知(setXxxRef)
  • 主动获取(getXxxRef)

index.vue

<template>
  <div>
    <ChildrenA />
  </div>
</template>
<script>
import ChildrenA from "./ChildrenA";
export default {
  components: {
    ChildrenA
  }
};
</script>
<style>
.border,
.border1,
.border2 {
  border: 1px solid #000;
  padding: 10px 0;
  margin: 10px 10px 0;
}
.border1 {
  border-color: #ccc;
}
.border2 {
  border-color: #eee;
}
</style>

ChildrenA.vue

<template>
  <div class="border">
    <h1>A 结点</h1>
    <button @click="getEH3Ref">获取E h3 Ref</button>
    <ChildrenB />
    <ChildrenC />
    <ChildrenD />
  </div>
</template>
<script>
import ChildrenB from "./ChildrenB";
import ChildrenC from "./ChildrenC";
import ChildrenD from "./ChildrenD";
export default {
  components: {
    ChildrenB,
    ChildrenC,
    ChildrenD
  },
  provide() {
    return {
      setChildrenRef: (name, ref) => {
        this[name] = ref;
      },
      getChildrenRef: name => {
        return this[name];
      },
      getRef: () => {
        return this;
      }
    };
  },
  data() {
    return {
      color: "blue"
    };
  },
  methods: {
    getEH3Ref() {
      console.log(this.childrenE);
    }
  }
};
</script>

ChildrenB.vue

<template functional>
  <div class="border1">
    <h2>B 结点</h2>
  </div>
</template>

ChildrenC.vue

<template>
  <div class="border1">
    <h2>C 结点</h2>
    <ChildrenE />
    <ChildrenF />
  </div>
</template>
<script>
import ChildrenE from "./ChildrenE";
import ChildrenF from "./ChildrenF";
export default {
  components: {
    ChildrenE,
    ChildrenF
  }
};
</script>

ChildrenD.vue

<template>
  <div class="border1">
    <h2>D 结点</h2>
    <ChildrenG />
    <ChildrenH v-ant-ref="c => setChildrenRef('childrenH', c)" />
    <ChildrenI />
  </div>
</template>
<script>
import ChildrenG from "./ChildrenG";
import ChildrenH from "./ChildrenH";
import ChildrenI from "./ChildrenI";
export default {
  components: {
    ChildrenG,
    ChildrenH,
    ChildrenI
  },
  inject: {
    setChildrenRef: {
      default: () => {}
    }
  }
};
</script>

ChildrenE.vue

<template>
  <div class="border2">
    <h3 v-ant-ref="c => setChildrenRef('childrenE', c)">
      E 结点
    </h3>
  </div>
</template>
<script>
export default {
  components: {},
  inject: {
    setChildrenRef: {
      default: () => {}
    }
  }
};
</script>

ChildrenF.vue

<template>
  <div class="border2">
    <h3>F 结点</h3>
    <button @click="getARef">获取A Ref</button>
    <button @click="getHRef">获取H Ref</button>
  </div>
</template>
<script>
export default {
  components: {},
  inject: {
    getParentRef: {
      from: "getRef",
      default: () => {}
    },
    getParentChildrenRef: {
      from: "getChildrenRef",
      default: () => {}
    }
  },
  methods: {
    getARef() {
      console.log(this.getParentRef());
    },
    getHRef() {
      console.log(this.getParentChildrenRef("childrenH"));
    }
  }
};
</script>

ChildrenG.vue

<template>
  <div class="border2">
    <h3>G 结点</h3>
  </div>
</template>
<script>
export default {};
</script>

ChildrenH.vue

<template>
  <div class="border2">
    <h3>H 结点</h3>
  </div>
</template>
<script>
export default {};
</script>

ChildrenI.vue


<template functional>
  <div class="border2">
    <h3 :style="{ color: injections.theme.color }">I 结点</h3>
  </div>
</template>
<script>
export default {
  inject: {
    theme: {
      default: () => ({})
    }
  }
};
</script>

results matching ""

    No results matching ""