Vuejs.org: Any plan for docs of abstract components?

Created on 19 Jan 2017  路  9Comments  路  Source: vuejs/vuejs.org

There are several built-in abstract components, such as transition, keep-alive. However, the official guide doesn't tell the developers that they could also create their own.

Here's a possible use case. If the user's network is very good, I may want to guess his/her behavior based on some rules, and prefetch some async data or routes. So I create a prefetch abstract component. When the user really does what I have guessed, the UI could response immediately.

After read source code of the built-in abstract components, I found that there are pitfalls I didn't realize. For example, an abstract component may contain another abstract component. Then I start to worry whether I could use it the right way.

Is abstract designed to be internal only, or is there any plan for the docs?

question

Most helpful comment

Hi, I asked a question on stackoverflow related to this issue. My use case is simple. I just want to have a component which will add a property to its child component but will not change html at all.

From this:

<div id="app" class="container">
    <foo>
        <p>hello</p>
    </foo>
</div>

To this:

<div id="app" class="container">
     <p>hello</p>
</div>

All 9 comments

My understanding is that it's internal-only, but I'll ping @yyx990803 to double check.

For now it is internal only. I'm interested to see more details about your use case though, that may help validate the idea and see whether we can make it public.

I'm involved in a big data product.

  1. In the product we have some super large data grids - the list view. At this step, we couldn't guess much.
  2. When the customer clicks an item in the list, he gets to the item's highlights view - selected potion of data (1/5 roughly) that customers most concern about.
  3. According to some user behavior studies, more than 60% of customers will go on click the expando, which reveals the rest 4/5.

To be honest, there could be a way to improve the design, so does technical design. Despite that, this looks like a typical use case for prefetching data (step 2 -> 3).

Here's the sample prefetch component:

<script>
  export default {
    name: 'prefetch',
    abstract: true,
    render: () => '',
    props: ['api'],
    watch: {
      api (val) {
        if (val) {
          // Use fetch here for quick prototyping,
          // Should use cancellable method in production.
          fetch(val)
            .then(response => response.json())
            .then(data => {
              this.$store.dispatch('prefetchData', data)
            })
        }
      }
    }
  }
</script>

In root component, dataPath is a computed property based on current route:

<prefetch :api="dataPath"></prefetch>

For now, the approach is experimental. And it's definitely not the only way to achieve such functionality, a util method could also do the job. So I couldn't say I need it desperately. I'm just trying to implement the idea that everything could be a component. If abstract components are meant to be internal only, I'm still ok with it.

Hi, I asked a question on stackoverflow related to this issue. My use case is simple. I just want to have a component which will add a property to its child component but will not change html at all.

From this:

<div id="app" class="container">
    <foo>
        <p>hello</p>
    </foo>
</div>

To this:

<div id="app" class="container">
     <p>hello</p>
</div>

There's not many responses since it was opened. And it's not the only way how I could meet my development task. Close the issue.

Hi. I have run into a case where this might be pretty useful. I'm new to Vue, so there may already be a good solution for what I'm presenting. I looked through the docs and through issues and didn't see anything that might help.

I'm working on a project that uses canvas pretty extensively to draw graphs. I've worked with React where creating abstract components isn't a problem. I guess that I assumed the case would be the same in Vue (not a criticism, Vue is the cat's pajamas).

Let me explain the use case:

I'd like to make a series of components that encapsulate drawing operations to a canvas. Think: <weighted-edge>, <unidirectional-edge>, <bidirectional-edge>, <graph-node>, etc. These nodes need simply to contain the logic for drawing to the canvas, hence no rendering new DOM elements. I originally sketched out a hierarchy like so, (before I painted myself into a corner):

<canvas-stage>
    <weighted-edge v-for="edge in edges" ctx="ctx">
    <graph-node v-for="node in nodes" ctx="ctx">
    ...etc...
</canvas-stage>

The idea is that a parent component handles the canvas and passes the context down into all the child abstract components, which handle drawing. My thinking is that this might provide a simple way of managing draw layers to the canvas and for maintaining drawing operation code. If you've ever worked on a project with lots of drawing, it usually ends up a pain to maintain.

My point is that some 'view' elements aren't always DOM elements. The canvas is a pretty complex element and it'd be most excellent to use Vue components (and vuex) to manage the state of a canvas image. Having access to abstract components would make it somewhat easier to incorporate more robust drawing libraries as well.

Anywho, just my two cents.

@giodif This kind of pattern is actually very doable with Vue currently - I use it quite often. 馃檪 You can see a simple example here using MapboxGL, though in a real-world context I like to use provide/inject instead of $parent for sharing context with descendent components.

@chrisvfritz Thanks for the example, makes sense.

Not to dredge up an old topic, but a _really_ excellent use case for abstract components is if you're attempting to implement a port of the styled paradigm found in the emotion and styled-components. It's obviously trivial is you're just attempting to attach styles to a basic tag (div, span, etc), but attempting to accomplish this in Vue is currently non-trivial:

const StyledComponent = styled(ExistingComponent)`
  color: red;
  font-size: 12px;
`
Was this page helpful?
0 / 5 - 0 ratings

Related issues

sherzinger picture sherzinger  路  3Comments

webryan picture webryan  路  4Comments

andreasvirkus picture andreasvirkus  路  3Comments

meetzaveri picture meetzaveri  路  4Comments

estyh picture estyh  路  5Comments