number of display swiper items when loading is not correct in vue3 nuxt3 project - vuejs3

I create a base swiper component
I give it a default breakpoint that show 6 item in desktop but while loading,
first show 1 item and then 6 item
this is really bad for cls and screen will change
my packages: package.json
"devDependencies": {
"#tailwindcss/typography": "^0.5.8",
"autoprefixer": "^10.4.13",
"nuxt": "3.0.0",
"postcss": "^8.4.20",
"postcss-extend": "^1.0.5",
"tailwindcss": "^3.2.4"
},
"dependencies": {
"#heroicons/vue": "^2.0.13",
"#tailwindcss/aspect-ratio": "^0.4.2",
"#tailwindcss/line-clamp": "^0.4.2",
"#vueuse/core": "^9.8.2",
"daisyui": "^2.46.0",
"gsap": "^3.11.4",
"swiper": "^8.4.5",
"vee-validate": "^4.7.3",
"yup": "^0.32.11"
}
this my base swiper component: Swiper.vue
<template>
<swiper :modules="modules" :navigation="!navigationHide" :breakpoints="breakPoints">
<swiper-slide class="cursor-pointer" v-for="i in 10" :key="i">
<slot></slot>
</swiper-slide>
</swiper>
</template>
<script setup>
// import Swiper core and required modules
import { Navigation, A11y } from "swiper";
// Import Swiper Vue.js components
import { Swiper, SwiperSlide } from "swiper/vue";
// Import Swiper styles
import "swiper/css";
import "swiper/css/navigation";
const modules = [A11y, Navigation]
const props = defineProps({
breakPoints: {
type: Object,
default() {
return {
0: {
slidesPerView: 1.85,
},
500: {
slidesPerView: 2.15,
},
600: {
slidesPerView: 2.75,
},
768: {
slidesPerView: 3.5,
},
992: {
slidesPerView: 4,
},
1024: {
slidesPerView: 4.5,
},
1200: {
slidesPerView: 5,
},
1440: {
slidesOffsetBefore: 12,
slidesPerView: 6,
},
1900: {
slidesPerView: 7,
},
};
},
},
navigationHide: {
type: Boolean,
default: false,
}
});
</script>
if I want to descice with image:
enter image description here
I want that eve while loading it should exactly that number item that I entered in breakpoint.
thank you for your attention

Related

How Laravel 9 works with VueJS 3 on Blade files?

This is some files from my Laravel 5.8 project that has some Vue2 components.
I have created a new fresh installation of Laravel 9, Vue 3 and ViteJS.
Something is wrong and I can't figure out what.
Let's see some code:
The package.json:
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"#popperjs/core": "^2.11.6",
"#vue/compat": "^3.1.0",
"axios": "^1.1.2",
"bootstrap": "^5.2.3",
"laravel-vite-plugin": "^0.7.2",
"lodash": "^4.17.19",
"postcss": "^8.1.14",
"sass": "^1.56.1",
"vite": "^3.0.0"
},
"dependencies": {
"#vitejs/plugin-vue": "^3.2.0",
"#vue/compiler-sfc": "^3.1.0",
"fsevents": "^2.3.2",
"jquery": "^3.6.3",
"laravel-echo": "^1.15.0",
"moment-timezone": "^0.5.40",
"pusher-js": "^8.0.1",
"tinymce": "^6.3.1",
"vue": "^3.2.45",
"vue-loader": "^15.10.1",
"vue-moment": "^4.1.0",
"vue-scrollto": "^2.20.0",
"vue-the-mask": "^0.11.1",
"vue-toasted": "^1.1.28"
}
}
The vite.config.js:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/sass/app.scss',
'resources/js/app.js',
],
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js',
},
},
});
This is a piece of my app.jsfile:
import Vue from 'vue';
import { createApp } from 'vue';
import UploadForm from './components/UploadForm.vue';
// ...
import './bootstrap';
const app = createApp({
components: {
UploadForm,
// ...
}
})
app.mount('#app')
export const bus = new Vue();
This is a part of < body > section of app.blade.phpfile:
<div id="app">
<div v-if="loader" class="loading" id="loader">Loading…</div>
#include('_inc.nav.topNav')
<main class="m-t-0">
#yield('content')
</main>
</div >
This is part of some.blade.php file:
#extends('layouts.app')
#section('content')
<div class="container m-b-100">
<!-- Content -->
</div>
#endsection
#section('scripts')
<script type="text/javascript" src="{{ asset('js/moment-with-locales.min.js') }}"></script>
<script>
const { createApp } = Vue;
const app = createApp({
el: '#app',
data: {
// some data, methods
}
});
app.mount('#app');
</script>
#endsection
At the Inspector Window the error is:
Uncaught TypeError: t.call is not a function
and it is pointing to:
app.mount('#app');

Include 3rd party scss in component library using Vue 3 + Vite

I'm currently building an external component library using Vue 3 + Vite. I'm using 3rd party component and style, but the style doesn't apply when I used it in my main project. It used to work before when I use Vue 2 + Vue CLI.
My component library project looks like this:
and here's the detail for my code
vite.config.js
import { resolve } from 'path'
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
build: {
lib: {
entry: resolve(__dirname, 'src/main.js'),
name: 'custom-lib',
fileName: 'custom-lib',
},
rollupOptions: {
external: ['vue'],
output: {
globals: {
vue: 'Vue'
}
}
}
}
})
package.json
{
"name": "custom-lib",
"private": true,
"version": "0.0.0",
"type": "module",
"files": [
"dist"
],
"main": "./dist/custom-lib.umd.cjs",
"module": "./dist/custom-lib.js",
"exports": {
".": {
"import": "./dist/custom-lib.js",
"require": "./dist/custom-lib.umd.cjs"
}
},
"scripts": {
"build": "vite build"
},
"dependencies": {
"moment": "^2.29.4",
"vue": "^3.2.41",
"vue-datepicker-next": "^1.0.2"
},
"devDependencies": {
"#vitejs/plugin-vue": "^3.2.0",
"sass": "^1.56.0",
"sass-loader": "^13.1.0",
"vite": "^3.2.3"
}
}
src/components/Datepicker.vue
<template>
<DatePicker
:id="id"
v-model:value="inputVal"
value-type="date"
type="date"
:format="dateFormat"
:placeholder="dateFormat"
:disabled="disabled"
input-class="mx-input"
/>
</template>
<script>
import DatePicker from 'vue-datepicker-next';
import moment from 'moment';
export default {
name: 'Datepicker',
components: {
DatePicker
},
props: {
id: {
type: String,
required: true
},
modelValue: null,
dateFormat: String,
disabled: Boolean
},
computed: {
inputVal: {
get() {
if (this.modelValue) {
return moment(this.modelValue).toDate();
}
return null;
},
set(val) {
let strVal = undefined;
let m = moment(val);
if (m.isValid()) {
strVal = m.format("YYYY-MM-DDTHH:mm:ss");
}
this.$emit('update:modelValue', strVal);
}
}
}
};
</script>
<style lang="scss">
#import "vue-datepicker-next/scss/index.scss";
</style>
src/main.js
import Datepicker from './components/Datepicker.vue';
export {
Datepicker
}
My Datepicker style not working in my main project, is there something missing from the config?
As I was suggesting in comment, you can use vite-plugin-css-injected-by-js
Add the plugin to your component project:
npm i vite-plugin-css-injected-by-js --save
Add the plugin to vite config of your custom component:
import { resolve } from 'path'
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js' // 👈
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
cssInjectedByJsPlugin() // 👈
],
build: {
lib: {
entry: resolve(__dirname, 'src/main.js'),
name: 'custom-lib',
fileName: 'custom-lib',
},
rollupOptions: {
external: ['vue'],
output: {
globals: {
vue: 'Vue'
}
}
}
}
})
It should work without hassle.
See it on Stackblitz:
you can go in test folder (cd test) and run yarn dev to launch the preview.
preview:
https://stackblitz.com/edit/vitejs-vite-yd1rzw
Result:

swiper js dosn't work with next.js v 12.1.4?

my slider component does not recognize the swipe and click on the swiper and any action dosn't work on them.I don't know what is the problem here.
here is my package.json:
"dependencies": {
"clsx": "^1.1.1",
"next": "12.1.4",
"react": "18.0.0",
"react-dom": "18.0.0",
"swiper": "^8.0.7"
},
"devDependencies": {
"#types/node": "17.0.23",
"#types/react": "17.0.43",
"#types/react-dom": "17.0.14",
"#typescript-eslint/eslint-plugin": "^4.30.0",
"#typescript-eslint/parser": "^4.30.0",
"eslint": "^7.32.0",
"eslint-config-airbnb": "18.2.1",
"eslint-config-airbnb-typescript": "^12.0.0",
"eslint-config-airbnb-typescript-prettier": "^4.2.0",
"eslint-config-next": "^11.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.1.3",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.25.1",
"eslint-plugin-react-hooks": "^4.2.0",
"jest": "^26.6.3",
"prettier": "^2.3.2",
"sass": "^1.49.11",
"typescript": "4.6.3"
}
and here is my swiper component :
import React from 'react';
import { Navigation, Autoplay, Pagination } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/autoplay';
import 'swiper/css/effect-fade';
interface ISliderItem {
key: string; //
image: string;
}
const Slider: React.FunctionComponent = () => {
const items: ISliderItem[] = [
{ key: '1', image: '/logo.svg' },
{ key: '2', image: '/logo.svgi' },
{ key: '3', image: '/logo.svgj' },
{ key: '4', image: '/logo.svgm' },
{ key: '5', image: '/logo.svgm' },
{ key: '6', image: '/logo.svg,' },
];
return (
<Swiper
navigation
modules={[Navigation, Autoplay, Pagination]}
centeredSlides
autoplay={{
delay: 4000,
disableOnInteraction: false,
}}
>
{items.map(item => (
<SwiperSlide
key={item.key}
style={{ backgroundImage: `url(${item.image})`, width: '100%', height: '200px' }}
>
<p>{item.image}</p>
</SwiperSlide>
))}
</Swiper>
);
};
export default Slider;
this exact code works in my ther next js projects but it dosn't work here in my new project with next js version 12
import { Navigation, Pagination, Scrollbar, A11y, Autoplay } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
import 'swiper/css/scrollbar';
export default function SwiperPage(){
const items = [
{ key: '1', image: '/logo.svg' },
{ key: '2', image: '/logo.svgi' },
{ key: '3', image: '/logo.svgj' },
{ key: '4', image: '/logo.svgm' },
{ key: '5', image: '/logo.svgm' },
{ key: '6', image: '/logo.svg,' },
];
return(
<Swiper
// install Swiper modules
modules={[Navigation, Pagination, Scrollbar, A11y, Autoplay]}
spaceBetween={50}
slidesPerView={1}
autoplay={
{delay: 5000}
}
>
{items.map(item => (
<SwiperSlide
key={item.key}
style={{ backgroundImage: `url(${item.image})`, width: '100%', height: '200px' }}
>
<p>{item.image}</p>
</SwiperSlide>
))}
</Swiper>
)
}
Here is basic example adapted to your items - works with nextjs v12

How to use css-modules with storybook 6

My css-module is not working with Storybook. There are not any error, it is only not working. I don´t understand what is the problem. This is the image of how storybook is rendering the button:
Button.js file:
import React from "react";
import PropTypes from "prop-types";
import style from "./styles.module.css";
const Button = ({ type, children }) => (
<button className={style.button}>{children}</button>
);
Button.propTypes = {
children: PropTypes.node.isRequired,
type: PropTypes.string,
};
Button.defaultProps = {
children: "primary",
type: "primary",
};
export default Button;
Button.stories.js file:
import React from "react";
import Button from "./Button";
export default {
component: Button,
title: "Test/Button",
};
const Template = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
children: "xx ",
};
export const Secondary = Template.bind({});
Secondary.args = {
children: "xx ",
type: "secundary",
};
styles.module.css file:
.button {
background: yellow;
border: 1px solid var(--colors-transparent);
}
.test {
background: red;
color: var(--colors-white);
}
.type-primary {
background: red;
color: var(--colors-white);
}
.type-secundary {
background: rgb(12, 177, 163);
color: var(--colors-white);
}
package.json file:
"devDependencies": {
"#babel/core": "^7.16.0",
"#storybook/addon-actions": "^6.3.12",
"#storybook/addon-essentials": "^6.3.12",
"#storybook/addon-links": "^6.3.12",
"#storybook/react": "^6.3.12",
"babel-loader": "^8.2.3",
"classnames": "^2.3.1",
"react": "^16.14.0",
"react-scripts": "^4.0.3"
}
I have tried these other options
<button className={style["button"]}>{children}</button>
Maybe some idea how to solve it?
#Slava Zoref you can see this video css-modules storybook 6 minute 15:52 into .storybook/main.js you can write this code:
async function supportCssModules(config) {
// console.log('1=================================')
// console.log('>>>config', config.module.rules)
// console.log('1=================================')
config.module.rules.find(
(rule) => rule.test.toString() === '/\\.css$/'
).exclude = /\.module\.css$/
config.module.rules.push({
test: /\.module\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
},
},
],
})
return config
}
module.exports = {
stories: [
'../atomDesign/**/*.stories.#(js|jsx|ts|tsx)',
// "../ejemplos/**/*.stories.#(js|jsx|ts|tsx)",
// "../stories/**/*.stories.mdx",
// "../stories/**/*.stories.#(js|jsx|ts|tsx)"
],
addons: [
'#storybook/addon-links',
'#storybook/addon-essentials', //,'storybook-css-modules-preset',
],
// FIXME: Support CSS Modules for Storybook
webpackFinal: supportCssModules,
}
Use Storybook preset addon to add CSS Modules capabilities.
Installation
npm install -D storybook-css-modules
Configuration
Next, update .storybook/main.js to the following:
// .storybook/main.js
module.exports = {
stories: [
// ...
],
addons: [
// Other Storybook addons
"storybook-css-modules", // 👈 The addon registered here
],
};
By default this preset configured CSS Modules

Vuetify CSS missing when i build for production

We purchased a web app written in Vue from someone and we developing to change/improve it. One thing we added was Vuetify so we can use the Vuetify elements and everything has been working great while in development mode, but when we build for production the CSS for Vuetify elements is missing.
I have searched for this online already and have already tried what everybody is suggesting without any luck.
Anybody has an idea of what could be wrong and why npm run build would be missing some of the CSS?
What's weird is that all the UI functionality for Vue elements is working perfectly, just the CSS is missing.
Please see code samples below.
main.js:
import '#fortawesome/fontawesome-free/css/all.css'
import Vue from "vue";
import App from "./App.vue";
import VueMoment from "vue-moment";
import VueAnalytics from "vue-analytics";
import VueMeta from "vue-meta";
import { library } from "#fortawesome/fontawesome-svg-core";
import {
faCoffee,
faPlusCircle,
faChartLine,
faChevronDown,
faMobile,
faEnvelope,
faClock,
faUsers,
faPaperPlane,
faCheckCircle,
faCheck,
faLeaf,
} from "#fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "#fortawesome/vue-fontawesome";
import axios from "axios";
import router from "./router";
import store from "./store";
import vuetify from './plugins/vuetify';
import Vuetify from 'vuetify/lib'
library.add([
faCoffee,
faPlusCircle,
faChartLine,
faChevronDown,
faMobile,
faEnvelope,
faClock,
faUsers,
faPaperPlane,
faCheckCircle,
faCheck,
faLeaf,
]);
Vue.use(VueAnalytics, {
id: "xxx",
router,
});
Vue.use(VueMoment);
Vue.use(VueMeta);
Vue.component("font-awesome-icon", FontAwesomeIcon);
Vue.use(Vuetify)
axios.interceptors.response.use(undefined, async function (error) {
if (error.response.status === 401) {
await store.dispatch("auth/logout");
router.push("/login");
}
return Promise.reject(error);
});
// Plugins
// ...
// Sass file
require("./assets/styles/main.css");
Vue.config.productionTip = false;
new Vue({
router,
store,
vuetify,
render: (h) => h(App)
}).$mount("#app");
App.vue:
<template>
<v-app>
<v-main>
<router-view/>
</v-main>
</v-app>
</template>
<style>
.text-white {
color: #fff !important;
}
.text-gray-600 {
color: #757575 !important;
}
.font-semibold, .text-gray-700 {
color: #616161 !important;
}
</style>
package.json:
{
"name": "reviewgrower-spa",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"deploy": "git push dokku master"
},
"dependencies": {
"#fortawesome/fontawesome-svg-core": "^1.2.25",
"#fortawesome/free-solid-svg-icons": "^5.11.2",
"#fortawesome/vue-fontawesome": "^0.1.8",
"#fullhuman/postcss-purgecss": "^1.3.0",
"axios": "^0.19.0",
"chart.js": "^2.9.4",
"core-js": "^2.6.10",
"i": "^0.3.6",
"jquery": "^3.5.1",
"npm": "^6.13.0",
"tailwindcss-spinner": "^0.2.0",
"tailwindcss-toggle": "github:TowelSoftware/tailwindcss-toggle",
"url-parse": "^1.4.7",
"vue": "^2.6.10",
"vue-analytics": "^5.17.2",
"vue-chartjs": "^3.5.1",
"vue-click-outside": "^1.0.7",
"vue-clickaway": "^2.2.2",
"vue-feather-icons": "^4.22.0",
"vue-js-toggle-button": "^1.3.3",
"vue-meta": "^1.6.0",
"vue-moment": "^4.0.0",
"vue-router": "^3.1.3",
"vue-stripe-elements-plus": "^0.2.10",
"vuetify": "^2.4.0",
"vuex": "^3.0.1",
"vuex-persist": "^2.1.1"
},
"devDependencies": {
"#fortawesome/fontawesome-free": "^5.15.2",
"#vue/cli-plugin-babel": "^3.12.1",
"#vue/cli-plugin-eslint": "^3.12.1",
"#vue/cli-service": "^3.12.1",
"babel-eslint": "^10.0.3",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.2.3",
"sass": "^1.32.0",
"sass-loader": "^7.1.0",
"tailwindcss": "^1.1.3",
"vue-cli-plugin-vuetify": "~2.1.0",
"vue-template-compiler": "^2.5.21",
"vuetify-loader": "^1.7.0"
}
}
It's a little tough to understand what is missing where. If you think that is just missing then please try adding css onto the HTML file from the cdn and check the working.
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
I see that you are using webpack to compile the code. So, this could be also something related to webpack configuration. In your webpack rules do you have rules for css and scss. Because vuetify files are in scss.
My webpack configuration is as below when I do these type of circus.
--webpack.config.js--
const path = require("path");
const VuetifyLoaderPlugin = require("vuetify-loader/lib/plugin");
const { VueLoaderPlugin } = require("vue-loader");
module.exports = {
watch: true,
entry: {
main: 'main.js'
},
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.vue$/,
use: "vue-loader",
},
{
test: /\.s(c|a)ss$/,
use: [
"vue-style-loader",
"css-loader",
{
loader: "sass-loader",
// Requires sass-loader#^8.0.0
// options: {
// implementation: require('sass'),
// sassOptions: {
// fiber: require('fibers'),
// indentedSyntax: true // optional
// },
// },
},
],
},
],
},
plugins: [
new VueLoaderPlugin(),
new VuetifyLoaderPlugin({
/**
* This function will be called for every tag used in each vue component
* It should return an array, the first element will be inserted into the
* components array, the second should be a corresponding import
*
* originalTag - the tag as it was originally used in the template
* kebabTag - the tag normalised to kebab-case
* camelTag - the tag normalised to PascalCase
* path - a relative path to the current .vue file
* component - a parsed representation of the current component
*/
match(originalTag, { kebabTag, camelTag, path, component }) {
if (kebabTag.startsWith("core-")) {
return [
camelTag,
`import ${camelTag} from '#/components/core/${camelTag.substring(
4
)}.vue'`,
];
}
},
}),
],
}
Check your postcss.config.js, see if it has something to do with the purgecss.
You have to config the whitelist to ignore the vuetify styles.
Here is a sample for your reference:
const autoprefixer = require("autoprefixer");
const postcssImport = require("postcss-import");
const purgecss = require("#fullhuman/postcss-purgecss");
const IS_PROD = ["production", "prod"].includes(process.env.NODE_ENV);
let plugins = [];
if (IS_PROD) {
plugins.push(postcssImport);
plugins.push(
purgecss({
content: [
"./src/**/*.vue",
"./public/**/*.html",
`./node_modules/vuetify/src/**/*.ts`,
`./node_modules/vuetify/dist/vuetify.css`
],
defaultExtractor (content) {
const contentWithoutStyleBlocks = content.replace(/<style[^]+?<\/style>/gi, '')
return contentWithoutStyleBlocks.match(/[A-Za-z0-9-_/:]*[A-Za-z0-9-_/]+/g) || []
},
safelist: [ /-(leave|enter|appear)(|-(to|from|active))$/, /^(?!(|.*?:)cursor-move).+-move$/, /^router-link(|-exact)-active$/, /data-v-.*/ ],
whitelist: [
'container',
'row',
'spacer',
'aos-animate',
'col',
'[type=button]',
'v-application p',
],
whitelistPatterns: [
/^v-.*/,
/^col-.*/,
/^theme-.*/,
/^rounded-.*/,
/^data-aos-.*/,
/^(red|grey)--text$/,
/^text--darken-[1-4]$/,
/^text--lighten-[1-4]$/
],
whitelistPatternsChildren: [
/^post-content/,
/^v-input/,
/^swiper-.*/,
/^pswp.*/,
/^v-text-field.*/,
/^v-progress-linear/
]
})
);
}
module.exports = {
plugins:[
require('cssnano')({
preset: 'default'
}),
require('postcss-pxtorem')({
remUnit:15, //每个rem对应的px值
threeVersion:true
}),
...plugins,autoprefixer
]
}``
You are simply missing an include in your main.js (see vuetify docs):
import 'vuetify/dist/vuetify.min.css'
This will ensure that webpack includes the vuetify styles in the bundled CSS for production. This fixed the same issue for me (i.e. it worked locally but not in production).

Resources