How to import HTMX variable? - htmx

I am using HTMX attributes on some dynamically generated DOM elements. HTMX is not working, as stated in the docs unless you call htmx.process().
When I tried to call this, I get - correctly - the error:
Uncaught ReferenceError: htmx is not defined
Any idea how I can import this htmx variable? No idea how the example in the docs can work.
Thx!

The non-module version of htmx.org defines a global, but you're using modules (via import). Half the point of modules is to do away with globals, and so the module version of it won't create a global, it'll return an export.
In a deleted comment you said the actual import is import "htmx.org" (not import htmx.org as in the comment that's still there). That being the case, you likely want one of these:
// Importing the default export
import htmx from "htmx.org";
// Or importing the module namespace object
import * as htmx from "htmx.org";
// Or importing a named export, but looking at the file I doubt you want this one
import { htmx } from "htmx.org";
Most likely, you want the first one.
You'd do that in the module where you're doing the htmx.process() call.

In your HTML file, after including Htmx, listen for the load event.
E.g. to enable logging:
<script>
document.body.addEventListener('htmx:load', function (evt) {
htmx.logAll();
});
</script>

Related

Gridsome: How to add Vue.use(MyPlugin) for a single page only?

I have added ReCaptcha plugin using Vue.use(ReCaptcha, {some options}) in Gridsome main.js which is displaying on all pages.
How to add plugin for a particular page only in gridsome?
I've never used ReCaptcha or Gridsome before, but generally, if you install a plugin using npm, then the simplest way to use it on a single page would be to import the plugin to the specific component rendered on the route you want to use it on. i.e
/* === MyComponent.vue === */
<script>
import plugin from 'packageName';
// or
import { pluginExport } from 'packageName';
export Default{
// You can then use the plugin/pluginExport here
}
From there you should be able to use the package in that specific component as you normally would if you implemented it app-wide with Vue.use. In some cases, depending on how the plugin is meant to be used, you may need to register the imported plugin Module as a child component in the components object. Like this vuejs QR Code generator for example.

Is it possible to use ag-grid with vue without a builder?

In particular, can the typescript source of the ag-grid-vue component be compiled then included in a regular html file?
I found a way to do this without modifying the source. Near the top of ag-grid-vue.umd.js, you can see that the module does this:
root["ag-grid-vue"] = factory(root["Vue"], root["agGrid"]);
Here, "root" is the window, and the result of the factory call is what you'll want. But due to the dashes, you can't access it directly. But you can use the dictionary syntax (or whatever it's called):
let agVueObj = window["ag-grid-vue"];
//The component is a field on this object:
let AgGridVue = agVueObj.AgGridVue;
//Then register it as a component in your Vue instance:
//components: { AgGridVue }
And you should be able to use <ag-grid-vue> tags.
I figured it out:
Download the ag-grid source code, go into the packages/ag-grid-vue directory and do npm install and npm run build. That will put compiled javascript modules in the dist directory that can be used without a build system.
I did have to modify the built javascript slightly to get the AgGridVue object into the global namespace, since I'm not using a module loader.
EDIT:
To get the AgGridVue into the global namespace, add window.AgGridVue = AgGridVue; to the end of the function that returns AgGridVue in ag-grid-vue.umd.js

How to lazy load a plugin in Vue?

Vue plugins usually requires a global setup in app entrypoint by Vue.use(somePlugin). Doing so increases the bundle size for all pages, which is often bad and that it is better to defer the downloading of the module until when the module is actually being used, aka lazy loading or code spliting.
How do I lazy load a plugin if only one page in my Vue app needs it?
To answer the OP's question more directly: You can't lazy load a plugin.
According to the documentation, plugins by definition provide globally-accessible functionality and must be setup with Vue.use() before the Vue instance is created. Due to this, they'll always be bundled with the entire Vue instance (in a vendors chunk, for example).
What you want is to lazy load the functionality in a smaller scope, at a component level. Depending on the plugin, the plugin module should also support some sort of direct code importing at a component level, like this one does. Because it just uses import statements, they can be async loaded.
TL;DR: Anything using Vue.use() can't be lazy loaded. Async imports can.
One of the options is to call your plugin file in created/mounted hook and do the stuff you want.
Just import it on the specific page an example would be "Slide" from "vue-burger-menu"
<script>
import { Slide } from "vue-burger-menu"
export default {
components: {
Slide
}
}
</script>

How to access a constant in main.js in another js file in vue.js framework?

I have a vue.js application and in the main.js file I have configured the Vuei18n as per the documentation. This is working perfectly and in order to access this in other components, I have added this to new Vue() instance and this is now accessible (with this.$i18n).
Now I have created a validator.js file for validation rules and I need to use the this.$i18n there, but its not working. I have also tried Vue.prototype.$i18n but that too not working. Can someone help me to find out where I went wrong ?
 exporting the i18n variable
I'll assume your app is a vue-cli app, or at least that you use webpack to build it
and therefore can use ES modules.
Working with vue-i18n you would do something like the following:
// step 1: define the i18n object via new Vue18n
const i18n = new VueI18n({
locale: DEFAULT_LANGUAGE,
messages,
});
// step 2: setup the Vue object to use this object:
new Vue({
i18n,
... store, router.... whatever
})
Where messages contain all the JSON's with the translations keys and values.
I guess you already are doing something like this.
And now, in your validator module you need the very same i18n object you plugged to Vue.
Instead of trying to get to Vue in your validator, you can just plain export the i18n varible from main.js:
export {i18n}
So, in your validator.js file, you can just import it:
import {i18n} from '#/main.js' // or whatever is the path
This is pretty much how I'm solving the validator internationalization problem in my own application.
Important note: circular dependencies
If you're already importing the validator.js in your main.js, you won't be able to import i18n from main in your validator module. To avoid such a problem, you would move the i18n initialization and exportation to another module, such as i18n.js, so the validator and the main file can import it independently. 
 Without es6 modules
In case you're not using webpack or another bundler to bundle your code, you can still just export the i18n object to the window object:
window.i18n = i18n
and then use it from whatever file. You just need to be careful to store the i18n object in window before any file will try to access it.
I think what you're looking for is Custom Events. According to this documentation, you should be able to emit your variable with something like below
this.$emit('send-i18n', this.$i18n)
Still according to the documentation, try to use v-on:send-i18n to retreive your value.
Hope it works.

Using Vue.set() and Vue.use() in .vue files

How can I use Vue.set() and Vue.use() in .vue files? I'm using the vue-cli to scaffold my project and I need to use Vue.use(VeeValidate) for validation. Also I would like to use something like following, found here.
Vue.set(example1.items, indexOfItem, newValue)
Since the .vue files export object, How do I get the Vue reference. Also I would like to use it inside my default object exported in .vue files. What I mean is that I need to use Vue.set() on an item present in my data function.
You have to use import wherever you need Vue or vee-validate, you can do it like following inside the script tag:
<script>
import Vue from 'vue'
import VeeValidate from 'vee-validate'
Vue.use(VeeValidate)
...
...
</script>
If you just want to do Vue.set, you can instead do this.$set which is the alias of the global Vue.set.
Your components have Vue.set available as this.$set. For reference: instance methods & properties.
Vue.use is a global method and can be called wherever. It is basically never called inside a component(and might actually throw if you try? Never tried it). Call it wherever you're doing the rest of your initialization.