Vuejs implementing Vue-Select2 not showing on result - javascript

After installing vue3-select2-component with their document when i implementing that. it doesn't show in output on html but i have the html of that in source code
BTW: i'm using inertiajs on Laravel framework
install:
// npm install
npm install vue3-select2-component --save
Use as component:
import {createApp, h} from 'vue'
import BootstrapVue3 from 'bootstrap-vue-3'
import IconsPlugin from 'bootstrap-vue-3'
import {InertiaProgress} from "#inertiajs/progress";
import {createInertiaApp, Head} from '#inertiajs/inertia-vue3'
import {Link} from "#inertiajs/inertia-vue3"
///...
import Select2 from 'vue3-select2-component';
import {createStore} from "vuex"
///...
createInertiaApp({
resolve: async name => {
return (await import(`./pages/${name}`)).default;
},
setup({el, App, props, plugin}) {
createApp({render: () => h(App, props)})
.use(plugin)
.use(bootstrap)
.use(BootstrapVue3)
.use(IconsPlugin)
.use(VueSweetalert2)
.component('Link', Link)
.component('Select2', Select2)
.mount(el)
},
title: title => 'azizam - ' + title
}).then(r => {
});
vuejs page which i want to use into that:
<template>
<Select2 v-model="myValue" :options="myOptions"
:settings="{ settingOption: value, settingOption: value }"
#change="myChangeEvent($event)"
#select="mySelectEvent($event)" />
</template>
<script>
import menubar from "./menubar";
import emulator from "./emulator";
import {mapActions} from "vuex";
import notification from "../../../partials/notification";
export default {
name: "image",
data() {
return {
caption: '',
myValue: '',
myOptions: ['op1', 'op2', 'op3']
}
},
components: {
menubar,
emulator,
notification
},
methods: {
...mapActions([
'changeBreadcrumb'
]),
myChangeEvent(val){
console.log(val);
},
mySelectEvent({id, text}){
console.log({id, text})
}
},
mounted() {
const payload = {
title: 'محصولات',
subTitle: 'ایجاد محصول تک عکس در سامانه'
};
this.changeBreadcrumb(payload);
}
}
</script>
console log:
Warning - slinky.min.js is not loaded. application.js:336:21
[Vue warn]: A plugin must either be a function or an object with an "install" function. vendor.js:10544:17
[Vue warn]: Plugin has already been applied to target app. vendor.js:10544:17
Use of Mutation Events is deprecated. Use MutationObserver instead. content.js:19:11
Source map error: Error: request failed with status 404
Resource URL: http://127.0.0.1:8000/js/vendor.js?id=594b688c9609a79fb52afd907a69c736
Source Map URL: tooltip.js.map
in console as you can see i don't get any error for this component
html source code:
<select2 options="op1,op2,op3" settings="[object Object]"></select2>
and then webpack:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
//.sass('resources/scss/app.scss','public/css')
.extract()
.vue({
version: 3,
options: {
compilerOptions: {
isCustomElement: (tag) => ['Select2'].includes(tag),
},
},
})
.postCss('resources/css/app.css', 'public/css', [
//
])
.version();

The problem is you've configured Vue to treat <Select2> as a custom element, so the actual component does not get rendered.
The fix is to remove that configuration:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
//.sass('resources/scss/app.scss','public/css')
.extract()
.vue({
version: 3,
//options: {
// compilerOptions: {
// isCustomElement: (tag) => ['Select2'].includes(tag), ❌ remove this
// },
//},
})
.postCss('resources/css/app.css', 'public/css', [
//
])
.version();

Related

Can't load Expo Vector Icons in Nextjs

