I'm trying to use Vuejs with some plugins.
There are two components
Vue.component('element-one', {
template: '<h1>Element ONE</h1>',
}
And the second one :
Vue.component('element-two', {
template: '<h1>Element TWO</h1>',
}
I want to be able to display the compiled version of element-one in element-two, I know there is something like:
var element = Vue.component('element-one');
new element().$mount().$appendTo('body');
But I'd love to have just the 'mounted' version, and not append it to any place.
Something I can play with in console.log ??
I received an answer from https://gitter.im/vuejs/vue. You can get the element by
new element().$mount().$el
Related
I'm trying to write a function to find child(ren) element(s) within a locator something like:
async findElements(locator: Locator){
return locator.querySelector(some/xpath/or/css);
}
However, I'm seeing the querySelector is not available in Locator. What is the equivalent of querySelector?
I figured it out,
locator.locator(some/xpath/)
I have just started working with playwright. So this may not be the exact answer that are looking for.
I am studying playwright with an existing repository.
[https://github.com/twerske/ng-tube/blob/main/src/app/video-grid/video-grid.component.html]
In this scenario I just want to know that I am getting a list of cards back.
<div class="videos-grid">
<mat-card *ngFor="let video of videos" class="video-card">
I don't need a reference to a parent for this situation. I am able to simply reference the child by class videos-grid. This all exists inside of a angular's For loop. I know Svelte and other frameworks iterate through lists in different ways.
test.only('ngTube has header and cardList', async ({browser}) => {
const page = await browser.newPage();
const context = await browser.newContext();
await page.goto("http://localhost:4200/")
const title = await page.locator('.header-title').textContent();
const videoList = (await page.locator('.video-card').allTextContents()).length;
// await page.pause();
expect(title).toStrictEqual('ngTube');
expect(videoList).toBeGreaterThan(0)
})
Because I want all text contents I can get everything with the classname '.video-card'.
I guess what I am getting at is as long as you can access an identifier you should be able to directly access it. As I run through the documentation more and scenarios I will update/add to this answer.
I was using VueJS in browser mode and am now trying to switch my code to a VueJS SPA and vue-router. I've been stuck for hours with a $refs not working anymore.
To interact with my Google Charts, I was using an absolute reference to the graph (this.$refs.villesChart) to get selected data like that:
computed: {
eventsprox() {
let eventsprox = {
select: () => {
var selection = "";
if (this.$refs.villesChart) selection = this.$refs.villesChart1.chartObject.getSelection();
if (selection.length) {
var row = selection0[0].row + 1;
this.code_commune = this.dataprox[row][4];
this.changerville(this.code_commune, this.dataprox[row][0]);
}
return false;
},
};
return eventsprox;
}
HTML code for graph:
<GChart type="BarChart" id="villesChart" ref="villesChart" :data="dataprox" :options="optionsprox" :events="eventsprox"/>
I don't know why, but in browser mode, this.$refs.villesChart is a component:
[1]: https://i.stack.imgur.com/xJ8pV.png
but now it is a proxy object, and lost its chartObject attribute:
[2]: https://i.stack.imgur.com/JyXrL.png
I'm really confused. Do you have an idea why?
And if I use the proxy object, then I get a Vue warning "Avoid app logic that relies on enumerating keys on a component instance" and it is not working in production environment.
Thanks a lot for your help!!
After hours of testing different solutions, I finally found a solution working with Vue3 and Vue-google-chart 1.1.0.
I got rid of "refs" and put the events definition and code in the data section of my Vue 3 app (instead of computed) and accessed the chart data through a component variable I used to populate it.
Here is my event code where this.dataprox is my data table for the chart:
eventsprox: {
'click': (e) => {
const barselect = parseInt(e.targetID.split('#')[2]) + 1;
this.code_commune = this.dataprox[barselect][4];
this.nom_commune = this.dataprox[barselect][0];
this.changerville(this.code_commune, this.nom_commune);
}
},
My Gchart html code:
<GChart type="AreaChart" :data="datag" :options="optionsg" :events="eventsprox"/>
I hope it can help!
I am using Duet Date Picker in the Ionic 5/ Vue 3 application. The event listener for the duetChange is not working for me.
Here is my code snippet:
<duet-date-picker #duetChange="handleInput($event)"identifier="date" :localization.prop="localisation" direction="left"></duet-date-picker>
handleInput(e: any) {
console.log("e", e);
this.$emit("input", this.content);
}
I have even tried following listners:
v-on:duetChange="handleInput($event)"
v-on:change="handleInput($event)"
#change="handleInput($event)"
Is this the right way to add an event listener or am I missing something?
Here is the code sandbox link:
https://codesandbox.io/s/old-silence-1f0nx?file=/src/App.vue
TIA
I tried to use the duetDatePicker in a Vue CodeSandbox, the following works:
<duet-date-picker
#duetChange="handleInput"
identifier="date"
:localization.prop="localisation_uk"
>
Along with the above, my methods object contained the handleInput function declaration.
Check the App.vue file in the codesandbox for details.
I was able to get it to work the old fashion way...
onMounted(() => {
// Select the date picker component
const date = document.getElementById("date-picker");
// Listen for when date is selected
date.addEventListener("duetChange", function (e) {
console.log("selected date", e.detail.valueAsDate);
});
});
<duet-date-picker id="date-picker"
#duetChange="handleInput"
identifier="date"
:localization.prop="localisation_uk"
>
There's always an overlap with Navbar dropdown when more than one is clicked. It focuses and takes a few minutes to clear this becomes a problem because it causes clutter.
The configuration for this in the Vuepress docs is just to add navbar items and ariaLabel any know how I can stop this behaviour.
themeConfig: {
nav: [
{
text: 'Languages',
ariaLabel: 'Language Menu',
items: [
{ text: 'Chinese', link: '/language/chinese/' },
{ text: 'Japanese', link: '/language/japanese/' }
]
}
]
}
Here's an example
To answer your question one would need to address two distinct issues:
how do I run custom JavaSCript in VuePress?
how do I close any previously open dropdowns on click in my current VuePress theme, using JavaScript?
For the first problem there are several solutions (one of them being by using a custom component with code run in its mounted() hook, but this would require you to include that component in every page and make sure it doesn't run more than one time (since you want to bind events to elements).
I believe the cleanest way would be by adding a <script> to <head> which can be achieved by adding this to the head prop of your .vuepress/config.js export:
head: [
// ...existing stuff, if any,
['script', {}, `
(function() {
// your code here...
})();
`]
]
However, there are a few problems with the above solution. Firstly, it's going to be run as soon as it's parsed, and that's inside the <head> tag. Which means none of the contents of your page are rendered yet. And the second problem is you're in a template literal. You don't really want to be writing JavaScript code in a template literal. Ideally you should be able to put your code in a '.js' file and append it as a <script> tag.
In order to do that, you need to create a .vuepress/public/ folder, if you don't already have one. Place your .js file in there (I used test.js but feel free to name it as you like). Modify the above code to:
['script', {}, `
(function() {
var s = document.createElement('script');
s.src = './test.js';
var h = document.querySelector('head');
h.appendChild(s);
})();
`]
Change ./test.js to your file's name.
Now your file has clean JavaScript and the door is open. Your code executes in the window object context.
To answer the second part of your question, well..., it largely depends on the theme you are using. If you're using the default theme (which seems to be the case, from the SS you posted), this should work, if placed inside your .js file:
document.addEventListener('DOMContentLoaded', fixDropDowns);
function fixDropDowns() {
document.body.addEventListener('click', (ev) => {
const header = document.querySelector('header');
if (header) {
const dds = header.querySelectorAll('.dropdown-wrapper');
[...dds].forEach(el => el.classList.remove('open'));
const curr = ev.target.closest('.dropdown-wrapper');
if (curr) {
curr.classList.add('open');
}
}
})
}
But it's based on a close inspection of the generated markup.
Specifically on the fact the dropdowns have a class of .dropdown-wrapper and that they're opened by toggling class open on them. The above is just an example and will likely not work on other themes and might even stop working on the default theme in some future version.
I am rather new to sencha touch, I've done a lot of research and tutorials to learn the basics but now that I am experimenting I have run into a problem that I can't figure out.
I have a basic DataList which gets its data from a store which displays in a xtemplate.
Within this template I have created a member function which requires store field data to be parsed as a parameter.
I would like to make a thumbnail image (that's source is pulled from the store) execute the member function on click/tap.
I can't find any information on this within the docs, does anyone know the best way to go about this?
Here is a code example (pulled from docs as I can't access my actual code right now).
var tpl = new Ext.XTemplate(
'<p>Name: {name}</p>'
{
tapFunction: function(name){
alert(name);
}
}
);
tpl.overwrite(panel.body, data);
I want to make the paragraph clickable which will then execute the tapFunction() member function and pass the {name} variable.
Doing something like onclick="{[this.tapFunction(values.name)]} " does not seem to work.
I think functions in template are executed as soon as the view is rendered so I don't think this is the proper solution.
What I would do in your case is :
Add a unique class to your < p > tag
tpl : '<p class="my-p-tag">{name}</p>'
Detect the itemtap event on the list
In your dataview controller, you add an tap event listener on your list.
refs: {
myList: 'WHATEVER_REFERENCE_MATCHES_YOUR_LIST'
},
control: {
myList: {
itemtap: 'listItemTap'
}
}
Check if the target of the tap is the < p > tag
To do so, implement your listItemTap function like so :
listItemTap: function(list,index,target,record,e){
var node = e.target;
if (node.className && node.className.indexOf('my-p-tag') > -1) {
console.log(record.get('name'));
}
}
Hope this helps