vue-elm-components v0.3.0
vue-elm-components
Simply embed Elm apps as components into your Vue.js applications
This package makes it easy to turn Elm code into Vue.js components.
Companies that use Elm in production usually start small. Read more about how to use Elm at work here.
Development Status
- Immediate Goals
- Add demos for Elm 0.18 and 0.19
- Add automated tests
- Coming Soon
- Interact with Elm ports using Vue.js props and events
Usage
Installation
npm i vue-elm-components
Basic Usage
If you have an Elm app, you can import it using the elm-webpack-loader and embed it in your Vue code like this:
<template>
<v-elm :src="Counter" />
</template>
<script>
import VElm from 'vue-elm-components'
import Counter from '@/path/to/file/Counter.elm'
export default {
data: { Counter },
components: { VElm }
}
</script>
Flags
Sometimes you want to give your Elm program some flags on start up. Let's say we want our counter to start at 5. You would write something like this:
<template>
<v-elm
:src="Counter"
:flags="flags"
/>
</template>
<script>
import VElm from 'vue-elm-components'
import Counter from '@/path/to/file/Counter.elm'
export default {
data: {
Counter,
flags: { start: 5 }
},
components: { VElm }
}
</script>
These flags will be given to the Elm program, allowing you to do some setup work in your Vue code first.
JavaScript/Elm Interop
As your Elm program gets fancier, you will probably need to interact with JavaScript. We do this with ports. Think of these as holes in the side of an Elm program that let you pass messages back-and-forth.
So let's say we want to extend our app to allow outsiders to modify the counter through the counter
port. And maybe we also expose the current count so that outsiders can subscribe to it using the countChanged
port. You would set it up like this:
<template>
<v-elm
:src="Counter"
:ports="setupPorts"
/>
</template>
<script>
import VElm from 'vue-elm-components'
import Counter from '@/path/to/file/Counter.elm'
export default {
data: {
Counter,
currentCount: 0,
},
methods: {
setupPorts(ports) {
ports.countChanged.subscribe((n) => {
this.currentCount = n;
});
ports.counter.send(1);
ports.counter.send(1);
}
},
components: { VElm }
}
</script>
Advanced Usage
Once the Elm component is initialized, changing the flags
and ports
properties will do nothing. So here are some tricks that may help you out:
- If you want to reinitialize your Elm component, add a different
key
to the old and new components. This way old one is destroyed and replaced by the new one. - This package is super simple. Check out the implementation and do it different if you want!
- You can also use compiled versions of your elm app (
.js
outputs) if you find it easier. - The default export from an Elm module (
.elm
or compiled to.js
) is an object which contains your app as a property. For example, you can imagine that a file namedCounter.elm
, or its compiled counterpart nameddist/counter.js
will export something like this:
export default {
Elm: {
Main: {
embed: [[Function]], // version 0.18 and prior
init: [[Function]], // since version 0.19
}
}
}
Angular, Ember, etc.
If you want to embed Elm in something else, you are in luck!
The implementation is pretty short, mostly Vue-related. The important lines are basically running the following program at the correct time:
import App from "@/path/to/file/App.elm";
var app = App.Elm.Main.embed(node, flags);
setupPorts(app.ports)
So if you are interested in embedding Elm in something else, do the same trick! You can get more complete docs on embedding Elm in JS here. Let the community know if you make something!
This package was inspired by react-elm-components which is maintained by the good folks at Culture Amp.