UIkit undefined in Vue web component build - vue.js

I try to build Vue web-component with UIkit as UI library. After proper build with command:
npm run build -- --target wc --inline-vue --name my-element 'src/App.vue'
When I'm trying to embed component in other website UIkit styles are displayed properly, but UIkit instance which handles modal, dropdowns is undefined.
vue.runtime.esm.js:1888 TypeError: Cannot read property 'modal' of undefined
Here is main.js file where I initialize global UIkit variable.
import App from "./App.vue"
import wrap from "#vue/web-component-wrapper"
import Vue from "vue"
import VueFlatPickr from "vue-flatpickr-component"
import uk from "uikit"
import Icons from "uikit/dist/js/uikit-icons.js"
import "flatpickr/dist/flatpickr.css"
uk.use(Icons)
Vue.config.productionTip = true
Vue.use(VueFlatPickr)
Vue.mixin({
data: function() {
return {
get uk() {
return uk
},
}
},
})
const app = new Vue({
render: (h) => h(App)
})
app.$mount("#app")
const WrapperElem = wrap(Vue, App)
window.customElements.define("my-element", WrapperElem)
And here a little example of code how I use it and where the trouble occurs:
this.uk.modal("#delete-dialog").hide()

I've seen your question on the discord channel - I do not have a solution for your question BUT i have already successfully used UIkit 3 and Vue 3 in two of my projects with this base, may it helps you:
https://medium.com/#4ravind/uikit-with-vuejs-vue-cli-3-db811e43c46b

Related

How to Convert Vue 2 x to Vue 3 x?

We are integrating Vue into an existing ASP.Net MVC Application
Below code (Vue 2 X)working fine in our .Net Application
new Vue({
el: '#component1',
render: h => h(App)
});
To convert Vue 2 X to Vue 3 X used command "vue add vue-next" , after executing command version changed but "npm run build" command giving error.
You can use the Vue 3 migration build to help with the upgrade. It shims most of the Vue 2 code, while emitting console warnings that help you identify what to migrate.
To enable it in your Vue CLI project (based on installation steps from the migration guide), and to fix the code you mentioned:
Update vue to 3.1, and install #vue/compat of the same version:
npm i -S #vue/compat#^3.1.4
npm i -S vue#^3.1.4
Setup an alias from vue to #vue/compat:
// vue.config.js
module.exports = {
chainWebpack: config => {
config.resolve.alias.set('vue', '#vue/compat')
}
}
Update the app entry to the new global mounting API:
// import Vue from 'vue'
// import App from './App.vue'
// new Vue({ el: '#component1', render: h => h(App) });
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#component1')

Vue CLI 4.5.*: "export 'default' (imported as 'Vue') was not found in 'vue'

While working with Vue CLI 4.5.x, I tried the following code:
import Vue from "vue"
import App from './App.vue'
new Vue({
el: "#app",
render: h=> h(App)
})
But unfortunately, it gave the following warnings:
"export 'default' (imported as 'Vue') was not found in 'vue'
What I can conclude from this, is that Vue CLI 4.5.x has stopped this way of creating an application where you first create a Vue instance.
To initialize the main application, the official way is as follows:
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
I'm not sure if my conclusion is correct or not. It would be a great help if somebody would concrete my conclusion, as so far I have not found any proof of that in official documentation of vue.
Moreover, the later code comes baked with Vue CLI 4.5.* application instance, while former code is true when using the CDN.
You've installed vue 3 using vue-cli 4 and this version has this new global api for creating new app :
import { createApp } from 'vue'
const app = createApp({})
You're still able to create apps using vue 2 based on vue cli 4 but you should indicate the version when you launch new project.

getting error when trying to upgrade to vuetify 2.0

