So I have a basic Vue Native application with a few screens managed by the StackNavigator.
My App.vue file looks like this:
<template>
<app-navigator></app-navigator>
</template>
<script>
import {
createAppContainer,
createStackNavigator,
} from "vue-native-router";
import Login from './screens/Login.vue';
import Register from './screens/Register.vue';
import HomeScreen from "./screens/HomeScreen.vue";
import DetailsScreen from "./screens/DetailsScreen.vue";
import UserDetails from "./screens/UserDetails.vue";
import CarHistory from "./screens/CarHistory.vue";
const StackNavigator = createStackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
Login: Login,
Register: Register,
UserDetails: UserDetails,
CarHistory: CarHistory,
},
{
initialRouteName: 'Login',
// initialRouteName: 'CarHistory',
defaultNavigationOptions: {
headerStyle: {
display: 'none',
},
},
},
);
const AppNavigator = createAppContainer(StackNavigator);
export default {
components: { AppNavigator },
data: function() {
return {
}
},
}
</script>
<style>
</style>
What I am trying to achieve is somehow create a file or even write the Styling in the Style attribute of the App.vue file but make it apply globally - on every template/screen of the application.
Is that even possible or...?
EDIT: I have tried typing the style in the attribute of the App.vue file, but it does not apply anywhere else but in App.vue.
The only way i know is to write styles in script part of vue component, not in a style tag, and applying it like:
<view :style='styleobj.styleClass'></view>
So you could create javascript files with variables and import it manually to each component, or globally to Vue.prototype.
Related
I wanted to know how can I add a class to a modal in a navbar components? My navbar is in App.vue and I wanted to create a message that would add the class "is-active" to a modal in my navbar when I click on it. But I can't find the way to do that..
Thank you
Usually when you have a parent -> child relationship you can use events. In this case since you have two components that are not linked (directly) then you have two alternatives.
Using store (it is usually used in cases where your application is of a considerate size)
You can use vuex to have a central place where you will have your global state. A simple example would be:
store/main.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
isModalOpen: false
},
getters: {
isModalOpen => (state) => state.isModalOpen,
},
mutations: {
setIsModalOpen (state, isOpen) {
state.isModalOpen = isOpen;
}
}
})
then you can access the store in your component as such:
<template>
<navbar :class="[isNavBarOpen ? "is-active" : ""]" />
</template>
export default {
computed: {
isNavBarOpen () {
this.$store.getters['isModalOpen']
}
}
}
Event bus (it is usually used in cases where you have a small app and do not need a global state manager)
Read more about EventBus here.
You can create a simple EventBus
services/eventBus.js
import Vue from 'vue';
const export EventBus = new Vue();
then on your component when the modal is open you can do:
// # -> is an alias to your root folder. Most projects scafolded by Vue CLI has this by default
import {EventBus} from "#/services/eventBus"
export default {
methods: {
openStore: () => {
// your logic to open modal
EventBus.$emit('modal-open');
}
}
}
then on your App.vue you just listen to this event
App.vue
<template>
<navbar :class="[isModalOpen ? "is-active" : ""]" />
</template>
// # -> is an alias to your root folder. Most projects scafolded by Vue CLI has this by default
import {EventBus} from "#/services/eventBus"
export default {
data() {
return {
isModalOpen: false,
}
},
created() {
EventBus.$on('modal-open', this.onModalOpen);
},
methods: {
onModalOpen() {
this.isModalOpen = true;
}
}
}
The one you will pick depends on our application structure and if you think it is complex enough to use a central state management (vuex).
There might contain some errors in the code but the main idea is there.
I have a dialog component which is using the Primereact dialog internally. When I make a storybook for the same, the custom css for button is being imported as it is imported inside dialog.jsx. But the default css of Primereact dialog is not loading and reflecting in the storybook. Although it is being loaded in my React app.
dialogComp.jsx
import { Dialog } from "primereact/dialog";
const DialogComp = (props) => {
return (
<Dialog
className="dialog-modal"
header={props.header}
visible={true}
>
{props.children}
</Dialog>
);
};
export default DialogModal;
dialog.storybook.js
import React from "react";
import DialogModal from "./dialogComp";
import { addDecorator, addParameters } from "#storybook/react";
import { Store, withState } from "#sambego/storybook-state";
import { store } from "./../../utils/storyStore";
const DialogModalComp = (props) => {
return [
<div>
<DialogModal
header="Dialog Modal"
displayModal={true}
>
Modal content
</DialogModal>
</div>,
];
};
addDecorator(withState());
addParameters({
state: {
store,
},
});
export default {
title: "dialog",
};
export const DialogModalComponent = () => DialogModalComp;
storybook---main.js
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials",
"#storybook/preset-create-react-app"
]
}
Am I missing something in the configuration?
You'll need to import any styles you use in App.js globally in Storybook, by importing them in .storybook/preview.js (create the file if it doesn't already exist).
Every component in React is self contained - your DialogModal component won't get styled because in Storybook it is not being rendered within your App component (where you're importing your styles).
To simulate your app when using Storybook, you import the css in a preview.js file.
Docs:
To control the way stories are rendered and add global decorators and
parameters, create a .storybook/preview.js file. This is loaded in the
Canvas tab, the “preview” iframe that renders your components in
isolation. Use preview.js for global code (such as CSS imports or
JavaScript mocks) that applies to all stories.
TL;DR
import your styles in .storybook/preview.js
import "../src/index.css";
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};
If you use storybook and emotion, and if you implement Global styles or Theming, you may add a decorator into the .storybook/preview.js like this:
I'm using Create React App, therefore I'm using jsxImportSource
/** #jsxImportSource #emotion/react */
import { Global } from '#emotion/react'
import { GlobalStyles } from '../src/styles'
const withGlobalProvider = (Story) => (
<>
<Global styles={GlobalStyles} />
<Story />
</>
)
export const decorators = [withGlobalProvider]
You may find more information on: https://storybook.js.org/docs/react/essentials/toolbars-and-globals#global-types-and-the-toolbar-annotation
I am kinda new in vue.js
I have a laravel app with vue.js. When hp is loading script also loading all elements are initialised (owl carousel, rev slider etc), but when i click other route contact or about and come back to hp the sliders or other related to js doesnt load .
routes.js
import VueRouter from 'vue-router';
import Home from './components/views/Home.vue';
import About from './components/views/About.vue';
import Contact from './components/views/Contact.vue';
let routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
{ path: '/contact', component: Contact },
{ path: '/notes', component: Notes }
];
export default new VueRouter({
routes,
linkActiveClass: 'active'
});
and app.js
import router from './routes';
import './components';
const app = new Vue({
el: '#app',
router
});
Is there a way to run the functions to load carousels etc each time i change view ?
On mounted trigger you can add your custom js for each component
<script>
export default {
mounted () {
}
}
</script>
if anyone stumbles upon this and still looking for a way to do it, this is how I managed to do this. wrap the <route-view/> in a <transition> which you can control with css and call a method on enter which calls the function you want.
this will call the function as soon as the component is loaded in the DOM on every route change
<transition name="slide" v-on:enter="reInitJS">
<router-view></router-view>
</transition>
<script>
//import the wanted function
import {init} from './main';
export default {
name: 'App',
methods: {
reInitJS(){
//call the function
init();
}
}
}
</script>
I am currently trying to learn reactjs, and i came across on router-react-dom, i was trying to create a dynamic router, and found this solution How to Implement dynamic routing in routes.js for generated menu items in sidebar in universal react redux boilerplate by erikras Solution Option 2 but i could not make it work on my end.
Here is my Main.js
import React, { Component } from 'react';
import { Switch, Route, Link, Redirect, withRouter} from 'react-router-dom'
import Home from './Home'
import Inbox from './Inbox'
import Trash from './Trash'
import Order from './Order'
import Protected from './Protected'
import Login from './Login'
import Forums from './Forums'
import NoMatch from './NoMatch'
import Promos from './Promos'
import SiteRoutes from './Nav'
const Main = () => (
<main>
<Switch>
{SiteRoutes.public.map(route =>
<Route
key={route.index}
path={route.path}
exact={route.exact}
component={route.main}
/>
)}
</Switch>
</main>
)
export default Main;
And here is my Nav.js
import React, { Component } from 'react';
const Data = {
public :[
{
path: "/",
exact: true,
main: 'Home'
},
{
path: "/inbox",
main: 'Inbox'
},
{
path: "/trash",
main: 'Trash'
},
{
path: "/order/:value",
main: 'Order'
},
{
path: "/login",
main: 'Login'
},
{
path: "/forums",
main: 'Forums'
},
{
path: "/promos",
main: 'Promos'
}
]
};
export default Data;
I am trying to map and create a dynamic routes base from the Nav.js, but my problem is on the part of creating the Route on the component={route.main}, which assigns the route.main string value from Nav.js seems to not work in my situation. I followed what was on the link i mentioned above.
When i am clicking the link, console error is
index.js:2178 Warning: <Home /> is using uppercase HTML. Always use lowercase HTML tags in React. i guess because it was a string and wont call the component, but on link i mentioned above seems to work on their end. I am wondering is there something missing in my code?
Thanks in advance.
A string, when passed to React.createElement, creates a DOM element, not a custom component, which are usually only lowercase, hence the warning. Instead, I'd recommend just storing the component classes in Nav.js itself:
import Home from './Home'
import Inbox from './Inbox'
import Trash from './Trash'
import Order from './Order'
import Protected from './Protected'
import Login from './Login'
import Forums from './Forums'
import NoMatch from './NoMatch'
import Promos from './Promos'
const Data = {
public: [
{
path: "/",
exact: true,
main: Home
},
…
]
}
So when React Router creates the component internally, it will create the element from a component class, not a string.
I'm using the react toolbox in my react project. Is there a way to set some default styles which override the styles from react-toolbox?
Wan't to change some colors and paddings?
Thanks for your help.
Can I do this with something like this:
postcssPlugins: [
cssnext({
features: {
customProperties: {
variables: {
'color-primary': 'var(--palette-amber-500)',
},
},
},
}),
solution is to create a theme.js component which overwrites the react-toolbox stuff
import RTInput from './input.css';
import RTTooltip from './tooltip.css'
export default {
RTInput, RTTooltip
};
And then You need a theme-provider .. I did this in index.js
import {ThemeProvider} from 'react-css-themr';
import theme from './styles/react-toolbox-customs/theme.js';
<ThemeProvider theme={theme}>
And wrap your content
thats it.