How to bulid Application template Vue - ecmascript-6

I'm new to Vue and to ES6
And I did the following:
import Vue from 'vue'
import VueRouter from 'vue-router'
import $ from 'jquery'
Vue.use(VueRouter)
var App = {};
App.template = `
<main-menu></main-menu>
<router-view></router-view>`;
const header = Vue.component('main-menu', require('./components/app/header.vue'));
const facebook = Vue.component('facebook-gif', require('./components/facebook.vue'));
const router = new VueRouter({
routes: [
{
path: '/',
},
{
path: '/facebook',
component: {
facebook: facebook
}
}
]
});
App.app = new Vue({
router,
render (h) {
return h(`div`, App.template)
}
}).$mount('#app');
But what it's nothing render , I just see the main-menu and router-view tags in my broswer...
And when I edit my html and put there this:
<div id="app">
<main-menu></main-menu>
<router-view></router-view>
</div>
I get this error when I'm trying to enter the facebook route:
[Vue warn]: Failed to mount component: template or render function not defined.
and the facebook template is wrapped with template tag and it's inside a vue file
facebook.vue
<template>
<div>
dsfsdsfdsf
<div v-if="showLogin">
<button v-on:click="login">Log In With Facebook</button>
<span v-if="error">{{ error }}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
showLogin: true,
error:null,
}
},
methods() {
return {
login() {
}
}
}
}
</script>
But the main-menu component is render...
What is the problem?
EDIT
I downloaded the example like wostex said
I create an App.vue file contain:
<template>
<div id="app">
<main-menu></main-menu>
<router-view></router-view>
</div>
</template>
I edit my html file to contain
I added in app.js
import App from './components/App.vue'
const v = new Vue({
el: "#app",
router,
render: h => h(App)
});
and my html file contain:
<div id="app"></div>
and I get this error:
vue.common.js:436 [Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <Anonymous>
<App> at /opt/lampp/htdocs/gif/resources/assets/js/components/App.vue
<Root>
it happens because the facebook component, when I'm in the main page I don't see the error, only when I enter the facebook route

It seems your first set up was failing because of what build you we're using. For eg:
App.app = new Vue({
router,
render (h) {
return h(`div`, App.template) // this part can be roughly
// translated to `return h(`div`,
// `<one-component></one-component>
// <router-view></router-view>`)` and I believe
// this failed due to the fact that when you pass
// template string to the render method it needs to
// be compiled and your setup didn't account for that.
}
}).$mount('#app');
Your other set up ( as per suggestion of #wostex ) is much better but I think that here you are missing .$mount('#app') at the end of your Vue initialization. So:
const v = new Vue({
router,
render: h => h(App)
}).$mount('#app')

I looked at Laracasts in Jeffry tutorial about Vue
He did there like that:
const router = new VueRouter({
routes: [
{
path: '/',
},
{
path: '/facebook',
component: require('./components/facebook.vue')
}
]
});
and it work's
So thanks every one that tried to help me

Related

How to define variables in Vue router to be used inside components?

I have a navbar on top and a <router-view> right below it (as seen in App.vue). I want the title inside the navbar to change depending on the route/view I am on. Since my views in the <router-view> do not contain the title itself, I need to define them somewhere. An example for the scenario could be when reaching the route /login, the title in the navbar changes to "Login".
How do I achieve this?
When searching for a solution, I came across a lot of page title questions. I am not talking about the document.title assignment, however, that could be a solution, but not a perfect one. What if I wanted the title to be something else than the document title..
App.vue:
<template>
<Menu :isActive="isMenuActive" />
<Navbar #toggle:hamburger="onHamburgerToggle($event)" />
<router-view />
</template>
Vue router allows you to attach any information you want to any route using Route Meta Fields
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
meta: { title: "FOO" }
}
]
})
You can access the information for currently active route in any component using $route variable
const child = Vue.component('child', {
template: `
<div>
Child component ("{{ $route.meta.title }}")
</div>
`
})
const router = new VueRouter({
mode: 'history',
routes: [
{
name: 'route1',
path: '/route1',
component: child,
meta: { title: 'Hello from route 1!'}
},
{
name: 'route2',
path: '/route2',
component: child,
meta: { title: 'Hello from route 2!'}
},
]
})
new Vue({
el: '#app',
router,
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<router-link to="/route1">Route 1</router-link>
<router-link to="/route2">Route 2</router-link>
<h4> Current route: {{ $route.meta.title }} </h4>
<router-view></router-view>
</div>
Every component can access the $route object, so you could use that directly in your template. Or you can access that object in the script and do something with it.
Imagine your routes have the name property:
router/index.js
routes: [
{ path: '/', name: 'home', component: Home },
{ path: '/foo', name: 'foo', component: Foo },
{ path: '/bar', name: 'bar', component: Bar }
]
You could show that name in the template with no script necessary:
Navbar.vue
<template>
<div>Title: {{ $route.name }}</div>
</template>
(meta is also a good idea here as explained in #MichalLevĂ˝'s answer.)
Or you could access the route object in the script and create a title however you want.
Navbar.vue (Composition API)
<template>
<div>Title: {{ title }}</div>
</template>
<script>
import { ref } from 'vue';
import { useRoute } from 'vue-router';
export default {
setup() {
const route = useRoute();
const title = ref('My title ' /* Do something with `route` */);
return { title }
}
}
</script>

How load html template in vuejs

I use vue.js and vue-router.js.
I added both of files to a html page
This is my component for load template...
const Dashboard = {template: "<strong>"}
But I want load html page dynamically and with HTTP URL.
const Dashboard = {template: "How load html page with url(http)"}
Can anyone guide me?
you could define a component similar to this
Vue.component('dynamic-component', {
props: {
contentURL: String,
},
template: `<div v-html='inner_html'></div>`,
computed: {
inner_html() {
return // http call to get html value utilizing this.contentURL
},
},
});
then from the router
{
path: '/path/option-a',
components: {
DynamicComponent
},
props: {
contentURL: `https://some-resource/option-a`
}
},
{
path: '/path/option-b',
components: {
DynamicComponent
},
props: {
contentURL: `https://some-resource/option-b`
}
}
For creating layers, you can create vue component and use slot
Layout.vue
<template>
Header
AnyComponents
<slot />
Footer
</template>
and in your page component you should import your layout and wrap
MainPage.vue
<template>
<MainLayout>
Here is your conntent of page or router
<router-view />
</MainLayout>
</template>
<script>
import MainLayout from 'layout.vue';
export default {
components: {
MainLayout
}
}
</script>
And now for render your page you should use your page in router
example of router.js
import Vue from 'vue';
import Router from 'vue-router'
import MainPage from 'MainPage.vue';
Vue.use(Router)
export default new Router({
routes: [{
path: '/',
component: MainPage,
}]
})
If you want to insert html to your page, use v-html
<div class="content" v-html="dashboard.template">
</div>

VUE.JS Recieve a json file from url via axios in webpack-simple

I am new to vue.js and I try to recieve the list from url.
There are some problems here:
1. I can't define the axios in main.js so I can use it in index.html (this solution doesn't work for me https://stackoverflow.com/a/51374448/9582441)
2. When I use console.log(response), the response is empty, thus the request havn't been done
I've installed axios and vue threw the vue-cli
main.js
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios);
new Vue({
el: '#app',
render: h => h(App)
})
index.html
<template>
<div id="app">{{ info }}</div>
</template>
<script>
export default {
name: "app",
data() {
return {
info: null
};
},
mounted() {
Vue.axios
.get("https://dog.ceo/api/breeds/list/all"
)
.then(response => (this.info = response));
console.log(response);
}
};
So that I just want to recieve a list and connect the axios somehow
Soultion is to use
this.axios
the solution was to use
this.axios

Vue.js: Failed to generate render function

I try to run a simple Vue.js, but I constantly receive the following error:
[Vue warn]: It seems you are using the standalone build of Vue.js in
an environment with Content Security Policy that prohibits
unsafe-eval. The template compiler cannot work in this environment.
Consider relaxing the policy to allow unsafe-eval or pre-compiling
your templates into render functions.
main.js:3180 [Vue warn]: Failed to generate render function:
EvalError: Refused to evaluate a string as JavaScript because
'unsafe-eval' is not an allowed source of script in the following
Content Security Policy directive: "default-src 'self'". in
with(this){return _c('div',{attrs:{"id":"app"}})}
(found in )
Yet, I can't understand what is causing this error. I don't seem to use any dynamic templates and everything should be pre-compiled. Here is the code of my application:
import Vue from 'vue'
import VueRouter from 'vue-router'
const Home = Vue.component('home-component', {
render() {
return <div>
<router-link to="/users">Users</router-link>
<router-link to="/about">About</router-link>
</div>
}
})
const Users = Vue.component('users-component', {
render() {
return <p>Users</p>
}
})
const NotFound = Vue.component('not-found-component', {
render() {
return <p>Not Found</p>
}
})
const routes = [
{ path: '/', component: Home },
{ path: '/users', component: Users }
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')
And here is how I process JavaScript files in my gulpfile:
const paths = {
main: 'web/javascript/src/main.js',
allJs: 'web/javascript/**/*.{js,vue}',
resultJs: 'public/assets/javascript/main.js',
};
gulp.task('scripts', function() {
return browserify(paths.main)
.transform(babelify, { presets: ['es2015'], plugins: ["transform-runtime"] })
.transform(vueify)
.bundle()
.pipe(fs.createWriteStream(paths.resultJs))
}
There are seem to be many similar questions on StackOverflow, but none of them helped me.
The broweser is throwing Content Security Policy (CSP) error, to get around this issue you should consider switching to the runtime-only build, which is fully CSP-compliant.
https://v2.vuejs.org/v2/guide/installation.html#CSP-environments
Also, You have return incorrectly written. It should return jsx in pair of paranthesis (). The code below should help
import Vue from 'vue'
import VueRouter from 'vue-router'
const Home = Vue.component('home-component', {
render(h) {
return(
<div>
<router-link to="/users">Users</router-link>
<router-link to="/about">About</router-link>
</div>
)
}
})
const Users = Vue.component('users-component', {
render(h) {
return(
<p>Users</p>
)
}
})
const NotFound = Vue.component('not-found-component', {
render(h) {
return(
<p>Not Found</p>
)
}
})
const routes = [
{ path: '/', component: Home },
{ path: '/users', component: Users }
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')

Vue-router components when using one data set

I'm using Vue.js as well as the usual setup that comes with it (vue-router etc). I'm having a problem, using one global data set (JSON output of all projects on a site), to return the data for an individual project when viewing that view. I'm confused to where I am going wrong?
My master page has this simple output:
<div id="app">
<router-view></router-view>
</div>
app.js:
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import router from './routes.js';
const app = new Vue({
router: router,
data: data
}).$mount('#app');
And my routes.js file has the following:
import VueRouter from 'vue-router';
var routes = [
{
path: '/',
component: require('./views/Projects.vue')
},
{
name: 'project',
path: '/:id',
component: require('./views/Project.vue')
}
]
export default new VueRouter({
routes: routes
});
I have two .vue components; Projects and Project.
Projects.vue looks like the following and seems to work fine:
<template>
<ul>
<li v-for="project in projects">
{{ project.title }}
<router-link :to="{ name: 'project', params: { id: project.id }}">View Details</router-link>
</li>
</ul>
</template>
<script>
module.exports = {
data: function () {
return data
}
}
</script>
However, Project.vue isn't working.
<template>
<div>
<h1>{{ project.title }}</h1>
<router-link to="/">Homepage</router-link>
</div>
</template>
<script>
module.exports = {
data: function () {
var project;
for (var i = 0; i < data.length; i++) {
if (data[i].id == this.$route.params.id) {
project = data[i];
break;
}
}
return {
project: project
}
}
}
</script>
My JSON data is just set in a footer include file.
var data = {"projects":[{"id":1080,"title":"Hopton Yard","name":"hopton-yard","size":null,"img":{"featured":"\/Sites\/hat-projects-vuejs\/site\/assets\/files\/1080\/hat_projects_hoptonyard_exterior-001-1.jpg"}},{"id":1082,"title":"Science Museum Entrances & Supporters\u2019 Centre","name":"science-museum-entrances-supporters-centre","size":null,"img":{"featured":"\/Sites\/hat-projects-vuejs\/site\/assets\/files\/1082\/hat_projects_science_museum.jpg"}},{"id":1084,"title":"Upper & Lower Fosters","name":"upper-lower-fosters","size":null,"img":{"featured":"\/Sites\/hat-projects-vuejs\/site\/assets\/files\/1084\/hat_projects_upper_lower_fosters.jpg"}},{"id":1086,"title":"Jerwood Gallery","name":"jerwood-gallery","size":null,"img":{"featured":"\/Sites\/hat-projects-vuejs\/site\/assets\/files\/1086\/hat_projects_jerwood.jpg"}},{"id":1101,"title":"High House Artists\u2019 Studios","name":"high-house-artists-studios","size":null,"img":{"featured":"\/Sites\/hat-projects-vuejs\/site\/assets\/files\/1101\/hat_projects_high_house_artists_studios.jpg"}},{"id":1115,"title":"Stoke Barn","name":"stoke-barn","size":null,"img":{"featured":"\/Sites\/hat-projects-vuejs\/site\/assets\/files\/1115\/hat_projects_stoke_barn.jpg"}}]}
Your code would work except for one minor mistake. Your global object, data, is not the object you want to iterate over. You want to iterate over data.projects.
var project;
for (var i = 0; i < data.projects.length; i++) {
if (data.projects[i].id == this.$route.params.id) {
project = data.projects[i];
break;
}
}