Skip to content

Instantly share code, notes, and snippets.

@aaronhelton
Last active October 16, 2023 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaronhelton/0786f2d6c583ce570a47809f49b91395 to your computer and use it in GitHub Desktop.
Save aaronhelton/0786f2d6c583ce570a47809f49b91395 to your computer and use it in GitHub Desktop.
{% extends 'base.html' %} {% block content %}
<div id="skeleton_vm" v-show="true" data-api_prefix="{{api_prefix}}">
<div class="row">
<skeletoncomponent api_prefix="{{api_prefix}}"></skeletoncomponent>
</div>
</div>
<script type="module" src="{{url_for('static', filename='js/skeleton_vm.js')}}" ></script>
{% endblock %}
import { foocomponent } from "./foocomponent.js"
import bar from "./lib/bar.js"
export let skeletoncomponent = {
/*
Simple props declaration; A more verbose props declaration treats each prop as an object and gives you the ability to
mark the prop required, define its type, and provide default values; this is seldom necessary.
*/
props: ["api_prefix"],
/*
The template is where you create the DOM and render your data, usually in a reactive way.
Note that we are using v-for to iterate through the data properties we have (these can be anything)
and that we have also registered a click event on the span that contains the dataProp value;
we can respond to this click event in our methods below.
*/
template: `<div>
<div v-for="dataProp in sortedDataProps"><span @click="doClick($event)">{{ dataProp }}</span></div>
<!-- here we are mounting the foocomponent we imported above and registered below -->
<!-- the ref allows us to access the methods defined in foocomponent (see below for an example) -->
<!-- and :baz is a data property we can set in the current component and pass to foocomponent -->
<foocomponent ref="foo" :baz="baz"></foocomponent>
</div>`,
/*
Everything returned by the data function is reactive and can trigger page updates. You can set data properties
via methods or in the lifecycle hooks, depending on when you need that data available.
*/
data: function () {
return {
dataProps: [],
baz: ""
}
},
/*
Computed allows us to manipulate *and cache* data that exists in our Vue component. It differs from
a method in that a method is re-evaluated each time it's called. Computed values are commonly used
for sorting and filtering data for rendering in the DOM. A typical sorting example appears below.
*/
computed: {
sortedDataProps () {
return this.dataProps.sort( (a,b) => {
return a.localeCompare(b)
})
}
},
/*
Created is a lifecycle hook that is called as soon as the component is created but
before there is a DOM. Use this to initialize data that doesn't depend on the DOM.
*/
created: function () {
/*
Operations in here just fire off in the order they are encountered, but you can also
chain them together via promises or .then()
*/
// Get the dataProps, e.g., using the "bar" library we imported above
bar.getData().then( (data) => {
this.dataProps = data
})
// Also do something with foocomponent; e.g., run doFoo(), which is a method registered on foocomponent
this.$refs.foo.doFoo()
},
/*
Mounted is a lifecycle hook that is called once the component is mounted in the DOM.
Use this if you need to manipulate the DOM as soon as the component is mounted and
before the user interacts with it.
*/
mounted: function () {
/*
Operations in here just fire off in the order they are encountered, but you can also
chain them together via promises or .then()
*/
// Toggle a class from the classList of all spans on the page
for (let el of document.getElementsByTagName("span")) {
el.classList.toggle("my-class")
}
},
// Methods are all of the functions we want available to our component; via refs these can also be invoked
// from outside the component, say from another component
methods: {
// A basic method that can be called from elsewhere in the component, or from outside the component
doSomething() {
return {foo: "bar"}
},
doClick(e) {
// e contains the event we just triggered, and that in turn includes the target element, so anything that
// relies on knowing *which* element was clicked will be able to use this information
console.log(e)
console.log(e.target)
// Do something in response to the click, say, toggle the class we set above when we mounted the component
e.target.classList.toggle("my-class")
}
},
// Here we register the other components we're using in our component; these are imported at the top
components: {
'foocomponent': foocomponent
}
// There are more lifecycle hooks available for components, but created and mounted are the
// most commmonly used and should cover most use cases.
}
import { skeletoncomponent } from "./skeleton.js";
/////////////////////////////////////////////////////////////////
// VIEW MODEL DEFINITION
/////////////////////////////////////////////////////////////////
export let skeleton_vm = new Vue({
el: '#skeleton_vm',
components: { skeletoncomponent },
data: {
visible: false,
},
methods: {}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment