Passing twig data to vue js in symfony 4 - symfony

I am using a component named "vue-cookie-law in my symfony application so I call it like that in my base (default twig template):
<div id="CookieLaw" data-locale="{{ app.request.locale }}"></div>
and then in my vue template I have this:
<template>
<div id="CookieLaw">
<cookie-law theme="base" transitionName="slideFromBottom">
<div slot="message">{{ locale }}En poursuivant votre navigation sur notre site vous acceptez l'utilisation de cookies, pour vous proposer des contenus personnalisés en fonction de vos centres d'intérêt et mesurer la fréquentation de nos services, pour en savoir plus et paramétrer les cookies, cliquez ici </div>
</cookie-law>
</div>
</template>
<script>
import CookieLaw from 'vue-cookie-law'
export default {
data() {
return {
locale: ""
}
},
components: { CookieLaw },
beforeMount: () => {
this.locale = this.$el.attributes['data-locale'].value;
}
}
</script>
<style scoped>
.Cookie {
background: white;
padding: 2rem;
}
</style>
And my js part :
import Vue from 'vue';
import CookieLaw from './components/CookieLaw';
new Vue({
el: '#CookieLaw',
render: h => h(CookieLaw)
});
So I try to pass the locale variable of my app but I have an error like that :
[Vue warn]: Error in beforeMount hook: "TypeError: _this.$el is undefined
So it seems I can't access my data attributes like that. Any idea on what I'm doing the wrong way here ? could it be a conflict between twig and vue ?

Have you checked the value of this.$el? I suspect that it targets <div id="CookieLaw" data-locale="{{ app.request.locale }}"></div> but in that case the latter element would be replaced by your Vue template.
If that's the case you should put the data-attribute in an element over it and instead of this.$el.attributes['data-locale'].value you write this.$el.previousElementSibling.getAttribute('data-locale').value
I would like to add also that your lifecycle hook is beforeMount but your element does not still exist at this point; try with mounted()instead

Related

Data communication between two userInterface (ui) - Apps script refer to client instantiated sidebar

