Share Vue variable across whole Laravel application - performance

I am using a mixin to detect mobile users. Now I don't want to import this mixin into every single component where I need it, because this way I think it is probably running multiple times at the same time.
So I tried to do it like this (in app.js):
import DetectMobile from './mixins/DetectMobile.vue'
const app = new Vue({
el: '#app',
mixins: [ DetectMobile ],
});
But that doesn't work, when I try to access one of the variables from the mixin within a component, I get undefined.

Related

There are any difference in performance having a dictionary object of images?

I want to manage all static resources in my React Native project in the best and mantainable way.
I'm using Image component, and all of this is for passing the local reference of the image, like <Image source={imageReference} />, where imageReference can be get in the next two ways.
I have this:
import mailIcon from '../../../assets/icons/mail.png';
import passwordIcon from '../../../assets/icons/password.png';
import mainLogo from '../../../assets/brand/main-logo.png';
but also have this:
index.js in the assets folder
export const brand = {
mainLogo: require('./brand/main-logo.png'),
logoHorBlanco: require('./brand/logo-hor-blanco.png'),
};
export const icons = {
checked: require('./icons/checked.png'),
unchecked: require('./icons/unchecked.png'),
};
SomeComponent.js in somewhere
import { brand } from '../../assets';
The first way allow me to import only the images that I needed, but is dificult to mantain the paths. The second way, is exported from the assets folder, so when I need an images I just import the right object and use the image that I need with brand.mainLogo (for example).
So I want to know:
If there are differences in performance between the two options.
When im importing the brand object for example, are (in some way) imported (or required, or cached, or something) all images in that object, o just the one that I call with brand.mainLogo.
Thanks.

How can I configure create-react-app to export CSS into two different files

I'm working a project that will dynamically allow the user to change themes, and uses reactstrap and styled-components under the hood. We want to configure all of the variables via SASS, which is working fine. In order to make those variables available to styled-components, we have been using sass-extract-loader to create theme objects.
This all works great when we statically choose one of the themes, but I haven't been able to get it working dynamically reliably. I have two issues:
1) In development, it works fine to switch the theme once. If I change it again, my non-styled-components (i.e., raw reactstrap components) are styled with the second theme. I believe this is because the second theme is loading and overriding the original CSS.
2) In production, I get the same mix as #1 by default (i.e., because all of the CSS files are being put together into a single bundle, reactstrap components are styled one way, while styled-components "honors" the theme).
I believe the best option for us is to have the themes in two separate CSS files, and to toggle "alternate" rels on them. I just don't know how to configure CRA not to put all of the CSS into a single main bundle, and let me manually add links to alternate stylesheets. If I can split them out into separate files, I believe I can just add tags and dynamically swap the rel="alternate" property.
There may well be better ways to accomplish this. My understanding is that the easiest way to control the Bootstrap themes is via SASS variables, and I'd like to make sure those variables don't have to be re-defined when using them in styled-components.
If you want to apply styles conditionally, you can import your stylesheets in your index.js file and make it available to all your components through the context API. First of all we import the CSS files into index.js.
import themeA from './css/themeA.css';
import themeB from './css/themeB.css';
However, by using it this way, you cannot have element selectors in both CSS files, because they would be globally applied from both files. However, you could import an extra stylesheet that complements the selected theme, in which you define the element selectors.
By using CSS modules, you avoid the need for element selectors. You may want to read this article if you are unfamiliar with CSS modules: https://javascriptplayground.com/css-modules-webpack-react/
If you still need to apply element selectors in one theme, you can do so, but they will also get applied in your other theme this way.
import './css/default.css';
This example below is a modified version from the React documentation: https://reactjs.org/docs/context.html
In this example, we draw a button that changes the global theme when
it its clicked. There are three parts in this example that are crucial
to understand if you want to use React its context API.
1. Creating a Context.
Creating a Context is being done by assigning the return value of React.createContext(yourValue) to a variable. This variable can then be used to use the Provider or Consumer component inside your React components.
const ThemeContext = React.createContext();
2. Providing a value by passing it to your Provider component as prop. Now your value is accessible to all your components.
class App extends React.Component {
swapTheme() {
this.setState({ withThemeA: !this.state.withThemeA });
}
render() {
const theme = this.state.withThemeA ? themeA : themeB;
return (
<ThemeContext.Provider value={theme}>
<ThemedButton onClick={this.swapTheme} />
</ThemeContext.Provider>
);
}
}
3. Listening to updates with the Consumer component.
To listen for changes, you need to use the Consumer component. The passed function receives the theme as an argument so it can be assigned to the className prop of the button element.
class ThemedButton extends React.Component {
render() {
return <ThemeContext.Consumer>
{theme => <button className={theme.Button}}>click me</button>}
</ThemeContext.Consumer>;
}
}

What is the correct way to import and use d3 and its submodules in ES6?

