I need to bind $price_php with price in this Vue object. We do not use templates and imported components in the project
<html >
<head>
<meta charset="utf-8">
<title>Laravel</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="example">
<?php $price_php = 100 ?>
<p>Price: "{{ $price_php }}"</p>
<p v-bind:price="$price_php">Computed amount: "#{{ amount }}"</p>
</div>
<script>
var vm = new Vue({
el: '#example',
data: {
quantity: 10
},
// props: ['price'],
computed: {
amount: function () {
return price*this.quantity
}
}
})
</script>
I believe something like this would work for you.
<script>
var vm = new Vue({
el: '#example',
data: {
quantity: 10,
price: <?php echo $price_php; ?>,
},
// props: ['price'],
computed: {
amount: function () {
return this.price*this.quantity
}
}
})
</script>
Reference of Idea: See "Rendering JSON" subheading on https://laravel.com/docs/7.x/blade#displaying-data
Related
i have a requirement where autocomplete comes from backend and it will have key called filedId based on that i want to show the label
if we click on dynamic resource 1 btn the label should be city
if we click on dynamic resource 2 btn the label should be pinCode
if we click on dynamic resource 3 btn the label should be countryCode
Note: i don't want to change the data structure / json
here is what i have tried
var app = new Vue({
el: '#app',
components: { Multiselect: window.VueMultiselect.default },
data () {
return {
value: [],
options: [],
infoData:{},
}
},
methods:{
dr1(){
let infoObj = {
resource:{
autocomplete:{
fieldId:'city',
},
data:[{
id:1,
city:'Bengaluru'
}],
}
}
this.infoData = infoObj;
this.options = infoObj.resource.data;
},
dr2(){
let infoObj = {
resource:{
autocomplete:{
fieldId:'pinCode',
},
data:[{
id:1,
pinCode:'560097'
}],
}
}
this.infoData = infoObj;
this.options = infoObj.resource.data;
},
dr3(){
let infoObj = {
resource:{
autocomplete:{
fieldId:'countryCode',
},
data:[{
id:1,
countryCode:'+91'
}],
}
}
this.infoData = infoObj;
this.options = infoObj.resource.data;
},
determineLabel(){
let labelName = this.infoData.resource.autocomplete.fieldId;
return labelName;
}
},
})
body { font-family: 'Arial' }
<!DOCTYPE HTML>
<html>
<head>
<title>Timeline</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-multiselect#2.1.0"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect#2.1.0/dist/vue-multiselect.min.css">
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
</head>
<body>
<div id="app">
<button #click="dr1()">dynamic resource 1</button>
<button #click="dr2()">dynamic resource 2</button>
<button #click="dr3()">dynamic resource 3</button>
<br/><br/>
<div>
<multiselect
v-model="value"
label="determineLabel"
:options="options"
:multiple="false"
:taggable="false"
></multiselect>
</div>
</div>
</body>
here is codepen link to play with: https://codepen.io/eabangalore/pen/MWmrOBb
Still i did not find solution, please help me thanks in advance
Label prop in <multiselect> doesn't execute determineLabel by itself. it only gets computed or data option or a simple string. so you should put determineLabel in the computed:
...
computed: {
determineLabel() {
let labelName = this.infoData.resource.autocomplete.fieldId;
return labelName;
}
}
...
I have 2 different parts of the website
First: is it ok to use one instance in another especially with v-model, is this have any disadvantages.
Second: Is there any way I can cross reference each other, like footer in aside even though one is declared before the other. I get an error with this code. "footer is undefined"
My JS:
var aside = new Vue({
"el":"aside",
data:{
name:"Peylan"
}
});
var footer= new Vue({
"el":"footer",
data:{
companyname:"Company Inc"
}
});
My HTML
<aside><h3 v-bind="footer.companyname"></h3></aside>
<footer>
<input type="text" v-model="aside.name">
</footer>
Standard way of handling what you want is using a shared Vuex store.
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<aside><h3 v-text="footer.companyname"></h3></aside>
<footer>
<input type="text" v-model="aside.name">
</footer>
<script>
const store = new Vuex.Store({
strict: false,
state: {
aside: {
name:"Peylan"
},
footer: {
companyname:"Company Inc"
}
}
});
var aside = new Vue({
store,
"el":"aside",
data:{},
computed: {
...Vuex.mapState(['aside', 'footer'])
}
});
var footer= new Vue({
store,
"el":"footer",
data:{},
computed: {
...Vuex.mapState(['aside', 'footer'])
}
});
</script>
The demo above is a very simplified way of using it. For optimal usage (like with getters, actions and mutations) consider Vuex's official docs.
Or you can use a computed property on both, like below.
This creates a bit of a chicken and egg issue, that's why you need to use .$mount() in this case.
<script src="https://unpkg.com/vue"></script>
<aside><h3 v-text="footer.companyname"></h3>
</aside>
<footer>
<input type="text" v-model="aside.name">
</footer>
<script>
var aside = new Vue({
data:{
name:"Peylan"
},
computed: {
footer() { return footer; }
}
});
var footer = new Vue({
data:{
companyname:"Company Inc"
},
computed: {
aside() { return aside; }
}
});
aside.$mount("aside");
footer.$mount("footer");
</script>
For following code: I want the "test1 span" could be changed with javascript. How can I do it? NOTE: the {{msg}} maybe from ajax output.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<!-- app -->
<div id="app">
<span v-html="test"></span>
<span v-html="test1"></span>
{{test3}}
</div>
<script>
var app1 = new Vue({
el: '#app',
data: {
test: '<p style="color: red">THIS IS HTML</p>',
test1: '{{msg}}',
test3: 20,
msg: 10
}
})
function change() {
app1.msg = Math.random()
app1.test3 = Math.random()
}
setInterval(change, 2000)
</script>
</body>
</html>
Modification:
Maybe I need to make my question clear:
For next modify code, when launch the page, you will see Go to Foo link in the page, then you click the link, you will see hello {{msg}}
NOTE: this comes from the remote server: b.html.
I set a timer there, every 2 seconds, change the value of msg, I wish the {{msg}} in page could change to a random number.
main.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/2.7.0/vue-router.min.js"></script>
</head>
<body>
<div id="app">
<p>
<router-link to="/foo">Go to Foo</router-link>
</p>
<router-view></router-view>
</div>
<script>
const Foo = {
template: '<div v-html="template1"></div>',
data: function () {
return {
template1: null
}
},
created: function () {
this.fetchData()
},
watch: {
'$route': 'fetchData'
},
methods: {
fetchData () {
var that = this
$.get("http://localhost/try/b.html", function(data, status) {
that.template1 = data
})
}
}
}
const routes = [
{ path: '/foo', component: Foo }
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')
function change() {
app.msg = Math.random()
}
setInterval(change, 2000)
</script>
</body>
</html>
b.html
<div>
hello
{{msg}}
</div>
Use the tools that Vue.js gives you. Put change() in your VM's methods object, then create a created() hook that sets up the interval.
Please note that v-html expects a String, not a Number, so just add .toString() when generating the random number.
var app1 = new Vue({
el: '#app',
data: {
test: '<p style="color: red">THIS IS HTML</p>',
test1: null,
test3: 20,
msg: 10
},
watch: {
msg: function(newVal, oldVal) {
this.test1 = newVal
}
},
methods: {
change() {
this.msg = Math.random().toString()
this.test3 = Math.random()
}
},
created() {
setInterval(this.change, 2000)
}
})
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
<div id="app">
<span v-html="test"></span>
<span v-html="test1"></span>
{{ test3 }}
</div>
Instead of a watcher it is even easier to go for a computed property instead.
var app1 = new Vue({
el: '#app',
data: {
test: '<p style="color: red">THIS IS HTML</p>',
test3: 20,
msg: 10
},
computed: {
test1() {
return this.msg.toString()
}
},
methods: {
change() {
this.msg = Math.random()
this.test3 = Math.random()
}
},
created() {
setInterval(this.change, 2000)
}
})
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
<div id="app">
<span v-html="test"></span>
<span v-html="test1"></span>
{{ test3 }}
</div>
Use v-model instead of v-html :-
var app1 = new Vue({
el: '#app',
data: {
test: '<p style="color: red">THIS IS HTML</p>',
test1: '{{msg}}',
test3: 20,
msg: 10
}
})
function change() {
app1.msg = Math.random()
app1.test3 = Math.random()
}
setInterval(change, 2000)
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
<div id="app">
<span v-html="test"></span>
<span v-model="test1">{{msg}}</span>
{{test3}}
</div>
Finally I get the answer from here
Vue.compile( template )
this will make the template from remote server be parsed again by vuejs.
main.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/2.7.0/vue-router.min.js"></script>
</head>
<body>
<div id="app">
<p>
<router-link to="/foo">Go to Foo</router-link>
</p>
<router-view></router-view>
</div>
<script>
const Foo = {
data: function () {
return {
template1: null,
msg: null
}
},
created: function () {
this.fetchData()
setInterval(this.change, 2000)
},
render: function(createElement) {
if (this.template1)
{
return this.template1();
}
},
methods: {
change() {
this.msg = Math.random()
},
fetchData () {
var that = this
$.get("http://localhost/try/b.html", function(data, status) {
that.template1 = Vue.compile(data).render
})
}
}
}
const routes = [
{ path: '/foo', component: Foo }
]
const router = new VueRouter({
routes
})
const app1 = new Vue({
router
}).$mount('#app')
</script>
</body>
</html>
b.html
<div>
hello
{{msg}}
</div>
Here is my script :
<html>
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.17.0/axios.js"></script>
<body>
<div id="app-3">
<span v-if="seen">{{ textFromApi }}</span>
</div>
<br/>
<script type="text/javascript">
var app3 = new Vue({
el: '#app-3',
data: {
seen: true,
textFromApi: "hello"
},
methods: {
getData() {
return axios.get('https://jsonplaceholder.typicode.com/posts/1')
},
},
created: function () {
this.textFromApi = this.getData();
}
})
</script>
</body>
</html>
I'm trying to modify this.textFromApi from the call of this api: https://jsonplaceholder.typicode.com/posts/1
but my this.textFromApi doesn't seems to update, any ideas why?
Here is a fiddle code:
https://jsfiddle.net/bussiere/5t3v013o/
Edited from remark just below
Regards and thanks
created() is a lifecycle hook, it should be at the same level as data, methods, computed etc. Not a child of methods (so if you nest created() in methods() it will never get executed unless you call the method).
You also don't do anything with the axios promise, you should process it using then ().
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.17.0/axios.js"></script>
<body>
<div id="app-3">
<span v-if="seen">{{ textFromApi }}</span>
</div>
<br/>
<script type="text/javascript">
var app3 = new Vue({
el: '#app-3',
data () {
return {
seen: true,
textFromApi: { title: 'empty'}
}
},
methods: {
getData() {
return axios.get('https://jsonplaceholder.typicode.com/posts/1').then(response => {
this.textFromApi = response.data
})
},
},
created: function () {
this.getData();
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/vue.js"></script>
<meta charset="UTF-8">
<title>V-for example</title>
</head>
<body>
<script type="x/template" id="testTemplate">
<div><h1>{{name}}</h1>
<p>{{Age}}</p></div>
</script>
<div id="example">
<div id="filler">
<template v-for="person in people">
<test-component name="{{person.name}}"></test-component>
</template>
</div>
</div>
<script>
var newComponent = Vue.extend({
template: '#testTemplate',
props: ['name'],
data: function () {
return {
Age: 1010
}
}
});
Vue.component('test-component', newComponent);
new Vue({
el: '#example',
data: {
people: [{
name: 'jason',
age: 15,
complete: true
}, {
name: 'Jeremy',
age: 20,
complete: false
}]
},
ready: function () {
var divoutput = document.querySelector('#filler');
alert(divoutput.innerHTML);
len = this.$data.people.length;
for (i = 0; i < len; i += 1) {
var nameT = this.$data.people[i].name;
divoutput.innerHTML += '<test-component name="' + nameT + '"></test-component>';
}
},
});
</script>
</body> </html>
I'm trying to take all of the people in the Vue data array and inject it into a component and add it to a innerHTML of a div during the Vue.ready() function. I show that result is being injected in to the "filler" array but the components them selves are not being rendered properly. If I make a manual instance of my component it works fine.
You shouldn't try to add Vue component using innerHTML. That's managing the DOM yourself, just let Vue do that on its own. Here is a fiddle:
https://jsfiddle.net/xccjsp4b/
I changed the script template to a div because I'm not certain you can use the script tag like that (although I could be wrong). Then you just use a v-for to loop through the people and pass the relevant data as properties. If each person is going to have their own age, you want it to be a property not a data variable.
Also, use the shorthand binding of :name="person.name" rather than name="{{person.name}}". The : tells Vue to evaluate the expression.