For the use of a google sheet stock management by several people, I use a sidebar for authentication (login). This running well, but i would like to allow different and simultaneous authentications (on different client computers)
In fact, my google scripts andZ html forms (integrated in userInterfaces) should be able to know and use the current agent, memorized by a sidebar field, as long as it is not closed.
I tried to use userProperties, scriptProperties, documentProperties,and cacheService but the connected agent is then memorized and common for all users instead of being specific to each workstation running the application. I have to work on the client side.
I know how to read and modify the DOM of the sidebar by the javascript code that i place there and also to recover this information within my google script. But here it is in fact a question of finding information from the instantiated sidebar.
My Apps Script:
function init_SideBar(e) { // init & show the sidebar
htmlSideBar = HtmlService.createHtmlOutputFromFile('htmlSideBar')
.setTitle('htmlSideBar')
.setWidth(300);
htmlSideBar.info="blabla"; // could it be a lead ?
SpreadsheetApp.getUi().showSidebar(htmlSideBar);
}
function gScriptFcGiveToSidebar() { // to send datas in an array to html page
let jSONforSheet= JSON.stringify(objForSheet);
return jSONforSheet;
}
function calledFromFormSubmit(sidebarForm) { // Receive datas from html sidebar
agentConnected=sidebarForm;
if(agentConnected=="Deconnecté"){
ss.toast("Deconnecté")
}else{
ss.toast("Bonjour "+agentConnected);
}
}
htmlSideBar.html:
<html>
<head>
<title>HTML DOM Objects</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
</head>
<body>
<label for="dowloading">dowloading</label>
<script>
function submitForm() { // envoi les données du form "sidebarForm" vers la fonction qui dans google script va les récupérer
// login & password verification (tablUser contains a column au login and a column of mp)
var elmts=document.getElementById("sidebarForm");
for(let iUsers=0;iUsers<sidebarObj.tablUser.length;iUsers++){
if (sidebarObj.tablUser[iUsers][0]==elmts.agentId.value){
if(sidebarObj.tablUser[iUsers][1]==elmts.mpId.value ){
document.getElementById('labelConnectId').innerHTML =elmts.agentId.value;
google.script.run.calledFromFormSubmit(elmts.agentId.value);
return;
}
}
}
alert ("password false, try again");
}
function deconnect(){
document.getElementById('labelConnectId').innerHTML ="Deconnecté";
document.getElementById('agentId').value ="Deconnecté";
google.script.run.calledFromFormSubmit("Deconnecté");
}
function jsFcGiveToForm(jSONforSheet){ //
$('#rangeResult').text(jSONforSheet); //$('#rangeResult').text(<nom de la variable qui va finalement délivrer au js, les données du google script>)
sidebarObj=JSON.parse(jSONforSheet);
document.write('<label id="labelConnectId" form="sidebarForm" > '+sidebarObj.agentConnected+'</label>');
document.write('<br><input type="button" value="Deconnect" onclick="deconnect();" />');
document.write('<form id="sidebarForm">');
document.write('<select name="agent" id="agentId">');
document.write('<option value="'+sidebarObj.agentConnected+'">'+sidebarObj.agentConnected+'</option>');
for(let iUsers=0;iUsers<sidebarObj.tablUser.length;iUsers++){
document.write('<option value="'+sidebarObj.tablUser[iUsers][0]+'">'+sidebarObj.tablUser[iUsers][0]+'</option>');
}
document.write('</select>');
document.write('<br /><input type="text" name="mp" id="mpId" value="password">');
document.write('<br /><input type="button" value="Submit" onclick="submitForm();" />');
document.write('<input type="button" value="Close" onclick="google.script.host.close()" />');
}
document.close(); // HYPER IMPORTANT !! libere le navigateur pour qu il continu a charger la page
google.script.run.withSuccessHandler(jsFcGiveToForm).gScriptFcGiveToSidebar();
</script>
</form>
</body>
</html>
Some leads ? :
Must i use scriptless
<?= blablabla?>
Using Meta tags :
var x = document.createElement("META");
x.setAttribute("name", "description");
x.setAttribute("content", "blablabla");
document.head.appendChild(x);
Using a property of htmlOutpu:
htmlSideBar.info="blabla";
Thanks a lot for your participation ! :)
I found a solution and described the sequences using the commented steps A1-4 and B1-12) which you just have to follow
Sidebar.gs:
function init_SideBar(e) { //A-1) init & show the sidebar.html
htmlSideBar = HtmlService.createHtmlOutputFromFile('htmlSideBar')
.setTitle('htmlSideBar')
.setWidth(300);// n'est plus modifiable fixé par google à 300 px
htmlSideBar.info="blabla";
HtmlService.SandboxMode=HtmlService.XFrameOptionsMode;
SpreadsheetApp.getUi().showSidebar(htmlSideBar);
}
function gScriptFcGiveToSidebar() { // A-3) to send google sheet datas (array or json...) to htmlSideBar.html page
let jSONforSheet= JSON.stringify(objForSheet);
ss.toast("json"+jSONforSheet);
return jSONforSheet;
}
function gScriptFromSidebarThenGiveToFormIn(sidebarAgent,provenanceFlag){
//Browser.msgBox("2 4 sidebarAgent="+sidebarAgent+" cache="+cacheService.get('sidebarAgent')+"init="+init);
if (provenanceFlag==false) { // B-7) Called by the de html htmlFormIn...withSuccessHandler(jsFcGiveToFormIn)
// Utilities.sleep(8000); // simulating an excess of a retention time of the cache
sidebarAgent=cacheService.get('sidebarAgent'); // B-8) Retieve the useful data in the cache
if (sidebarAgent==null) {return "echec";} // B-9) Abort in case the cache got lost (retention time exceeded)
cacheService.remove('sidebarAgent'); // B-10) Free the cache
return sidebarAgent; //B-11) give to formIn.html the data it expects
}else{ // B-2) provenanceFlag=true means that the call is from the htmlSideBar.html file buton.onclick , (sidebarAgent has the useful data)
if (cacheService.get('sidebarAgent')!=null) return false // B-3) cache not freed, abort proces for try again in a few time
cacheService.put('sidebarAgent',sidebarAgent,5); // B-4) Stock in cache the data for 5 secondes
initFormIn(sidebarAgent); //B5 open the user interface formIn.html that will have to take imediately the data in the cache, then free it
}
}
function calledFromFormSubmit(sidebarForm) { // Receive datas from html sidebar
agentConnected=sidebarForm;
//userProperties.setProperty('agentConnected', agentConnected);
if(agentConnected=="Deconnecté"){
ss.toast("Deconnecté")
}else{
ss.toast("Bonjour "+agentConnected);
}
//SpreadsheetApp.getActiveSheet().appendRow(["test",sidebarForm]);
}
htmlSideBar.html:
<!DOCTYPE html>
<html>
<head>
<style>
body { font-size:1em; }
p { color : red; }
</style>
<title>HTML DOM Objects</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
</head>
<body>
<label for="dowloading">dowloading</label>
<?= info?>
<script>
function callFormIn(){ google.script.run.gScriptFromSidebarThenGiveToFormIn(document.getElementById("labelConnectId").innerHTML,true);
}
function submitForm() { // My connect process
var elmts=document.getElementById("sidebarForm");
for(let iUsers=0;iUsers<sidebarObj.tablUser.length;iUsers++){
if (sidebarObj.tablUser[iUsers][0]==elmts.agentId.value){
if(sidebarObj.tablUser[iUsers][1]==elmts.mpId.value ){
document.getElementById('labelConnectId').innerHTML =elmts.agentId.value;
google.script.run.calledFromFormSubmit(elmts.agentId.value);
return;
}
}
}
alert ("mp faux");
}
function writeLabelAndTxtBox(name,id,value){
document.write('<br /><label for="'+name+'">'+name+': </label>');
document.write('<br /><input type="text" name="'+name+'" id="'+id+'" value="'+value+'">');
}
function writeLabel(name){
document.write('<br /><label for="'+name+'">'+name+': </label>');
}
function writeTxtBox(name,id,value){
document.write('<br /><input type="text" name="'+name+'" id="'+id+'" value="'+value+'">');
}
// -----------------------------------------------------------------------------------------------------------------
function clearAndClose(){
google.script.host.close();
}
function deconnect(){
document.getElementById('labelConnectId').innerHTML ="Deconnecté";
document.getElementById('agentId').value ="Deconnecté"; // facultatif ?
google.script.run.calledFromFormSubmit("Deconnecté");
}
function jsFcGiveToSidebar(jSONforSheet){ // A-4) I can Fill the sidebar.html page with json datas received from apps script about goole sheet
// End of the A1-4) states
sidebarObj=JSON.parse(jSONforSheet); // in particular sidebarObj.tablUser[] that contains the sheet columns of logins and passwords
/* sidebarObj.agentConnected was used to don't have to connect when open a new sidebar
(I dont speak aubout the google acount connection)
sidebarObj.keepConnectPropertie==false desactive this mode
i prefer now have to connect on each new sidebar instentiation.
the login is preserved while the sidebar is instantiated.
*/
document.write(new Date().toLocaleDateString());
if (sidebarObj.keepConnectPropertie==false){sidebarObj.agentConnected="Deconnecté"}
document.write('<label id="labelConnectId" form="sidebarForm" > '+sidebarObj.agentConnected+'</label>');
document.write('<br><input type="button" value="Deconnect" onclick="deconnect();" />');
document.write('<form id="sidebarForm">');
document.write('<select name="agent" id="agentId">');
document.write('<option value="'+sidebarObj.agentConnected+'">'+sidebarObj.agentConnected+'</option>');
for(let iUsers=0;iUsers<sidebarObj.tablUser.length;iUsers++){
document.write('<option value="'+sidebarObj.tablUser[iUsers][0]+'">'+sidebarObj.tablUser[iUsers][0]+'</option>');
}
document.write('</select>');
writeTxtBox('mp','mpId','password')
document.write('<br><input type="button" value="Submit" onclick="submitForm();" />');
document.write('<br><input type="button" value="FormIn" onclick="callFormIn();" />'); // B-1) run gScriptFromSidebarThenGiveToFormIn() with data parameter needed
document.write('<input type="button" value="Close" onclick="google.script.host.close()" />');
}
document.close();
google.script.run.withSuccessHandler(jsFcGiveToSidebar).gScriptFcGiveToSidebar(); // A-2) give to jsFcGiveToSidebar() the return of gScriptFcGiveToSidebar()
</script>
</form>
</body>
</html>
htmlFormIn.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<style type="text/css">
.myDiv {cursor:pointer;}
.divBlack{background-color:#000; color:#fff;}
</style>
<label for="dowloading">dowloading</label>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
// ---------------------------------------------- Functions for Javascript ------------------
function writeLabel(name){
document.write('<br /><label for="'+name+'">'+name+': </label>');
}
function writeTxtBox(name,id,value,prefix){
prefix=prefix||'<br />';
document.write(prefix+'<input type="text" name="'+name+'" id="'+id+'" value="'+value+'">');
}
// -------------------------------------------------Wrinting in Body -----
function addRow(){
cptLine++;
//alert(sidebarAgent); // alert(document.getElementById("idLblSidebarAgent").innerHTML);
//document.getElementById("tableForm").appendChild("tr");
let newLin = document.getElementById("tableForm").insertRow(-1); // ajoute un <tr> à la fin de la table
let newCell=newLin.insertCell(0); // ajoute un <td>
newCell.innerHTML = '<input type="text" name="" id=c"'+cptLine+'" value="v'+cptLine+'"> <input type="text" name="" id=d"'+cptLine+'" value="'+sidebarAgent+'">';
//alert("ajouté");
}
function jsFcGiveToFormIn(aagent){ // B-12) aagent receive the data value return from gScriptFromSidebarThenGiveToFormIn that have been called in A6 state
// B-13) the formIn.html can fill its fields :) - End of the B1-12) states
if (aagent=="echec"){ alert ("htmlFormIn 71 le cache service n'a pas memorisé assez longemps le transfert de donnée depuis la sidebar")}
sidebarAgent=aagent; // pour étendre la portée de cette info dans le script de cette page html
document.write('<label id="idLblSidebarAgent" for="info">'+sidebarAgent+'</label>')
writeTxtBox("Saisie","idSaisie","Entrez un code");
document.getElementById("idSaisie").addEventListener("click", addRow);
document.write('<form id="sidebarForm">');
document.write('<table id="tableForm"><tr id="r'+cptLine+'""><td>');writeTxtBox("Date","iddat","date"," ");writeTxtBox("Ref","idRef"+cptLine,""," ");
writeTxtBox("agent","idAgent",sidebarAgent," ");
document.write('</td></tr>')
document.write('</table>')
document.write('</form>');
}
document.close();
var cptLine=0;
var sidebarAgent;
google.script.run.withSuccessHandler(jsFcGiveToFormIn).gScriptFromSidebarThenGiveToFormIn("",false); // B-6) give to jsFcGiveToFormIn the return of gScriptFromSidebarThenGiveToFormIn("",provenanceFlag=false) with provenanceFlag=false that meaning the call is from formIn.html file.
</script>
</body>
</html>

Angular Component with Content Projection Not Loading Properly in Storybook until a Control Is Changed

I'm new to Storybook, and am having trouble getting components which project ng-content to correctly receive input arguments on initial load.
Template:
<div id="alert-card">
<div>
<div class="iconDiv" fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="10px">
<mat-icon *ngIf='this.alertType === "Warning"' class="warningIcon" aria-hidden="false" aria-label="Warning">warning</mat-icon>
<mat-icon *ngIf='this.alertType === "Error"' class="errorIcon" aria-hidden="false" aria-label="Error">error</mat-icon>
<mat-icon *ngIf='this.alertType === "Info"' class="infoIcon" aria-hidden="false" aria-label="Info">info</mat-icon>
<mat-icon *ngIf='this.alertType === "Confirm"' class="confirmIcon" aria-hidden="false" aria-label="Confirm">check_circle</mat-icon>
<span><span class="alertType">{{ alertKeyword }}</span>{{ alertMessage }} </span>
</div>
<ng-content select="[cardContent]"></ng-content>
</div>
</div>
Component:
import {
Component,
Input,
ViewEncapsulation,
} from '#angular/core';
#Component({
selector: 'alert-card',
templateUrl: './alert-card.component.html',
styleUrls: ['./alert-card.component.scss'],
encapsulation: ViewEncapsulation.None,
})
// Displays the alert card
export class AlertCardComponent {
// The type of alert
#Input()
alertType: AlertType;
// The keyword at the start of the alert message
#Input()
alertKeyword: string;
// The alert message to display
#Input()
alertMessage: string;
constructor() {}
}
// Indicates a type of alert which has an associated icon and color scheme in the CSS
export enum AlertType {
Warning = "Warning",
Error = "Error",
Info = "Info",
Confirm = "Confirm",
}
Story:
import { componentWrapperDecorator, Meta, Story } from '#storybook/angular';
import { AlertCardComponent, AlertType } from './alert-card.component';
export default {
component: AlertCardComponent,
decorators: [componentWrapperDecorator(AlertCardComponent)],
} as Meta;
const Template: Story = (args) => ({
props: args,
template: `
<div cardContent
style="padding:10px"
fxLayoutAlign="center">
Arbitrary HTML content can go in this area
</div>
`
});
export const Warning = Template.bind({});
Warning.args= {
alertType: AlertType.Warning,
alertKeyword: "Warning: ",
alertMessage: "something has happened!"
};
This is nearly working as expected, but within the story, the component loads without any of the input arguments:
If I change any of the Storybook controls, the input arguments are passed and the component displays as expected:
I feel like I'm missing something obvious. Everything works as expected once I start manipulating the controls within Storybook, but how do I get the input arguments passed on initial load?
I'm also having what I believe are related issues on Storybook's Docs page. The component is displayed as it would without any arguments passed regardless of how the inputs are controlled.

