How to determine if vue.js is used in a site or web app? - vue.js

Is there a command in console? Or a tell tale sign like ng directives used in angular for vue that let you know if it's used in a site or app?

The Vue dev tools uses three different approaches.
One of the approaches is this:
// Method 3: Scan all elements inside document
const all = document.querySelectorAll('*')
let el
for (let i = 0; i < all.length; i++) {
if (all[i].__vue__) {
el = all[i]
break
}
}
if (el) {
let Vue = Object.getPrototypeOf(el.__vue__).constructor
while (Vue.super) {
Vue = Vue.super
}
win.postMessage({
devtoolsEnabled: Vue.config.devtools,
vueDetected: true,
}, '*')
return
}

Related

Add CoreUI icon to DevExtreme dxDataGrid column header in Vue.js

Currently I am working on a new UI for a legacy API. Unfortunately, this one delivers HTML source code for a column header. This code usually creates a FontAwesome icon. This library will not be used in the new project.
I found a very similar icon in the Icon Library of CoreUI. Now it is only a matter of rendering the icon at this point. However, no approach has been successful so far. How can I replace the icon in the headerCellTemplate method?
Or maybe there is a completely different, much better approach to do this. I don't know if I am on the right track with this method approach. You can probably use static templates, but I don't know how to do that.
import { CIcon } from '#coreui/vue';
import { cilCheckCircle } from '#coreui/icons';
headerCellTemplate: (element, info) => {
element.innerHTML = curr.ColumnTitle;
if (element.firstChild.nodeName === 'I') {
// WORKS
//element.firstChild.innerHTML = 'Done';
// ANOTHER EXPERIMENT
//const componentClass = Vue.extend(cilCheckCircle);
//const instance = new componentClass();
//instance.$mount();
//element.removeChild(element.firstChild);
//element.appendChild(instance.$el);
// ALSO NOT WORKING
return CIcon.render.call(this, cilCheckCircle);
}
}
I finally found a solution after revisiting this interesting article.
import Vue from 'vue';
import { CIcon } from '#coreui/vue';
import { cilCheckCircle } from '#coreui/icons';
headerCellTemplate: (element, info) => {
element.innerHTML = curr.ColumnTitle;
if (element.firstChild.nodeName === 'I') {
const cIconClass = Vue.extend(CIcon);
const instance = new cIconClass({
propsData: { content: cilCheckCircle }
});
instance.$mount(element.firstChild);
}
}
I don't know, though, if this is the ideal solution. So feel free to tell me, if you have a better, less complex solution.

Adding embedded mode in docusaurus

I am using docusaurus 1.14.4
I need to create embedded mode for each document which remove header, footer and left navigation.
Page url look like this http://localhost:3000/...../?mode=emb
I figure out a way by adding this piece of script to each md file
<script>
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
var mode = getParameterByName('mode');
if (mode === 'emb') {
setTimeout(()=>{
let list = ['fixedHeaderContainer', 'docsNavContainer', 'nav-footer', 'docs-prevnext'];
for (var itemClassName of list) {
var item = document.getElementsByClassName(itemClassName)[0]
item.parentNode.removeChild(item)
}
document.getElementsByClassName('navPusher')[0].style.paddingTop = 0;
document.getElementsByClassName('mainContainer')[0].style.paddingTop = 0;
}, 0)
}
</script>
It work but does not look like a proper way. Can anyone suggest a better way?
Docusaurus maintainer here. There's no supported way of doing this. May I know what your motivations for doing this are?

Adding auto-ads with Vue.js

I have tried to add auto-ads to my website which uses Vue.js but there are no requests via the script.
I have tried the vue-adsense plugin, which can be found on npm https://www.npmjs.com/package/vue-google-adsense
but they have no support for auto-ads, normal ads work fine with this plugin.
This is the code which needs to be added:
<script data-ad-client="ca-pub-0990618353003742" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
Is there a solution for adding auto-ads on a vue.js site?
Script tags cannot be placed in a part of the DOM controlled by an instance of Vue(). All you need to do is place the script in the <head> of your document. If you are using Vue CLI to create your project, the file you do this in is /public/index.html.
You can init your ads how many you've added after change data. For example.
mounted: function () {
this.data = [1,2,3,4];
var adCount=3;
for (var i = 0; i < parseInt(adCount); i++) {
window.setTimeout(function () {
console.log('vue ad ' + i + ' inited');
(adsybygoogle = window.adsybygoogle || []).push({});
}, 300);
}
},

How can I use "<nuxt-link>" in content rendered with "v-html"?

I have a utilities plugin for Nuxt.js that I created with a method to parse hashtags and mentions and replace them with <nuxt-link>. I am then using v-html to inject the converted data back into the template. My issue is that the <nuxt-link> are not being parsed with v-html.
import Vue from 'vue';
Vue.mixin({
methods: {
replaceMentions(data) {
// Tags
const tagRegEx = /\[#tag:[a-zA-Z0-9_-]*\]/g;
let tagMatch;
while ((tagMatch = tagRegEx.exec(data)) !== null) {
const tag = Array.from(tagMatch[0].matchAll(/\[#tag:(.*?)\]/g));
data = data.replace(tag[0][0], '<nuxt-link to="/search?q=' + tag[0][1] + '">#' + tag[0][1] + '</a>');
};
// Users
const userRegEx = /\[#user:[a-zA-Z0-9_-]*\]/g;
let userMatch;
while ((userMatch = userRegEx.exec(data)) !== null) {
const user = Array.from(userMatch[0].matchAll(/\[#user:(.*?)\]/g));
data = data.replace(user[0][0], '<nuxt-link to="/users/' + user[0][1] + '">#' + user[0][1] + '</>');
};
return data;
}
}
});
Does anyone have any tips for how I could make these work as proper nuxt compatible links? I already tried using <a> and it works fine, I would just prefer to utilize proper nuxt compatible links.
I think the discussion here basically answers the question: https://github.com/nuxt-community/modules/issues/185
Summarized, there are two options:
Render the HTML with a full Vue build and then attach the rendered node.
(Preferred) Find the links in the HTML and make them call router push instead of their default action.

SPFX 1.7.1 webpart is not working on IE11

I have created a new SharePoint web part (version 1.7.1). I'm using the react template. The web part is very basic, yet doesn't run on IE 11.
The error returned is
Object doesn't support property or method 'find'
I don't use find in any of my .ts files, so I found the .find method is being called by the .js files that were transpiled from my .ts files.
Can anybody confirm this to be a bug in SPFX v1.7.1?
If so, is there a solution.
I know this could be fixed by introducing a shim, but I don't know how to configure this for SPFX and can't find any documentation that explains how to do this.
Any help is welcome.
If I recall correctly, this is because IE 11 doesn't support Element.closest, which is used by the React engine.
I have personally used element-closest to polyfill it, although I'm sure other options exist.
// beginning of WebPart code file
import 'element-closest/browser';
import * as React from 'react';
import * as ReactDom from 'react-dom';
// rest of the code, etc.
With refer to this article, we can see that the Array.prototype.find() method not support IE browser. But, This method has been added to the ECMAScript 2015 specification and may not be available in all JavaScript implementations yet. However, you can polyfill Array.prototype.find with the following snippet:
// https://tc39.github.io/ecma262/#sec-array.prototype.find
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
value: function(predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];
// 5. Let k be 0.
var k = 0;
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return kValue.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return kValue;
}
// e. Increase k by 1.
k++;
}
// 7. Return undefined.
return undefined;
},
configurable: true,
writable: true
});
}
Besides, as far as I know, when we use React, by default, the generated react project supports all modern browsers. Support for Internet Explorer 9, 10, and 11 requires polyfills. You could check it and import related packages.
You can adjust your tsconfig.json file: set "target" to "es5" under "compilerOptions".
Typescript will create polyfills for you.
I had the same issue. Use this import in your webpart.ts file.
import 'core-js/modules/es6.array.find';