I am still new to Laravel and web packs.
I am trying to install FullCalendar via NPM into my Laravel project - Previously I have been working with includes from cdnjs, but I want to learn the other way. What I have done so far is:
https://fullcalendar.io/docs/initialize-es6
npm install #fullcalendar/core #fullcalendar/daygrid #fullcalendar/timegrid #fullcalendar/list
Then I updates my app.js in Laravel to
require('./bootstrap');
require('fullcalendar');
import { Calendar }from '#fullcalendar/core';
import dayGridPlugin from '#fullcalendar/daygrid';
import listPlugin from '#fullcalendar/list';
I also updates app.css
#tailwind base;
#tailwind components;
#tailwind utilities;
#fullcalendar/core/main.css;
#fullcalendar/daygrid/main.css;
#fullcalendar/timegrid/main.css;
#fullcalendar/list/main.css;
Then I ran
npm run dev
In blade file, I re-use the code from when I was working with script file from cdnjs. I added the updated app.js file, which was compiled through npm run dev
<div id="calendar"></div>
<script>
$(document).ready(function() {
// page is now ready, initialize the calendar...
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: [ 'dayGrid','List'],
header: {
left: 'prev,next today',
right: 'dayGridWeek,listWeek'
},
defaultView: 'dayGridWeek',
contentHeight: 'auto',
events : [
#foreach($events as $event)
{
title : '{{ $event->title }}',
start : '{{ $event->start_event }}',
},
#endforeach
]
});
calendar.render();
});
</script>
<script src="{{ asset('js/app.js') }}"></script>
The error I get is:
I don't understand why, and I have been playing around with app.js and re-compiling it a bunch of times and changing order of my code.. nothing works. What am I missing?
I had similar issue, made mine work this way:
//app.js
...
import { Calendar } from '#fullcalendar/core';
window.Calendar = Calendar;
import interaction from '#fullcalendar/interaction';
window.interaction = interaction;
import dayGridPlugin from '#fullcalendar/daygrid';
window.dayGridPlugin = dayGridPlugin;
import timeGridPlugin from '#fullcalendar/timegrid';
window.timeGridPlugin = timeGridPlugin;
import listPlugin from '#fullcalendar/list';
window.listPlugin = listPlugin;
...
Then, I use it on pages that require me to render fullcalendar like so:
//somescript.js
...
var calendar = new window.Calendar($('#calendar').get(0), {
plugins: [window.interaction, window.dayGridPlugin, window.timeGridPlugin, window.listPlugin],
selectable: true,
initialView: 'dayGridMonth',
eventBorderColor: 'white',
eventClick: info => { ... },
dateClick: info => { ... },
select: info => { ... }
...
});
calendar.render();
...
For styling,
//app.scss
// Variables
#import 'variables';
// Fullcalendar
#fullcalendar/core/main.css;
#fullcalendar/daygrid/main.css;
#fullcalendar/timegrid/main.css;
#fullcalendar/list/main.css;
Should this line:
var calendar = new FullCalendar.Calendar(calendarEl, {
Be changed to this:
var calendar = new Calendar(calendarEl, {
Thats what I gather from looking over https://fullcalendar.io/docs/initialize-es6
Here is a good example:
https://github.com/fullcalendar/fullcalendar-example-projects/blob/master/webpack/src/main.js
Let's say I have a simple Angular Component:
#Component({
selector: 'app-email-content',
template: '<h1>Welcome {{username}}!</h1>'
})
export class WelcomeEmailComponent {
#Input() username: string
}
My goal is to take this Angular component and render it to plain HTML with Node.Js, to send customized EMails.
I know that Server-side rendering is definitely possible with Angular Universal. But I am not sure how to explicitly render one specific component.
The approach is to send an Angular component-based dynamically generated templates to users' email from the Angular SSR project.
Find the example repository at the bottom of this answer.
The steps you need to follow;
Design your templates in an individual routing path that is dedicated to showing only the email templates not your navigation bars, global CSS, etc.
Example:
welcome-email-component.component.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-welcome-email-component',
templateUrl: './welcome-email-component.component.html',
styleUrls: ['./welcome-email-component.component.css']
})
export class WelcomeEmailComponentComponent implements OnInit {
username: any;
constructor(private route: ActivatedRoute) { }
ngOnInit(): void {
this.route.params.subscribe(params => {
this.username = params.username;
});
}
}
welcome-email-component.component.html
<style>
.title-p {
color: #00025a;
font-size: 20px;
font-weight: bold;
}
</style>
<p class="title-p">Welcome {{username}}</p>
You need to specify a route for this component as below, so when the user navigates to the welcome-email/username route it should show only the email template generated component.
{ path: 'welcome-email/:username', component: WelcomeEmailComponentComponent }
Implement Angular SSR to your project from the great Angular SSR guidelines, Server-side rendering (SSR) with Angular Universal.
It's just two lines of code.
ng add #nguniversal/express-engine
npm run dev:ssr
Finally create a server-side API to generate the template from your Angular component and send emails or provide the HTML code of the single component, add the API function in your server.ts as below.
server.ts
server.get('/api/send-email/:username', (req, res) => {
// Below is the URL route for the Angular welcome mail component
request(`http://127.0.0.1:4200/welcome-email/${req.params.username}`, (error, response, body) => {
// TODO : Send email to the user from WelcomeEmailComponentComponent.ts component as `body`
// use the body to send email
res.send('Email sent');
});
});
Example code: https://github.com/aslamanver/angular-send-component-email
The demonstration of a dynamically generated component on this repository;
Finally when you access /api/send-email/:username, this will generate the welcome mail component and give the HTML body of that, thereafter you can proceed with your email sending function.
I clap #Googlian's answer. But, angular produces too much unfamiliar HTML5, CSS3 and angular specific bundled features, so after that you have to remove those one by one specifically if you want a real valid email content, otherwise your email most probably will be considered as spam bu mailclients.
I sugges that you mah have a component with xHTML standarts with no-CSS3, no-experimental HTML5 features, and build an email templete with this and ElementRef, then parse required fields manually.
Send the string to serverside, nodejs, then send it as email. You can use nodemailer
I' am creating a Vue component that shows an SVG image from my node modules based on a given image name or key (given by an API).
If I put the source image directly like ~cryptocurrency-icons/svg/color/eur.svg, the resource loads.
But if I try to compute it with the props or by the mounted method asigning it using :src="imageSource" it does not load.
I'm new to Vue so I don't know why is this happening? Should I use images downloaded in a public directory instead of the NPM package?
<template lang="html">
<img src="~cryptocurrency-icons/svg/color/eur.svg" alt="icon" />
</template>
<script lang="js">
export default {
name: 'crypto-icon',
props: ['currency'],
mounted() {
this.imageSource = `~cryptocurrency-icons/svg/color/${this.currency}.svg`
},
data() {
return {
imageSource: ""
}
},
methods: {
getImageResource(){
return `~cryptocurrency-icons/svg/color/${this.currency}.svg`
}
},
computed: {
}
}
</script>
<style lang="scss" scoped>
.crypto-icon {}
</style>
You are missing the require attribute. Vue Loader, does this automatically when it compiles the <template> blocks in single file components. Try with this:
require(`~cryptocurrency-icons/svg/color/${this.currency}.svg`)
You can read more here.
I've solved it by using a Vue plugin (see vue-cryptoicons), although hatef is right about using require for image resources, using it in directories under node_modules tries to find the full path
~cryptocurrency-icons/svg/color in ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"a7e19d86-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/Wallet.vue?vue&type=template&id=7f1455a9&scoped=true&lang=html&
To install it, you can run: npm install --save ~cryptocurrency-icons/svg/color
I'm having difficulty with differences between client-side and server-side rendering of styles in Material-UI components due to classNames being assigned differently.
The classNames are assigned correctly on first loading the page, but after refreshing the page, the classNames no longer match so the component loses its styling. This is the error message I am receiving on the Console:
Warning: Prop className did not match.
Server: "MuiFormControl-root-3 MuiFormControl-marginNormal-4
SearchBar-textField-31"
Client: "MuiFormControl-root-3 MuiFormControl-marginNormal-4
SearchBar-textField-2"
I've followed the Material-UI TextField example docs, and their accompanying Code Sandbox example, but I can't seem to figure out what is causing the difference between the server and client classNames.
I experienced a similar issue when adding Material-UI Chips with a delete 'x' icon. The 'x' icon rendered with a monstrous 1024px width after refreshing. The same underlying issue being that icon was not receiving the correct class for styling.
There are a few questions on Stack Overflow addressing why the client and server might render classNames differently (e.g. need to upgrade to #Material-UI/core version ^1.0.0, using a custom server.js, and using Math.random in setState), but none of these apply in my case.
I don't know enough to tell whether this Github discussion might help, but likely not since they were using a beta version of Material-UI.
Minimal steps to reproduce:
Create project folder and start Node server:
mkdir app
cd app
npm init -y
npm install react react-dom next #material-ui/core
npm run dev
edit package.json:
Add to 'scripts': "dev": "next",
app/pages/index.jsx:
import Head from "next/head"
import CssBaseline from "#material-ui/core/CssBaseline"
import SearchBar from "../components/SearchBar"
const Index = () => (
<React.Fragment>
<Head>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charSet="utf-8" />
</Head>
<CssBaseline />
<SearchBar />
</React.Fragment>
)
export default Index
app/components/SearchBar.jsx:
import PropTypes from "prop-types"
import { withStyles } from "#material-ui/core/styles"
import TextField from "#material-ui/core/TextField"
const styles = (theme) => ({
container: {
display: "flex",
flexWrap: "wrap",
},
textField: {
margin: theme.spacing.unit / 2,
width: 200,
border: "2px solid red",
},
})
class SearchBar extends React.Component {
constructor(props) {
super(props)
this.state = { value: "" }
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
this.setState({ value: event.target.value })
}
handleSubmit(event) {
event.preventDefault()
}
render() {
const { classes } = this.props
return (
<form
className={classes.container}
noValidate
autoComplete="off"
onSubmit={this.handleSubmit}
>
<TextField
id="search"
label="Search"
type="search"
placeholder="Search..."
className={classes.textField}
value={this.state.value}
onChange={this.handleChange}
margin="normal"
/>
</form>
)
}
}
SearchBar.propTypes = {
classes: PropTypes.object.isRequired,
}
export default withStyles(styles)(SearchBar)
Visit page in browser localhost:3000 and see this:
red border around TextField component
Refresh the browser and see this:
TextField component's styles are gone
Notice that the red border around TextField disappears.
Relevant Libs:
"react": 16.4.0
"react-dom": 16.4.0
"next": 6.0.3
"#material-ui/core": 1.2.0
The problem is the SSR rendering in Next.js, which produces the style fragment before the page is rendered.
Using Material UI and Next.js (as the author is using), adding a file called _document.js solved the problem.
Adjusted _document.js (as suggested here):
import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '#material-ui/styles'; // works with #material-ui/core/styles, if you prefer to use it.
import theme from '../src/theme'; // Adjust here as well
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
{/* Not exactly required, but this is the PWA primary color */}
<meta name="theme-color" content={theme.palette.primary.main} />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's compatible with server-side generation (SSG).
MyDocument.getInitialProps = async (ctx) => {
// Resolution order
//
// On the server:
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. document.getInitialProps
// 4. app.render
// 5. page.render
// 6. document.render
//
// On the server with error:
// 1. document.getInitialProps
// 2. app.render
// 3. page.render
// 4. document.render
//
// On the client
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. app.render
// 4. page.render
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
};
};
This problem is related to MUI using dynamic class name which contain an ID. The IDs from the server side rendered CSS are not the same as the client side CSS, hence the mismatch error. A good start is to read the MUI SSR documentation
If you have this problem with nextjs (as I did) follow the example provided by the MUI team, which can be found here: material-ui/examples/nextjs
The most important part is in "examples/nextjs/pages/_app.js":
componentDidMount() {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}
the related ticket can be found here: mui-org/material-ui/issues/15073
what it does, is remove the server side rendered stylesheet and replace it by a new client side rendered one
The issue is the server side generates the class names but style sheets are not automatically included in the HTML. You need to explicitly extract the CSS and append it to the UI for the server side rendered components. The whole process is explained here: https://material-ui.com/guides/server-rendering/
There is one other important, separate issue here: Material UI V4 is not React Strict Mode compatible. Strict mode compatibility is slated for version 5 with the adoption of the Emotion style engine.
Until then, be sure you disable React Strict Mode. If you're using Next.js, this is turned on by default if you've created your app using create-next-app.
// next.config.js
module.exports = {
reactStrictMode: false, // or remove this line completely
}
I had the same problem with Next.js and styled component, with the transpilation by Babel. Actually, the class names are different on the client and the server side.
Fix it in writing this in your .babelrc :
{
"presets": ["next/babel"],
"plugins": [
[
"styled-components",
{ "ssr": true, "displayName": true, "preprocess": false }
]
]
}
I met this problem on Material-ui V5. The solution to fix this problem is to make sure that class name generator needs to behave identically on the server and on the client.
so adding the code below in your _app.js:
import { StylesProvider, createGenerateClassName } from '#mui/styles';
const generateClassName = createGenerateClassName({
productionPrefix: 'c',
});
export default function MyApp(props) {
return <StylesProvider generateClassName={generateClassName}>...</StylesProvider>;
}
// 1 . Warning: prop classname did not match. Material ui with React Next.js
// 2 . Use your customization css here
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
title: {
flexGrow: 1,
},
my_examle_classssss: {
with: "100%"
}
}));
// 3 . Here my Component
const My_Example_Function = () => {
const classes = useStyles();
return (
<div className={classes.root}>
<Container>
<Examle_Component> {/* !!! Examle_Component --> MuiExamle_Component*/}
</Examle_Component>
</Container>
</div>
);
}
export default My_Example_Function
// 4. Add name parameter to the makeStyles function
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
title: {
flexGrow: 1,
},
my_examle_classssss: {
with: "100%"
},
}), { name: "MuiExamle_ComponentiAppBar" });
{/* this is the parameter you need to add { name: "MuiExamle_ComponentiAppBar" } */ }
{/* The problem will probably be resolved if the name parameter matches the first className in the Warning: you recive..
EXAMPLE :
Warning: Prop `className` did not match.
Server: "MuiSvgIcon-root makeStyles-root-98"
Client: "MuiSvgIcon-root makeStyles-root-1"
The name parameter will be like this { name: "MuiSvgIcon" }
*/ }
I like to share this mismatching case:
next-dev.js?3515:32 Warning: Prop className did not match. Server:
"MuiButtonBase-root MuiIconButton-root PrivateSwitchBase-root-12
MuiSwitch-switchBase MuiSwitch-colorSecondary" Client:
"MuiButtonBase-root MuiIconButton-root PrivateSwitchBase-root-12
MuiSwitch-switchBase MuiSwitch-colorSecondary
PrivateSwitchBase-checked-13 Mui-checked"
On client there are two more classes which means that the behavior on client-side is different. In this case, this component shouldn't render on server-side. The solution is to dynamically render this component:
export default dynamic(() => Promise.resolve(TheComponent), { ssr: false });
I had a problem with different classNames for client and server. I was using React, Material-UI, makeStyles and SSR (server-side rendering).
The error was:
Warning: Prop `className` did not match. Server: "jss3" Client: "App-colNav-3"
I spent several hours before I figured out that I had discrepancy in webpack mode for client and server. The scripts in package.json were:
"devServer": "webpack --config webpack.server.config.js --mode=production --watch",
"devClient": "webpack --mode=development --watch",
After I changed both to have development mode, the problem was solved :)
"devServer": "webpack --config webpack.server.config.js --mode=development --watch",
"devClient": "webpack --mode=development --watch",
If somebody is still struggling even after trying above solutions, Try this
If you have used noSsr prop in any of your components or theme, then remove it.
I had the following config in mui theme object, which was causing this problem.
import { createTheme, responsiveFontSizes } from "#mui/material/styles";
let theme = createTheme({
components: {
MuiUseMediaQuery: {
defaultProps: {
noSsr: true,
},
},
},
palette: {
mode: "light",
common: {
black: "#000",
white: "#fff",
},
primary: {
main: "#131921",
contrastText: "#fff",
},
secondary: {
main: "#fb6a02",
contrastText: "#fff",
}
}
})
RemovingnoSSr fixed all of the issues in my app including style mismatch between client and server.
The problem is cause by Nextjs server side rendering. In order to solve I do as following:
Make a component to detect whether is it from Client side
import { useState, useEffect } from "react";
interface ClientOnlyProps {}
// #ts-ignore
const ClientOnly = ({ children }) => {
const [mounted, setMounted] = useState<boolean>(false);
useEffect(() => {
setMounted(true);
}, []);
return mounted ? children : null;
};
export default ClientOnly;
Wrap my page component using ClientOnly component
export default function App() {
return (
<ClientOnly>
<MyOwnPageComponent>
</ClientOnly>
);
}
So the idea is, if it is client side then only render the component on the page. Therefore if current rendering is from Client side, render <MyOwnPageComponent>, else render nothing
In my case the issue happened because of different compilation modes of webpack for client-side code and server-side: client's bundle was generated by webpack using "production" mode, while server ran some SSR code from a package optimized for "development". This created a different "className" hash in styled-components in generateAndInjectStyles():
if (process.env.NODE_ENV !== 'production') dynamicHash = phash(dynamicHash, partRule + i);
So my fix was just to align the webpack modes.
You can add the name in anywhere you use makeStyles, like this:
const useStyles = makeStyles({
card: {
backgroundColor: "#f7f7f7",
width: "33%",
},
title: {
color: "#0ab5db",
fontWeight: "bold",
},
description: {
fontSize: "1em"
}
}, { name: "MuiExample_Component" });
I am not sure how it works, but I found it here: Warning: Prop `className` did not match ~ Material UI css arbitrarily breaks on reload
I'm also using NextJS + MUI v5 and I ran into this exact error right after merging Git branches. I suspect the merge corrupted something in the cache. I deleted the contents of .next/ and restarted the dev server and the error went away.
#Leonel Sanches da Silva's answer didn't work for me, as #material-ui/styles is deprecated, but using a snippet I found for another (non-material UI) project seems to have worked just fine for me:
Hat tip to Raul Sanchez on dev.to for the answer to this one.
Next doesn't fetch styled-components styles on the server, to do that you need to add this page to pages/_document.js:
import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
})
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
}
} finally {
sheet.seal()
}
}
}
This code may update, so check Next's styled-components example for the latest.
So currently I am working with VueJS 2 and I am very new with it. Now I was getting some help with some other people, but I am still stuck.
Here is what I want to achieve (example - closely linked to what I want):
I have a NodeJS application that listens on WebSockets. The application listens for connections via WebSocket and will take JSON data, with a command and then a data object with any content needed for that command.
The command for example could be login, and the data be username and password. The login function on the NodeJS application will then take this data, do what it needs and then return it back over the socket, whether it was successful or not, and maybe include an ID and some user information for Vuex to pickup and place in it's state, for the front-end of the application to pick up/use.
Currently I am using this boiler plate: https://github.com/SimulatedGREG/electron-vue
Which has served me very well as a learning curve, due to me wanting to use Vue and Vuex to manage my application and then use WebSockets for managing data to and from the data server.
So if you look at the link I sent in app/src/renderer/ (this is where the main code is for vue and vuex).
A friend of mine added the following code for me as an example and I am stuck trying to get it into vuex as actions and mutations. He made it all in one vue component, so I am struggling on how it works with vuex. As I want to be able to access the (example) loginUser action from anywhere in the application (uses routes for multiple pages/views).
So in the MyApp/app/src/renderer/components/LandingPageView.vue
<template>
<div>
<img src="./LandingPageView/assets/logo.png" alt="electron-vue">
<h1>Welcome.</h1>
<current-page></current-page>
<websocket-output></websocket-output>
<versions></versions>
<links></links>
</div>
</template>
<script>
import CurrentPage from './LandingPageView/CurrentPage'
import Links from './LandingPageView/Links'
import Versions from './LandingPageView/Versions'
import WebsocketOutput from './LandingPageView/WebsocketOutput'
export default {
components: {
CurrentPage,
Links,
Versions,
WebsocketOutput
},
name: 'landing-page'
}
</script>
<style scoped>
img {
margin-top: -25px;
width: 450px;
}
</style>
That is the updated file for that, and then below is the code for the MyApp/app/src/renderer/components/LandingPageView/WebsocketOutput.vue
<template>
<div>
<h2>Socket output:</h2>
<p v-text="socket_out"></p>
</div>
</template>
<script>
var ws = require("nodejs-websocket")
export default {
data () {
return {
socket_out: "connecting to the websocket server..."
}
},
mounted () {
const parent = this
var connection = ws.connect("ws://dannysmc.com:9999", {}, function (conn) {})
connection.on("text", function (text) {
console.log('Text received: ' + text)
parent.socket_out = text
})
connection.on("connect", function () {
connection.send('yo')
})
},
created () {
// Set $route values that are not preset during unit testing
if (process.env.NODE_ENV === 'testing') {
this.$route = {
name: 'websocket-output',
path: '/websocket-output'
}
}
}
}
</script>
<style scoped>
code {
background-color: rgba(46, 56, 76, .5);
border-radius: 3px;
color: #fff;
font-weight: bold;
padding: 3px 6px;
margin: 0 3px;
vertical-align: bottom;
}
p {
line-height: 24px;
color: red;
}
</style>
Everything else is just the boiler plate that you see, so if anyone is willing to help me and give me some tips of what to read that explains this or anything else? as I can't find much information on it unfortunately.
I have an electron application that uses Vue and a websocket for information and here is how I set mine up.
I have a store defined that also actually creates and sets up the websocket.
Store.js
const socket = require("socket-library") // Take your pick of socket libs
const mySocket = new socket(...)
mySocket.on("message", message => store.handleMessage(message))
...other handlers...
const store = {
handleMessage(message){
// do things with the message
}
}
export default store
Renderer.js
import store from "./store"
new Vue({
data:{
store
}
})
This exposes my store at the root level of my Vue and allows me to pass data to components, or what have you. The store manages all the incoming information from the websocket.
With you wanting to use Vuex, you could do essentially the same thing, where Vuex would be your store and when messages come in over the socket, you just pass them to Vuex.
mySocket.on("message", msg => vuexStore.dispatch("onSocketMessage", msg))
and set up your Vue and components to work with Vuex as you typically would.