How can I pass class and style attributes on a vue component to a different element like $attrs?

I have a single file component called confirm-document that looks something like this:
Sandbox
<template>
<v-dialog>
<template v-slot:activator="{ on }">
<v-btn v-bind="$attrs" :class="activatorClass" v-on="on">{{
title
}}</v-btn>
</template>
<v-card>
<v-card-title>{{ title }}</v-card-title>
<v-card-text><slot></slot></v-card-text>
</v-card>
</v-dialog>
</template>
<script>
export default {
name: "ConfirmDocument",
props: {
title: String,
activatorClass: {},
},
};
</script>
So when I then use this component like:
<ConfirmDocument
class="useless-class"
activator-class="mt-4 ml-n4"
title="Consent"
> Document Content </ConfirmDocument>
Sandbox
The classes get applied to the v-dialog, which ends up as an invisible div with nothing inside and both the activator and modal attached as sibling nodes.
Since this is mainly a wrapper component to provide a consistent UI, I actually only need for the activator to be positionable. So I want to pass the class and style props to the v-activator.
The activator-class prop that I have declared actualy works fine. But I am very curious if there a way to change the element to which the component's class and style attributes are bound, so that I can use class instead?
This is fixed in Vue.js v3 ref
For Vue.js v2, you can try this
Check v-bind and attrs computed property below
<template>
<v-dialog>
<template v-slot:activator="{ on }">
<v-btn v-bind="attrs" v-on="on">{{
title
}}</v-btn>
</template>
<v-card>
<v-card-title>{{ title }}</v-card-title>
<v-card-text><slot></slot></v-card-text>
</v-card>
</v-dialog>
</template>
<script>
export default {
name: "ConfirmDocument",
inheritAttrs: false, // <- added just for safety
props: {
title: String,
},
computed: {
attrs() {
const attrs = { ...self.$attrs }
// adding class and style for `v-bind`
attrs.class = self.$vnode.data.staticClass
attrs.style = self.$vnode.data.staticStyle
return attrs
}
}
};
</script>
Explanation - In Vue.js version 2.x.x, $attrs does not include class and style (ref) but there are many scenarios in which we wanted to pass on all the props along with class and style into another component so, $attrs should have class and style in it which they did add in version 3 of vue.js.
There is a detailed discussion on this topic on github do check it out for more details.
For version 2, what we wanted to achieve is that class and style can be passed to another component. We can pull it off by getting the class [as string] and style [as object] from the current component node i.e. vnode and pass it on to the other component using v-bind.
Now, you can pass props along with class and style into another component inside ConfirmDocument directly from the parent (or caller) component
What's about simple using props to handle this?
<template>
<v-dialog>
<template v-slot:activator="{ on }">
<v-btn :class="btnClass" v-on="on">Read {{ title }}</v-btn>
</template>
<v-card>
<slot></slot>
</v-card>
</v-dialog>
</template>
<script>
export default {
props: {
btnClass: { type: String },
title: { type: String }
}
}
</script>
and using the component:
<confirm-document
btn-class="mt-0 mb-0"
title="Privacy Policy"
>
Lorem ipsum dolor sit amet
</confirm-document>
I think you can use the inheritAttrs: false property. What it does it to make sure that attributes are not applied automatically to the root element and it lets you choose where to apply them instead.
<template>
<v-dialog>
<template v-slot:activator="{ on }">
<v-btn v-bind="buttonAttrs" >Read {{ title }}</v-btn>
</template>
<v-card>
<slot></slot>
</v-card>
</v-dialog>
</template>
<script>
export default {
inheritAttrs: false,
props: {
title: {type: String},
},
computed: {
buttonAttrs () {
// select which attrs to apply
const { title, ...rest } = this.$attrs;
return rest;
}
}
}
</script>
A working (and a bit cluttered) example can be found here.