I have tried a lot of different ways to do this, with absolutely zero luck, over multiple days.
I am trying to use Solito Nativebase Universal Typescript repo to do this:
https://github.com/GeekyAnts/nativebase-templates/tree/master/solito-universal-app-template-nativebase-typescript
I have read, and tried everything on this page at least a dozen times:
https://github.com/GeekyAnts/nativebase-templates/issues/43
My current next.config.js file looks like this:
/** #type {import('next').NextConfig} */
const { withNativebase } = require('#native-base/next-adapter')
const withImages = require('next-images')
const { withExpo } = require('#expo/next-adapter')
const withFonts = require('next-fonts')
module.exports = withNativebase({
dependencies: [
'#expo/next-adapter',
'next-images',
'react-native-vector-icons',
'react-native-vector-icons-for-web',
'solito',
'app',
],
plugins: [
[withFonts, { projectRoot: __dirname }],
withImages,
[withExpo, { projectRoot: __dirname }],
],
nextConfig: {
images: {
disableStaticImages: true,
},
projectRoot: __dirname,
reactStrictMode: true,
webpack5: true,
webpack: (config, options) => {
config.resolve.alias = {
...(config.resolve.alias || {}),
'react-native$': 'react-native-web',
'#expo/vector-icons': 'react-native-vector-icons',
}
config.resolve.extensions = [
'.web.js',
'.web.ts',
'.web.tsx',
...config.resolve.extensions,
]
return config
},
},
})
I have also tried using #native-base/icons, again, no luck.
My end use case is this:
export const Cart = (props: IIconStyles) => {
return (
<Icon
as={FontAwesome5}
name="shopping-cart"
size={props.size ? props.size : 6}
color="gray.200"
/>
)
Theoretically it SHOULD show a shopping cart, but instead, this is what I see:
So clearly there's some font issue or other issue that is preventing it from loading in the actual SVG.
I can't figure out what this is - I've tried rewriting my _document.tsx file like this:
https://docs.nativebase.io/nb-icons
I've tried adding this to my next.config.js:
config.module.rules.push({
test: /\.ttf$/,
loader: "url-loader", // or directly file-loader
include: path.resolve(__dirname, "node_modules/#native-base/icons"),
});
When I try to do something like this:
import fontsCSS from '#native-base/icons/FontsCSS';
in my _document.tsx file, I get the following error:
Module not found: Can't resolve '#native-base/icons/lib/FontsCSS'
Despite the fact that I've got #native-base/icons installed in my package.json, as well as having it in my Babel file per the instruction link above.
How do I get vector icons to work in Next?
Note, this is specifically Next/Expo/React Native
You can read more about setup of next-adapter-icons here.
I got it working with following approach,
next.config.js
const { withNativebase } = require("#native-base/next-adapter");
const path = require("path");
module.exports = withNativebase({
dependencies: ["#native-base/icons", "react-native-web-linear-gradient"],
nextConfig: {
webpack: (config, options) => {
config.module.rules.push({
test: /\.ttf$/,
loader: "url-loader", // or directly file-loader
include: path.resolve(__dirname, "node_modules/#native-base/icons"),
});
config.resolve.alias = {
...(config.resolve.alias || {}),
"react-native$": "react-native-web",
"react-native-linear-gradient": "react-native-web-linear-gradient",
"#expo/vector-icons": "react-native-vector-icons",
};
config.resolve.extensions = [
".web.js",
".web.ts",
".web.tsx",
...config.resolve.extensions,
];
return config;
},
},
});
pages/_document.js
import React from 'react';
import { DocumentContext, DocumentInitialProps } from 'next/document';
import { default as NativebaseDocument } from '#native-base/next-adapter/document'
// Icon Font Library Imports
import MaterialIconsFont from '#native-base/icons/FontsCSS/MaterialIconsFontFaceCSS';
import EntypoFontFaceCSS from '#native-base/icons/FontsCSS/EntypoFontFaceCSS';
const fontsCSS = `${MaterialIconsFont} ${EntypoFontFaceCSS}`;
export default class Document extends NativebaseDocument {
static async getInitialProps(ctx) {
const props = await super.getInitialProps(ctx);
const styles = [
<style key={'fontsCSS'} dangerouslySetInnerHTML={{ __html: fontsCSS }} />,
...props.styles,
]
return { ...props, styles: React.Children.toArray(styles) }
}
}
pages/index.tsx
import React from "react";
import { Box, Icon } from "native-base";
import Entypo from "#expo/vector-icons/Entypo";
export default function App() {
return (
<Box>
<Icon
as={Entypo}
name="user"
color="coolGray.800"
_dark={{
color: "warmGray.50",
}}
/>
</Box>
);
}
Using import like this:
import MaterialIcons from '#expo/vector-icons/MaterialIcons'
in place of:
import { MaterialIcons } from '#expo/vector-icons'
worked for me. I think this is because of the way babel/webpack handles imports in the template. I followed the steps here to setup the icons.
Here's what that looks like on web:

How to resolve npm error needing an appropriate loader?

I created a Vue.js project with vue-chartjs. I tried reinstalling the library, however I still got this error:
error in ./node_modules/chart.js/dist/chart.esm.js
Module parse failed: Unexpected token (6613:12)
You may need an appropriate loader to handle this file type.
| if (intermediateIndex1 !== startIndex && intermediateIndex1 !== lastIndex) {
| decimated.push({
| ...data[intermediateIndex1],
| x: avgX,
| });
# ./node_modules/vue-chartjs/es/BaseCharts.js 1:0-29
# ./node_modules/vue-chartjs/es/index.js
App.vue:
<template>
<div id="app"></div>
</template>
<script>
import axios from "axios";
import moment from "moment";
import LineChart from "./components/LineChart";
export default {
name: "App",
components: {
LineChart
},
}
LineChart.vue
<script>
import { Line } from "vue-chartjs";
export default {
extends: Line,
props: {
label: {
type: String
},
chartData: {
type: Array
},
options: {
type: Object
},
},
mounted() {
const dates = this.chartData.map(d => d.date).reverse();
const totals = this.chartData.map(d => d.total).reverse();
this.renderChart(
{
labels: dates,
datasets: [
{
label: this.label,
data: totals
}
]
},
this.options
);
}
};
</script>
........................................................................................................................................................................................................................................................................................................................
High chance you installed chartjs version 3. The vue wrapper is incompatibele with this version of chart.js and only supports the older version 2.
If you downgrade to version 2.9.4 by changing the version number in your package.json to 2.9.4 and run your install command again or remove the package and use the command install chart.js#2.9.4 . This will most likely resolve your issue

How to use Vue 3 Meta with Vue.js 3?

It seems that Vue Meta has been upgraded to handle Vue.js 3 with a new npm package called vue-3-meta
Before Vue.js 3, it was easy to use vue-meta by adding it to the Vue instance:
import Vue from 'vue'
import VueMeta from 'vue-meta'
Vue.use(VueMeta, {
// optional pluginOptions
refreshOnceOnNavigation: true
})
However in Vue.js 3, there is no Vue instance; and instead you create the app by running createApp like such:
const app = createApp(App);
const router = createVueRouter();
app.use(router);
// need to make app use Vue-Meta here
I cannot find any documentation for vue-3-meta. import VueMeta from 'vue-meta' no longer works.
How do I import the vue-3-meta plugin properly and use it with app like in prior versions?
Disclaimer: vue-meta v3 is still in alpha!
This was the minimal implementation I needed to get started:
Update vue-meta to v3 (in package.json)
- "vue-meta": "^2.4.0",
+ "vue-meta": "^3.0.0-alpha.7",
...or with yarn:
yarn add vue-meta#alpha
Add metaManager to Vue app
import { createMetaManager } from 'vue-meta'
const app = createApp(App)
.use(router)
.use(store)
.use(createMetaManager()) // add this line
await router.isReady()
app.mount('#app')
Add <metainfo> to App.vue <template> (this is also where I set a "title template")
<template>
<metainfo>
<template v-slot:title="{ content }">{{ content ? `${content} | SITE_NAME` : `SITE_NAME` }}</template>
</metainfo>
<header />
<router-view />
<footer />
</template>
Set default meta in App.vue <script>
Vue 3 vanilla:
import { useMeta } from 'vue-meta'
export default {
setup () {
useMeta({
title: '',
htmlAttrs: { lang: 'en', amp: true }
})
}
}
or with vue-class-component:
import { setup, Vue } from 'vue-class-component'
import { useMeta } from 'vue-meta'
export default class App extends Vue {
meta = setup(() => useMeta({
title: '',
htmlAttrs: { lang: 'en', amp: true }
})
}
Override meta in each component
Vue 3 vanilla:
import { useMeta } from 'vue-meta'
export default {
setup () {
useMeta({ title: 'Some Page' })
}
}
or with vue-class-component:
import { computed } from '#vue/runtime-core'
import { setup, Vue } from 'vue-class-component'
import { useMeta } from 'vue-meta'
export default class SomePage extends Vue {
meta = setup(() => useMeta(
computed(() => ({ title: this.something?.field ?? 'Default' })))
)
}
See also:
"Quick Usage" (vue-meta next branch)
Vue Router Example (vue-meta next branch)
In addition to the previous answers, I also needed to add a transpileDependency in my vue.config.js, as I was using vue-cli:
module.exports = {
transpileDependencies: ['vue-meta']
}
Else, I would get the error:
error in ./node_modules/vue-meta/dist/vue-meta.esm-browser.min.js
Module parse failed: Unexpected token (8:7170)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
Thanks to this thread for pointing me to this: https://stackoverflow.com/a/65844988/3433137
metaManager is a MetaManager instance created from createMetaManager() of vue-meta.
Based on the Vue 3 + Vue Router example for vue-meta, here's an example usage:
import { createApp } from 'vue'
import { createMetaManager, defaultConfig, resolveOption, useMeta } from 'vue-meta'
const decisionMaker5000000 = resolveOption((prevValue, context) => {
const { uid = 0 } = context.vm || {}
if (!prevValue || prevValue < uid) {
return uid
}
})
const metaManager = createMetaManager({
...defaultConfig,
esi: {
group: true,
namespaced: true,
attributes: ['src', 'test', 'text']
}
}, decisionMaker5000000)
useMeta(
{
og: {
something: 'test'
}
},
metaManager
)
createApp(App).use(metaManager).mount('#app')

Render external loaded vue component in react app

I want to load external vue components in a react app as plugins from an url.
I already bundled the vue component as a commonJs package, but it will not render in the react app.
I have found a solution
Vue Project
main.js
import Vue from 'vue'
import wrap from '#vue/web-component-wrapper'
import Plugin from './components/Plugin'
const CustomElement = wrap(Vue, Plugin)
window.customElements.define('vue-plugin', CustomElement)
./component/Plugin.vue
<template>
<div class>
<p>{{text}}</p>
<p>{{pluginData.text}}</p>
<button v-on:click="sendData({ text: 'primary click vue' })">primary</button>
<button v-on:click="sendData({ text: 'secondary click vue' })">secondary</button>
</div>
</template>
<script>
export default {
props: {
text: String,
data: String
},
computed: {
pluginData () {
return JSON.parse(this.data)
}
},
methods: {
sendData: function(payload) {
this.$emit('sendData', payload);
}
}
}
</script>
Then build the webcomponent with:
vue-cli-service build --target wc --name vue-plugin ./src/main.js
And loaded in the react app with:
const $script = require("scriptjs")
$script("https://external-url-to-your-component.com/plugin.js", () => {
this.setState({
Component: ({ data, children, ...props}) => React.createElement(
'vue-plugin',
{...props, data: JSON.stringify(data), ref: elem => this[name] = elem },
children
)
})
this[name].addEventListener('sendData', event => {
const payload = event.detail
payload && payload.length && sendData(payload[0])
})
})

Use I18n translation messages from SFC when using Vue.extend

I'm working on an app I'm migrate to VueJS so some parts are using old jQuery code.
So I'm trying to append an VueJS component using jQuery, so I made
import copyToClipboard from '../components/_base/VCopyToClipboard';
const CopyToClipboard = Vue.extend(copyToClipboard);
$(event.currentTarget).find('.dns-challenge-row').each((index, element) => {
const component = new CopyToClipboard({
propsData: {
targetId: $(element).find('code').attr('id'),
},
}).$mount();
$(element).append(component.$el);
});
Everything is working BUT when I go on the page where this component is appended, i18n return an error
Cannot translate the value of keypath 'tooltip.default'. Use the value of keypath as default.
FYI my translation messages are directly defined inside my SFC using the i18n keyword
i18n: {
messages: {
en: {
tooltip: {
default: 'Copy content',
success: 'Copied',
},
},
fr: {
tooltip: {
default: 'Copier le contenu',
success: 'Copié',
},
},
},
},
and I use then directly inside the SFC using this.$t('tooltip.default')
My i18n is import like the docs say but is loaded after the vue.js I use to create my component.
import {
Vue,
} from './vue';
import VueI18n from 'vue-i18n';
import en from '../../translations/en';
import fr from '../../translations/fr';
Vue.use(VueI18n);
export default new VueI18n({
locale: document.getElementsByTagName('html')[0].getAttribute('lang'),
messages: {
en,
fr,
},
});
The vue.js file is the the file where I put all my Vue.use() definitions, my routern, other stuff and is used to create the Vue instance inside another file
vueSetup(new Vue({
el: '#app',
components: {
...
},
i18n: i18n,
router: router,
store: store,
}));
Do you have an idea to solve this?
I tried to load i18n before the vue component without success and I saw a lot of GitHub issues with this error but not like my case.
Just import and add i18n instance to the new component instance
const CopyToClipboard = Vue.extend(copyToClipboard);
$(event.currentTarget).find('.dns-challenge-row').each((index, element) => {
const component = new CopyToClipboard({
i18n: i18n,
propsData: {
targetId: $(element).find('code').attr('id'),
},
}).$mount();
$(element).append(component.$el);
});

Categories