Ok so I am trying for the second time to migrate thus far it has been a complete failure it seems that vuetify is not detected, unfortunately I cannot share my full repo since it is work related, but will describe steps and share relevant code.
Project was created with vue-cli 3.3.0 with a vue.config.js file for environment variables.
1) npm uninstall vuetify
2)vue add vuetify
3)npm run serve
my site does not load and I get this error (adding code):
//vue.config.js
module.exports = {
chainWebpack: (config) => {
config.plugin('define')
.tap(([options, ...args]) => {
let env = options['process.env'].VUE_APP_ENV.replace(/"/g,'');
let envMdl = require('./build/' + env.toString() + '.js');
// replace all current by VUE concrente ones to be passed to the app
const processEnv = Object.assign({}, options['process.env'])
Object.keys(envMdl).forEach(function (k) {
processEnv['VUE_APP_' + k] = envMdl[k];
});
const ret = Object.assign({}, options, {'process.env': processEnv});
return [
ret,
...args
]
})
}
}
//vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
Vue.use(Vuetify)
export default new Vuetify({
icons: {
iconfont: 'mdiSvg',
},
})
//main.js
import vuetify from './plugins/vuetify'
...
new Vue({
vuetify,
router,
store,
i18n,
render: h => h(App),
...
Error message (and screenshot): Uncaught TypeError: _lib.default is not a constructor
at eval (vuetify.js?402c:6)
The main problem is that Vuetify v1 works under the Stylus preprocessor, and in v2 it works under the SASS preprocessor, and I personally do not recommend migrating to v2 if it is too advanced and even worse if it has custom Vuetify components.

Use Vue component after Webpack build

I have a CMS that delivers static HTML pages. For that CMS, I want to develop components with Vue that then can be used in the CMS individually.
As I understood, Vue is the perfect solution for that.
As TypeScript gets more and more common, I want to use TypeScript with Babel and Webpack, so the CLI project gave me a perfect boilerplate.
When I run npm run build, I get an index.html in the dist folder with my <div id="app"></div>-container. This could be my root element/template in CMS, and then just pass the components in it.
Sadly, everything in the app-container is rendered out.
I already registered my components inside the main.ts file, and removed the line render: (h)=>h(App), but it also replaces my container contents.
Main.ts:
import Vue from 'vue';
import App from './App.vue';
import ButtonLink from './components/ButtonLink.vue';
Vue.config.productionTip = false;
// Adding the component to my Vue context
Vue.component('ButtonLink', ButtonLink);
new Vue({
// render: (h) => h(App),
}).$mount('#app');
Excerpt of index.html in dist dir:
<div id=app>
<ButtonLink href="https://google.com">A link </ButtonLink>
</div>
Link to full project: https://gitlab.com/cedricwe/vue-problem/tree/master
What did I do wrong? Is this even possible?
It looks like you're using in-DOM templates without the runtime compiler, which would yield this browser console warning:
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
(found in <Root>)
The runtime compiler is excluded by default to reduce the bundle size. You could enable it in a Vue CLI project with the runtimeCompiler flag in vue.config.js in the root of your project:
module.exports = {
runtimeCompiler: true
}
What you really want to do is provide your Vue instance a "mounting point". In this case we normally use the el option something along the lines of this would work instead:
import Vue from 'vue';
import App from './App.vue';
import ButtonLink from './components/ButtonLink.vue';
Vue.config.productionTip = false;
new Vue({
el: '#app', // mounts this instance to #app but doesn't render it
components: {
ButtonLink // optionally have it local to your instance vs global
}
});

VeeValidate errors is not defined when importing into custom plugin

I'm building a custom Vue JS plugin using the vue create CLI. I've imported my various packages, however, I'm getting an error when trying to use custom settings with VeeValidate.
plugin.js
/*
* NOTE:
* This file is plugin stub for main.js
*/
// Import required packages
import Vue from 'vue'
import VeeValidate from 'vee-validate'
import VueResource from 'vue-resource'
import BootstrapVue from 'bootstrap-vue'
// Import custom LES form styling
import './assets/scss/les-application.scss'
// Import our plugin
import plugin from './index'
/* Vue Validation */
const config = {
fieldsBagName: 'fields',
errorBagName: 'errors',
classes: true,
strict: false,
classNames: {
valid: '',
invalid: 'is-invalid'
},
events: 'change|blur',
validity: false,
inject: false,
aria: true,
delay: 0
}
Vue.use(require('vue-moment'))
Vue.use(VueResource)
Vue.use(VeeValidate, config)
Vue.use(plugin)
// Custom validation rules
/*
* NOTE:
* If you want Vue instance of main.js to import something in your plugin as a Vue option,
* you need to export it here.
*/
// export default plugin
main.js
import Vue from 'vue'
import App from './App.vue'
import './plugin'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
Errors:
Property or method "errors" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
and
Cannot read property 'has' of undefined
I'm trying to figure out what I'm missing from my configuration, if I remove the VeeValidate config from plugin.js it then uses the default VeeValidate options and is working.
It is the inject: false, in the validation config causing this. if you set this to true or do not set it, the errors object should be injected in your component without errors.
The inject:false stops automatic injections in vee-validate 2 http://vee-validate.logaretm.com/v2/concepts/injections.html
This changes with vee-validate 3 where ValidationObserver and ValidationProvider need to be used https://logaretm.github.io/vee-validate/migration.html#migrating-from-2-x-to-3-0