next.js I don't know how to apply global .container css style to other pages

I'm new to react and next.js
I'm trying to do a projetct with next.js
I have a global css with a .container style properties and I imported it in my _app.js file.
But I don't know how to import it in a page.
I have a page with a import module.css and I understood that but in this page there is a div with the global container class and I don't know how to pass the css property.
Is it possible to write .container property in the global css or does it just work with global tags like a, img, h1, etc ?
I'm a little lost with the css in Next.
I think I've worked out how to pass global css to a page whitch contain module.css but know I'm stuck with the module css.
I've created a compotent HeroSection like that :
import React from "react";
import style from "./heroSection.module.css";
function HeroSection({ title, paragraphs, image }) {
return (
<div className={style.heroSection}>
<div className={style.text}>
<h1>{title}</h1>
<div className={style.paragraphes}>{paragraphs}</div>
</div>
<img src={image} alt="" />
</div>
);
}
export default HeroSection;
And a page whith contains the component and adds props :
<HeroSection
title="Nous contacter"
paragraphs={
<>
<div className="para1">
<p> Améliorons ensemble ce projet de société !</p>
<p>
Nous sommes à l’écoute de tes suggestions, avis et
commentaires.
</p>
</div>
<p>
C’est juste ici
</p>
</>
}
image="/images/contact.jpg"
/>
In my heroSection.module.css I have this code :
.para1 {
margin-bottom: 44px;
}
As you see in the page containing the heroSection a div has the className "para1" but I am unable to apply the css on it.
I tried className={style.para1} without success.
How can I style the div passed as props ?
You need to import to CSS file in the page where you use the <HeroSection> component.
import style from "<relative-path-to-heroSection.module.css>";
Then pass the appropriate class to the <div> further down.
<HeroSection
title="Nous contacter"
paragraphs={
<>
<div className={style.para1}>
<p> Améliorons ensemble ce projet de société !</p>
<p>
Nous sommes à l’écoute de tes suggestions, avis et
commentaires.
</p>
</div>
<p>C’est juste ici</p>
</>
}
image="/images/contact.jpg"
/>

