How to set InnerText with directive in SSR Vue/Nuxt - vue.js

I want to port my vue directive to also render server side.
client side:
mydirective(el,binding,vnode){
el.innerText = vnode.context.$data.points
}
What i have working so far in nuxt.config.js:
render: {
bundleRenderer: {
directives: {
mydirective(node, binding){
var points = node.context.$data.points //works
node.data.style = [{backgroundColor: 'green'}] //works
node.data.innerText = points //NOT working
node.data.textContent = points //NOT working
}
I cant find the element reference.
i used the following function to search through the node object:
Object.keys(node).forEach(key=>{
console.log(key)
console.log( node[key])
console.log('============================%%%%%%%%%%%%%%%%%%%%%================================')
})
enter code here

Found it:
mydirective(node, binding){
var points = node.context.$data.points
node.data.domProps = {
innerHTML: points
}
}
documentation: https://v2.vuejs.org/v2/guide/render-function.html#The-Virtual-DOM

Related

Passing variables to a querystring within a vuejs component

I have a script I've used from codepen to create Tinder-like swipe cards. It all works fine except for one thing - I need to pass a querystring with variables so when the user swipes right they are taken to another page. In this section of code I can do this if the URL is plain like so:
if (!approved) {
position.x = -x;
position.rotation = -maxRotation;
icon.type = 'pass';
}else{
window.location.href = "recipe.html"
}
icon.opacity = 1;
setTimeout(() => this.showing = false, 200);
}
},
(full code is on the Codepen link above)
But if I try and pass vars to the querystring it doesn't work. I've tried:
window.location.href = "recipe.html?recipeid="+idMeal;
And
window.location.href = "recipe.html?recipeid="+{{ idMeal }};
And even
window.location.href = "recipe.html?recipeid="+`${idMeal}`;
But I can't get it to work. Any ideas would be gratefully received.
You should use,
router.push({ path: 'swipe', query: { plan: 'beauty lady' } })
documented here
https://router.vuejs.org/guide/essentials/navigation.html

VueJS - create component programmatically by name

I'm trying to build a dynamic Vue system, where I want to insert custom components knowing only their name. Inspiration from here took me to do:
export default {
name: 'MySite',
mixins: [MyMixin],
components: {MyComponent1, MyComponent2},
...
}
...
mounted() {
var ComponentClass = Vue.extend(MyComponent1)
var instance = new ComponentClass()
instance.$mount() // pass nothing
this.$refs.container.appendChild(instance.$el)
}
Now I want to do the same thing, but knowing only the component name 'MyComponent1' as String. What is the way to do it ? I guess it's more related to pure JavaScript than Vue, but I can't figure out how to do it.
you are right is a simple js.
look at the example below, most importend thing is eval()
class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
get getHeight() {
return this.height
}
}
// js string code
var code = "new Polygon(15, 200)";
// convert it to code;
var cls = eval(code);
console.log(cls.getHeight)
I found that using
this.$options.__proto__.components['MyComponent1']
works and do what I want. Is it the cleanest solution ?

Getting reactivity from watch in Vue.js

Trying to make a component in Vue.js, which first shows image via thumbnail, loading full image in background, and when loaded, show full image.
The thing which does not work, component does not react on change of showThumb flag in watch section. What is wrong?
Vue.component('page-image',
{
props: ['data'],
template:
'<img v-if="showThumb == true" v-bind:src="thumbSrc"></img>'+
'<img v-else v-bind:src="fullSrc"></img>',
data: function()
{
return { thumbSrc: '', fullSrc: '', showThumb: true };
},
watch:
{
data: function()
{
this.thumbSrc = data.thumbImg.url;
this.fullSrc = data.fullImg.url;
this.showThumb = true;
var imgElement = new Image();
imgElement.src = this.fullSrc;
imgElement.onload = (function()
{
this.showThumb = false; // <<-- this part is broken
} );
}
}
} );
Note: there is a reason why I do it via 2 img tags - this example is simplified.
Your onload callback will have a different scope than the surrounding watch function, so you cannot set your data property like this. Change it to an arrow function to keep scope:
imgElement.onload = () =>
{
this.showThumb = false;
};
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Passing config to ExtJS prototypes

I'm trying to figure out how ExtJS4 passes around config objects.
I want to do the equivalent of...
store = function(config){
if ( typeof config.call !== 'unndefined' ){
config.url = "server.php?c=" + config.call || config.url;
};
Sketch.Data.AutoSaveStore.superclass.constructor.call(this,config);
};
Ext.extend(store, Ext.data.Store{})
I am probably missing something obvious here, but having dug around in the sandbox file, the closest I have come is....
Ext.define('My.awesome.Class', {
// what i would like to pass.
config:{},
constructor: function(config) {
this.initConfig(config);
return this;
}
});
which doesn't seem to work if you do something like...
var awesome = Ext.create('My.awesome.Class',{
name="Super awesome"
});
alert(awesome.getName()); // 'awesome.getName is not a function'
However
Ext.define('My.awesome.Class', {
// The default config
config: {
name: 'Awesome',
isAwesome: true
},
constructor: function(config) {
this.initConfig(config);
return this;
}
});
var awesome = Ext.create('My.awesome.Class',{
name="Super awesome"
});
alert(awesome.getName()); // 'Super Awesome'
This is biting me in the rear end when trying to do complex store extensions.
Anyone have any idea how I pass a bunch of random params to the prototype?
You should not be using new operator to create new instance on your class. In ExtJS4, you should use Ext.create() method.
Try doing:
var awesome = Ext.create('My.awesome.Class');
alert(awesome.getName());
And if you want to pass some param when creating an instance, you can do the following
var awesome = Ext.create('My.awesome.Class',{name:'New Awesome'});

looping through DOM / mootools sortables

I can't seem to get a handle on my list of sortables. They are a list of list elements, each with a
form inside, which I need to get the values from.
Sortables.implement({
serialize: function(){
var serial = [];
this.list.getChildren().each(function(el, i){
serial[i] = el.getProperty('id');
}, this);
return serial;
}
});
var sort = new Sortables('.teams', {
handle: '.drag-handle',
clone: true,
onStart: function(el) {
el.fade('hide');
},
onComplete: function(el) {
//go go gadget go
order = this.serialize();
alert(order);
for(var i=0; i<order.length;i++) {
if (order[i]) {
//alert(order[i].substr(5, order[i].length));
}
}
}
});
the sortables list is then added to a list in a loop with sort.addItems(li); . But when I try to get the sortables outside of the sortables onComplete declaration, js says this.list is undefined.
Approaching the problem from another angle:
Trying to loop through the DOM gives me equally bizarre results. Here are the firebug console results for some code:
var a = document.getElementById('teams').childNodes;
var b = document.getElementById('teams').childNodes.length;
try {
console.log('myVar: ', a);
console.log('myVar.length: ', b);
} catch(e) {
alert("error logging");
}
Hardcoding one li element into the HTML (rather than being injected via JS) changes length == 1, and allows me to access that single element, leading me to believe that accessing injected elements via the DOM is the problem (for this method)
Trying to get the objects with document.getElementById('teams').childNodes[i] returns undefined.
thank you for any help!
not sure why this would fail, i tried it in several ways and it all works
http://www.jsfiddle.net/M7zLG/ test case along with html markup
here is the source that works for local refernece, using the native built-in .serialize method as well as a custom one that walks the dom and gets a custom attribute rel, which can be your DB IDs in their new order (I tend to do that)
var order = []; // global
var sort = new Sortables('.teams', {
handle: '.drag-handle',
clone: true,
onStart: function(el) {
el.fade('hide');
},
onComplete: function(el) {
//go go gadget go
order = this.serialize();
}
});
var mySerialize = function(parentEl) {
var myIds = [];
parentEl.getElements("li").each(function(el) {
myIds.push(el.get("rel"));
});
return myIds;
};
$("saveorder").addEvents({
click: function() {
console.log(sort.serialize());
console.log(order);
console.log(mySerialize($("teams")));
}
});