Code Monkey home page Code Monkey logo

vue-hoc's People

Contributors

austio avatar dependabot[bot] avatar jackmellis avatar preusx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

vue-hoc's Issues

Optimise processOptions

Much of process options can be worked out statically with a preprocess function, which would cut down on work during rendering

named slots don't work correctly

Currently if you create a HOC around a component that has named slots, all of the provided slots will be converted into default slots.

So instead of having

{
  default: [ vNode ],
  header: [ vNode ],
  footer: [ vNode ],
}

you get

{
  default: [ vNode, vNode, vNode ],
}

normalizeSlots should only be normalizing default slots. And I guess we should be doing something with scopedSlots instead...

renderNothing

basically just a shortcut for createSink(() => {})?

connect

Effectively just a wrapper for withState + withHandlers + mapProps

Extra <template> tags

I wish to make a withStyle HOC component to style my components.

import { createHOCc } from 'vue-hoc';

export function withStyle(style) {
  return createHOCc(null, {style});
};

Then I used it this way to create a red button:

import {withStyle} from '../HOC/withStyle.js';

const style = {
  background: '#F00'
};

export default withStyle(style)('button');

The issue appears when I try to render it:

import euiButton from '../UI/styledButton.jsx';

export default {
  components: {
    styledButton
  },

  render() {
    return (
      <v-app>
        <v-content>
          Hello World
          <styledButton>MyButton</styledButton>
        </v-content>
      </v-app>
    );
  }
};

In the dom, an extra pair of <template> is created:

screenshot at 2018-03-27 11-49-14

And my button doesn't appear.

Why is this occurs ?

Thanks

Possible to wrap the contents of a slot?

I'm extending a data table component. I'd like to be able for a HOC that wraps the table's "no-data" slot with an alert tag and a td tag, so I don't have to write the same wrapping tags constantly. Is this possible? I tried to modify the slots in the renderWith options, but it didn't seem to take effect.

Props are rendered to the DOM

Whenever a prop is attached to a HOC, it is rendered to the DOM. For example, if I'm using a HOC for Vuetify's VDataTable component, I see this if I inspect the DOM:

<div data-v-a0f8bd1c="" items="[object Object],[object Object],[object Object],[object Object]" pagination="[object Object]" hide-actions="" must-sort="">
...

Is there any way do avoid this?

Error normalizing slots with multiple rows

If a component has multiple slots i..e

<foo>
  <span>a</span>
  <span>b</span>
</foo>

currently it will cut one of those slots. Needs to be something like:

if (isTextNode(vnode)) {
          slots[key][i] = context.$createElement('template', { slot: key }, [vnode]);
        } else {
          slots[key][i].context = context;

On top of this, it looks like having elements and text content at the root slot level does not work nicely either. i.e.

<foo>
  <span>a</span> b
</foo>

Looks like the b will be lost...

Listen to slot events?

Not sure if this is possible but see if we can intercept emit calls from a componentFromSlot component

Directives don't work with functional HOCs?

I'm using Vuetify's VSelect component and wrapping it with some custom prop defaults. If the HOC is functional, the v-validate (via VeeValidate) directive doesn't work. Removing functional: true makes the validation work again. Is this a bug or a technical limitation?

Loses class and other passed attributes

I've noticed that createHOC looses data.attributes in produced components which leads to loosing class and other attributes in actual DOM.
E.g.

 export const BackBtn = createHOC(IconBtn, {
  name: 'BackBtn',
  functional: true,
  // render (h, ctx) {
  //   return h(IconBtn, { ...ctx.data, props: { ...ctx.props, icon: 'arrow_back' } })
  // }
}, {
  props: { icon: 'arrow_back' }
})

When using in template like

<back-btn class="green--text"></back-btn>

Does not include class green-text
But when defined like:


export const BackBtn = createHOC({}, {
  name: 'BackBtn',
  functional: true,
  render (h, ctx) {
    return h(IconBtn, { ...ctx.data, props: { ...ctx.props, icon: 'arrow_back' } })
  }
})

It does.

create interim modules

In registerModule, if you try to register foo/bah/baz when foo or bah haven't already been registered, it fails.

I think we should recursively check each part of the path and if it doesn't exist, create an empty module to contain it.

Provide/Inject

Basically a shortcut for adding an object property or a provide function to a component.

provide(() => ({ foo: 'bah' }))
inject([ 'foo' ])

can not get full props in Componet.props

vue-hoc/src/createHOC.js

Lines 25 to 27 in ec91d6b

props: normalizeProps((typeof Component === 'function')
? Component.options.props
: Component.props),

You can not get full props in Componet.props due to the exist of mixin or extend.
But props can pass to the inner Component correctly by process options in running time.
So should we remove these lines?

Named slots problem and my solution

In order to create hoc with named slots, we should let the expression to be true:

// vue/src/core/instance/render-helpers/resolve-slots.js
if ((child.context === context || child.functionalContext === context) &&
      data && data.slot != null
    ) {
  ...
}

So I saw vue-hoc did two things:

// 1.
created(){
  this.$createElement = this.$parent.$createElement;
}

// 2.
normalizeSlots(this.$slots, this.$parent)

But sometimes, it didn't work because of the hoc's $parent is not it's $vnode.context.

Although I don't known why, but I tried to fix it by:

// 1.
created() {
  this.$createElement = this.$vnode.context.$createElement
  this._c = this.$vnode.context._c
}

// 2.
normalizeSlots(this.$slots, this.$vnode.context)

It works!

So, is this the correct way to solve this, or am I lost some special case.

branch falseFn shared between calls with different components

If there is no falseFn provided to branch HOC, it creates new one by wrapping the render function of provided Component. Problem is that first wrapped render function shared between subsequent branch hoc calls despite each call provided with another component.

Consider that example:

const withLoader = branch(p => p.loading, h => h(Loading))

const C1WithLoader = withLoader(C1) //C1 is some component
const C2WithLoader = withLoader(C2) //C2 is some other component

// somewhere in a code
template: `<div><C1/> <C2/></div>` // I expect C1 and C2 rendered properly

now when I render C1WithLoader and C2WithLoader I would expect them to use render functions from C1 and C2 accordingly. But instead, render function for C1 will be called for both components, which lead to unexpected results.

Problem is in this line:
https://github.com/jackmellis/vue-hoc/blob/master/packages/vue-compose/src/hocs/branch.js#L6

as falseFn exists in outer scope, it will work only for the first time, and then any next call with another ctor will reuse that function.

I can create PR for that problem if desired.

Merge props

Rather than just assigning the options to the hoc object, loop through each option and use Vue.config.mergingStrategies to merge them. If no strategy exists, just assume latest wins.

Pass props as attributes

Right now if you pass a prop into a child component, but that prop is not recognised, it is just abandoned. It would be good if any unknown props could be merged into attrs

[Question] Any way to access computed porperty of original component.

Thank you for the awesome work.

I am trying to access a computed property of the original component. Here is the code

import SourceComponent from '...';

const options = {
  methods: {
     myFunc() {
         console.log('computedRows', this.computedRows);
     }
  }
}

export default createHOC(SourceComponent, options, {});

Where computedRows is a computed property in the Source component. But the console line above prints undefined.

Make it work with properties added in the created method

I'm trying to make a HOC for debounced input. I'm using the same technique shown in the vue.js guide.

However, the method added to this in the created method does not seem to be available.

Error in the console: TypeError: this.debouncedInput is not a function

Relevant code:

import { createHOCc } from 'vue-hoc'
import { debounce } from 'lodash'

const withDebouncedInput = createHOCc(
  {
    methods: {
      input(value) {
        this.$emit('debounced-input', value)
      },
      created() {
        this.debouncedInput = debounce(this.input, 500)
      },
    },
  },
  {
    listeners: {
      input(arg) {
        this.$emit('input', arg)
        this.debouncedInput(arg)
      },
    },
  }
)

branch

(
  test: Function,
  trueRender: Function,
  falseRender?: Function,
) => (Component) => Component

example:

branch(
  (props) => props.foo === true, // or function(){ this.foo === true }
  // if true
  (h) => {
    return h('div');
  }
  // if false
  function(h){
    return h('span');
  }
)(Component)

slightly restricted as you can't provide an entirely new component to instantiate so you're forced to just provide a render function. Fine if you're using jsx or pure renders, but not if you're used to template syntax...

Mixin props applied in wrong order

This is related to issue #25

I'm using a HOC around Vuetify's VDataTable component. VDataTable uses a mixin called data-iterable, which has a customFilter prop. However, VDataTable overrides this prop with its own customFilter prop.

Normal behavior is for a component to override the props of their included mixins. However, when creating my HOC, I noticed my custom component actually inherits the customFilter prop from the data-iterable mixin, not the VDataTable component.

This seems to happen because the getProps method uses the component's props as the initial value when running mixins.reduce(). This means props are being overridden in exactly the opposite way that they should.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.