Pushing data to object in different component using POST

TL;DR I want to show submitted posts instantly instead of having to refresh my page
Using the Wordpress REST API I am able to create a new post without any issue. The post is being displayed as soon as the page refreshes, so what I want to do is update the posts object in my Hello.vue file as soon as I create that post so I don't need to refresh to show my newest posts.
I'm not really sure where to start - I've removed all of the experiments I've done so far (importing Post in Create, defining props, pushing to an array, reading about object reactivity on the official Vue documentation, nothing helped).
My App.js consists of the <router> object which shows Hello.vue and a component called Create which displays the Create.vue component. This is how my app currently looks like:
My App.vue file:
<template>
<div id="app">
<section class="posts">
<router-view></router-view>
<create></create>
</section>
</div>
</template>
<script>
import Create from '#/components/Create.vue'
export default {
name: 'app',
components: {
Create
}
}
</script>
<style lang="scss">
#import '../src/assets/styles/style.scss'
</style>
My Hello.vue which displays all the posts:
<template>
<div>
<section class="posts__Feed">
<ul class="posts__List">
<post v-for="item in posts" :item="item" :key="item.id"></post>
</ul>
</section>
</div>
</template>
<script>
var postsUrl = '/wp-json/wp/v2/posts/'
import Post from '#/components/Post.vue'
export default {
name: 'hello',
props: ['responseData'],
components: {
Post
},
data () {
return {
posts: []
}
},
beforeCreate () {
this.$http.get(postsUrl).then((response) => {
this.posts = response.data
})
}
}
</script>
And finally, the Create.vue file which creates the post:
<template>
<div>
<section class="posts__Create">
<form class="posts__CreateForm" v-on:submit="createPosts">
<div class="posts__CreateFormWrapper" v-bind:class="{ 'is-Loading': loading }">
<p>
<input v-model="formInfo.title" type="text" name="title" id="title" placeholder="Name" :disabled="formSent">
</p>
<p>
<textarea v-model="formInfo.content" name="content" id="content" cols="20" rows="10" maxlength="140" placeholder="Message" :disabled="formSent"></textarea>
</p>
<p>
<button :disabled="formSent">Send</button>
</p>
</div>
</form>
</section>
</div>
</template>
<script>
var postsUrl = '/wp-json/wp/v2/posts/'
export default {
name: 'create',
data () {
return {
formInfo: [],
responseData: [],
loading: false,
formSent: false
}
},
methods: {
createPosts (e) {
e.preventDefault()
var info = this.formInfo
// Check if fields are empty
if (this.formInfo.title && this.formInfo.content) {
this.loading = true
// POST
this.$http.post(postsUrl, info).then((response) => {
this.formSent = true
this.loading = false
// get body data
this.responseData = response.data
})
}
} // EOF createPosts
}
}
</script>
Any help would be much appreciated!
I ended up using an event bus as suggested by wotex. First, I've createad a file called bus.js with the below code:
import Vue from 'vue'
export const EventBus = new Vue()
Next, import bus.js to both .vue layouts using:
import { EventBus } from '#/bus.js'
Now emit the event as soon as a new post is created (this is sitting in my axios POST request inside the Create.vue file):
EventBus.$emit('newPost', this.responseData)
And finally, check if the event has happened on the other end (my Hello.vue file):
EventBus.$on('newPost', function (postData) {
Thanks for pointing me in the right direction!

Resources