Laravel 5.8 and Vue.js components - javascript

I'm new to using Vue.js and I am trying to learn how to implement a rating system for recipes in my Laravel application using vue-star-rating. The first thing I want to learn is how to build components and then include them in my blade views. Already here I am running into trouble.
Trying to include the ExampleComponent.vue that comes with Laravel out of the box, but I don't understand how I am to include it in my blade file.
The top of my blade file looks like this
Blade view
<div class="col-sm-6">
<div class="container recipeDesc">
<h2 class="text-center name">{{$recipe->title}}</h2>
<div class="stars">
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
</div>
<div id="app">
<example-component></example-component>
</div>
Default JS file
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
window.Vue = require('vue');
/**
* The following block of code may be used to automatically register your
* Vue components. It will recursively scan this directory for the Vue
* components and automatically register them with their "basename".
*
* Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
*/
// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
const app = new Vue({
el: '#app',
components: {
'example-component': require('./components/ExampleComponent.vue'),
}
});
How would I include the ExampleComponent.vue in this div? Having a hard time understanding this, even when reading the Vue.js documentation.
Thank you!

If you still have the default js files of the Laravel installation, in your resources/js/app.js file you should have the following:
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
const app = new Vue({
el: '#app'
});
The first line tells you that the name you should use for the example component is example-component, so to include it on your blade view, simply write this:
<example-component/>
The second block in the app.js file tells you that Vue will work on an element with id="app", so you should make sure that you have an div with that id on your layout if you want to use Vue components.

Before the body ending tag, you should include the vue script source in order to be able to implement it in your views:
<script src="{{ asset('js/app.js') }}"></script></body>

Related

How to you use vue js for certain Laravel Routes and blade for other routes?

I have tried searching up for this but can't seem to find an answer for this. It seems to point to if you are going to use blade then all your views must be in blade whereas if you are going to continue using vue js for your front end then every view must be in Vue.
So my question is can I use vue js for certain routes and blade for certain routes?
For an example , let's say if I have '/login' route and I would like to use Vue js for this route's front end and for '/about' route, I would like to use Laravel's blade for it's front end. Is this possible?
If yes, how to do it ?
Thank you.
Yes, create Vue components and call them from within the blade template:-
ExampleComponent.vue:
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
example.blade.php:
#extends('layouts.app')
#section('content')
<example-component></example-component>
#endsection
Thanks #chris for the answer, however I would like to extend this answer .
Let's say if you want to register a for a new component which is in resources/js/components/AboutComponent.vue
Step 1 : Register route in web.php
Route::get('contact', 'TestController#contact')->middleware('auth');
Step 2 : Create controller and point to blade
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function contact()
{
return view('testing.contact');
}
}
//Step 3 : Create vue component in resources/js/components/ContactComponent.vue
<template>
<div class="col-md-12">
<p>Brought to you by Evan You</p>
</div>
</template>
<script>
export default {
data() {
return {
}
} ,
mounted() {
console.log('Contact Component mounted.')
}
}
</script>
//Step 4 Register Vue Component in resources/js/app.js
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
window.Vue = require('vue');
/**
* The following block of code may be used to automatically register your
* Vue components. It will recursively scan this directory for the Vue
* components and automatically register them with their "basename".
*
* Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
*/
// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Vue.component('contact-component', require('./components/ContactComponent.vue').default);
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
const app = new Vue({
el: '#app',
});
// Step 5 Use this component in contact.blade.php which is located in resources/views/testing/contact.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<h2>From the vue component</h2>
{{-- This is the vue component that we registered in app.js --}}
<contact-component></contact-component>
</div>
<div class="container">
<div class="col-md-12">
<h2>From the blade component</h2>
<p>Brought to you by Taylor Otwell</p>
</div>
</div>
#endsection
//Step 6 Don't forget to run npm run watch
Result:

Font Awesome icons not showing up using Bulma in Gatsby