I'm trying to use a number of d3 packages in a Vue.js project with NPM for package management. I was trying to make a fiddle of a problem I'm having but am unable to replicate the issue there - the code works exactly as it should do.
I'm trying to identify differences between the code running in JSFiddle and the code running in my app and (aside from obvious fact that I'm not running Vue.js in the fiddle) the big one is how I'm importing my extra libraries. In the fiddle I'm adding links to the relevant libraries from CDNJS while in my app I'm using NPM and import. This is all to run charts using dc, which builds on a lot of d3 features. My complete imports for the chart component is:
import dc from 'dc'
import crossfilter from 'crossfilter2'
import * as time from 'd3-time'
import * as scale from 'd3-scale'
I'm not using any features from the base d3 module.
The fiddle in question is here: https://jsfiddle.net/y1qby1xc/10/
I am now using the following structure in my Vue projects. I am making a separate file to import all the needed modules and to export them all at once.
In ./src/assets/d3/index.js:
import { select, selectAll } from 'd3-selection';
import {
scaleLinear,
scaleTime,
scaleOrdinal,
schemeCategory10,
} from 'd3-scale';
import { axisTop } from 'd3-axis';
export default {
select,
selectAll,
scaleLinear,
scaleTime,
scaleOrdinal,
schemeCategory10,
axisTop,
};
Then I import everything into my component and I am able to use all functions with their d3 prefix: d3.select, d3.selectAll etc.
In ./src/components/MyComponent.vue:
<template>
</template>
<script>
import d3 from '#/assets/d3';
export default {
data() {
return {
};
},
};
</script>

Single Page Application on a dynamic path with Vue Router but using same component?

I'm not sure how to tackle my problem. I've the requirement to do a single page application (SPA) with Vue & Laravel within a specific dynamic path.
For example:
www.buying.dev/usernameXY/new-fresh-phone
Shows you the current Sellitem with the Title New Fresh Phone and it's description + Image of usernameXY and sellitem
Below that you can find his most popular items but also items from other users.
Just to visualise it I show you a super fast sketch:
So for backend I use Laravel.
Route::prefix('/{username}')->group(function () {
Route::get('/', 'UserProfileController#show');
Route::get('/reviews', 'UserProfileController#reviews');
Route::get('/{selllink}', 'BuyController#show'); //Here comes the SPA
});
If the user scrolls down below he will find other items as well, when he clicks on it the URL changes to
www.buying.dev/usernameYY/new-awesome-gadget
The change of the url should not refresh the complete page, but just update what is on the top.
For a solution comes Vue Router in my mind, but I never used it with Laravel Route and Vue Route at the same time.
Besides, normally you just call with VueRouter components to see the page such as
routes: [
{
path: '/',
name: 'home',
component: Home
}]
But I would only use one component buy.vue. I don't know how I would combine it, with perhaps
Route::prefix('/{username}')->group(function () {
Route::get('/', 'UserProfileController#show');
Route::get('/reviews', 'UserProfileController#reviews');
Route::any('/{selllink}', 'BuyController#show')
->where(['selllink' => '.*']);
});
But then I don't know how to use Vue Router, because what do I call?
routes: [
{
path: '/*/*', // /Username/Itemname ??
name: 'buy',
component: buy.vue
}]
So I'm lost and I don't what to do.
My alternative is that I don't use Vue Router and therefor are not able to change the URL dynamically.
I could use v-cloak to hide the whole page, only showing when it's mounted/created.
So my question to you is, how would you develop a single page application on a specific dynamic path and also having only one component to use? Or is it possible to change the URL without Vue Router?
I hope it was understandable
Thank you!
you can use dynamic path parameters in vue Router.
path: '/page/:lang/*'
component: MyComponent
and something like
Vue.config.lang = to.params.lang
during beforeEnter to handle the params.

Asynchronous loading of partial view in Ember

I've created an Ember helper to allow for loading a dynamically generated partial view from a URL on the server. It looks like this:
Ember.Handlebars.helper('serverPartial', function(url, options) {
var template;
$.ajax(url, {
async: false,
success: function(templateText){
template = Ember.Handlebars.compile(templateText);
}
});
template(this, options);
});
And it's called from a parent Handlebars template like this:
{{serverPartial templateUrl}}
As you can see, the ajax call to retrieve the template from the server is a synchronous call, because I couldn't find any other way to return the template contents as expected by the Ember framework. Unfortunately, this synchronous call holds up the rendering of the entire parent template.
Is there a way to return a promise for the template, or any other way to allow partial views to load asynchronously or independently?
Thanks for the tip, #Rajat. I did end up using Views to accomplish this. I created a view container that initially loads a default child template, then that child loads in the actual contents from the server after it is inserted. Here's the approach I took:
App.LoadingView = Ember.View.extend({
didInsertElement: function(){
var container = this._parentView;
$.get('http://server/serverTemplate', function(data){
container.pushObject(Ember.View.create({
template: Ember.Handlebars.compile(data)
}));
container.removeObject(container.get('loadingView'));
});
},
template: Ember.Handlebars.compile('client awesome')
});
// inherit from ContainerView and initialize with default content
App.SnippetView = Ember.ContainerView.extend({
childViews: ['loadingView'],
loadingView: App.LoadingView.create()
});
I'm sure there are better ways to express this, but does the job at a minimum.
First, what you are trying to do with Handlebars helpers is not what they are intended to do. Handlebars helpers are strictly markup formatters and should be used for simple HTML adjustments.
Second, in typical ember apps, what you are trying to do is never done. There is no 'on-demand' fetching of templates.
This is because all templates are downloaded in one sweep when the app loads and live on client. They are precompiled to JavaScript functions and stored as Strings in the Ember.Handlebars hash.
They are downloaded when the app loads and then get evaluated when the view is rendered. In the meantime, they live simply as Strings.
Now if you still want to do what you are doing, I would recommend trying to do that in Views.

Resources