I am building a website using Gatsby and Bulma. In my Nav.js file, where I create a general format for the buttons at the top of the website, I have a few buttons using Bulma to which I would like to add icons inside. I went off the documentation for adding Bulma buttons with Font Awesome Icons: https://bulma.io/documentation/elements/button/. My code is exactly the same, other that the fact that I have my buttons wrapped in an <a> tag to link to other pages in my website. I have the included <script> file listed in documentation to have Font Awesome Icons available, and my code looks as such:
const Nav = () => {
return (
<div style={{ margin: `3rem auto`, maxWidth: 650, padding: `0 1rem` }}>
<nav>
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
<p class="buttons is-outlined is-centered">
<a href="/"><button class="button is-outlined"> <span class="icon">
<i class="fas fa-home"></i>
</span>
<span>Home</span>
</button></a>
<button class="button is-outlined">Projects</button>
<button class="button is-outlined">Experience</button>
</p>
</nav>
</div>
)
}
I'm not sure if I have the script located in the correct part of the file, and I've only tried to put an icon for my Home button which looks like this:
The gap to the left of the "Home" is where I'm guessing the icon should be. I would appreciate any help as to why the icon is not showing up or is showing up blank. Thank you!
I ran into this issue myself so posting here for anyone that is looking for the answer. There are a few ways to make it work, including using the icons as components with a library such as react-fontawesome. However if you're using Bulma then chances are that you specifically don't want to do that, instead you want to use the class names.
So first install the package:
npm i #fortawesome/fontawesome-free
Then in your index.js / app.js / any styling wrapper component you have:
import '#fortawesome/fontawesome-free/css/all.min.css'
Here is a Typescript example I have in front of me. This is a wrapper component that imports all my global styles for nested child components to use:
import React from 'react';
import 'bulma/css/bulma.css';
import '#fortawesome/fontawesome-free/css/all.min.css';
import NavMenu from '../nav-menu';
import Footer from '../footer';
import './layout.css';
const Layout: React.FC<{ light: boolean }> = ({ light, children }) => {
return (
<div className="layout-wrapper">
<NavMenu light={light} />
{children}
<Footer light={light} />
</div>
);
};
export default Layout;
With the help of a friend, what solved the issue was putting the <script> tag in the public/index.html file of the project, and then making an exact copy and naming it index.html and putting it in the static folder in the project. This way, each time a Gatsby server is ran, it will create a copy of the index.html file in the public repository with the Font Awesome Icon script included.

Vuetify buttons in vue-social-sharing of nuxt application

I'm trying to implement this - https://github.com/nicolasbeauvais/vue-social-sharing in my nuxt (+vuetify) application.
I've created a file - vue-social-sharing.js in plugins folder:
import Vue from "vue";
import VueSocialSharing from "vue-social-sharing";
Vue.use(VueSocialSharing);
included them in nuxt.config.js
plugins: [
"#/plugins/vuetify",
"#/plugins/vue-social-sharing.js"
],
I'm trying to beautify the buttons with Vueity (this works fine - https://jsfiddle.net/menteora/evydLj65/1/)
<social-sharing url="https://vuejs.org/"
title="The Progressive JavaScript Framework"
description="Intuitive, Fast and Composable MVVM for building interactive interfaces."
quote="Vue is a progressive framework for building user interfaces."
hashtags="vuejs,javascript,framework"
twitter-user="vuejs"
inline-template>
<div>
<v-btn><network network="email">
<i class="fa fa-envelope"></i> Email
</network></v-btn>
<v-btn><network network="facebook">
<i class="fa fa-facebook"></i> Facebook
</network></v-btn>
</div>
</social-sharing>
But I'm running into the below errors:
[Vue warn]: The client-side rendered virtual DOM tree is not matching
server-rendered content. This is likely caused by incorrect HTML
markup, for example nesting block-level elements inside <p>, or
missing <tbody>. Bailing hydration and performing full client-side
render.
[Vue warn]: Unknown custom element: <v-btn> - did you register
the component correctly? For recursive components, make sure to
provide the "name" option.
I think it is an issue with configuration, v-btn is not available with social-sharing is being rendered, please suggest.
Thanks
I haven't installed those, but I can almost bet that the fact you are wrapping network components with a button is a problem.. Because the markup that it generates most likely looks like this:
<ul class="networks">
<button>
<li></li>
</button>
</ul>
Have you tried to replace this markup with:
<social-sharing>
<div>
<network network="facebook">
<v-btn><i class="fa fa-fw fa-facebook"></i> Facebook</v-btn>
</network>
<network network="facebook">
<v-btn><i class="fa fa-fw fa-twitter"></i> Twitter</v-btn>
</network>
</div>
</social-sharing>

Is there a way to suppress VueJS "Cannot find element" warning

I have a script file that contains two Vue apps, that I use across multiple django templates. Apps are vue1, and vue2, with el: #vue1-app, and el: #vue2-app.
On one particular page I only use one of those apps, not both. So my html contains only <div id="vue1-app"></div> and not both divs with vue1-app and vue2-app ids. Therefore Vue logs warnings "Cannot find element: #vue2-app".
Is there a way to suppress those warning or any other bypass?
Thank you!
I'm not a Django developer, but I think maybe you can just split out them into two files or add a condition like:
const vueApp = document.querySelector('#vue-app')
if(vueApp){
// mount the app
}
Vue warnings are not emitted in the production (minified) version of Vue, so you could load vue.min.js:
new Vue({
el: '#does_not_exist',
})
<script src="https://unpkg.com/vue#2.6.10/dist/vue.min.js"></script>
<div id="app">
<p>{{ message }}</p>
</div>

Keep existing markup in Vue's <div id="app" />

I have installed Vue using the latest CLI in to an existing .net mvc projects. My goal is to add components while keeping the existing pages intact.
Is it possible to do something like:
<div id="app">
<MyNewVueComponent></MyNewVueComponent> <!-- insert my vue compoents -->
<p>#Model.someText</p> <!-- keep original .net mvc view content -->
</div>
In my main.js:
new Vue({}).$mount('#app')
This just generates a blank page at the moment.
Using
new Vue({
el: '#app'
})
along with runtimeCompiler: true in vue.config.js did the trick.

Categories

Resources