I'm trying to use tinyMCE in VueJS. In numerous examples I'm seeing tinymce.init() being used within script tags:
<script>
tinymce.init({
selector: '#myTextarea',
setup: function (editor) {
editor.on('init', function (e) {
editor.setContent('<p>Hello world!</p>');
});
}
});
</script>
However, when I look at the TinyMCE Vue Integration documents, I see init being done directly in the HTML:
<div>
<editor
id="editor"
api-key="no-api-key"
:init="{
height: 500,
plugins: [
...
],
toolbar: '...'
}"
/>
</div>
The WYSIWYG initializes properly for me with init being done in the HTML section, but there are numerous instances where a function needs to go within init (see first code block) to load initial content, or deal with image uploads etc. This doesn't work with init being done within the <editor/> tag.
In VueJS with init being done within the <editor/> tag, how can I add the 'setup' function seen in the first codeblock?
Related
I need to present some random/dynamic html data in my project that might contain style tags, by default vue.js doesn't allow style tags in the template to avoid messing styles that is a very good option.
To make my project work I tried some runtime-component projects on github but they doesn't accept css styles in the way I need, so I came up with the solution of creating my own runtime component with accepting css styles data.
What I want in code is sth like:
<template>
<div v-html="template"></div>
</template>
<script>
export default {
name: "DynamicTemplate",
props: {template: String, style: String}
}
</script>
<style scoped>
// style data goes here
</style>
Any alternative working solution is welcome too :)
I tried v-html and v-text attributes on the component style tag (without any results) and also using css #import statement with base64 encoded css codes (got some errors like Cannot read properties of undefined), but none of them worked :(
You can encapsulate the data inside the style tags inside the component tag provided by vue in this manner ->
<component :is="'style'"> .test-class { color: red; }....Your style data </component>
An example of the same can be found in this project I created
https://codesandbox.io/s/interesting-dewdney-id9erd?file=/src/components/HelloWorld.vue
Edit 1 =>
After reading the comment as I think the CSS scope compilation is done during the build process not during runtime thus having css at runtime won't scope it an alternate solution for this can be embedding your HTML code inside an iframe and passing your code to the iframe using the srcdoc attribute.An example of the same is given below
https://codesandbox.io/s/currying-cherry-zzv3wk?file=/src/components/HelloWorld.vue
<template>
<iframe style="width: 100vw; height: 80vh" :srcdoc="htmlCssCode"></iframe>
</template>
<script>
export default {
data() {
return {
htmlCssCode: `Your Html code here`
<html>
Here is an example of passing that can pass dynamic HTML data in your project with an example using style tags
<template>
<div>
<div v-html="template" :style="style"></div>
</div>
</template>
<script>
export default {
name: 'DynamicTemplate',
props: {
template: {
type: String,
required: true
},
style: {
type: Object,
required: false,
default: () => {}
}
}
}
</script>
Here is the component being used.
<DynamicTemplate
:template="<p>This is some dynamic HTML content</p>"
:style="{ color: 'red', font-size: '14px' }">
</DynamicTemplate>
Here is an example of passing that can pass dynamic HTML data in your project with an example of passing classes dynamically
<template>
<div>
<div v-html="template" :class="classes"></div>
</div>
</template>
<script>
export default {
name: 'DynamicTemplate',
props: {
template: {
type: String,
required: true
},
classes: {
type: Object,
required: false,
default: () => {}
}
}
}
</script>
Here is the component being used.
<DynamicTemplate
:template="template"
:classes="classes"
/>
Everything works fine when developing but once I export for production 1 component doesn't render and instead gets replaced by <!--->
After some debugging, I discovered that this happens because of require()
I have images with dynamic URLs that look like this:
:src="require(`#/assets/path/${variable}`)"
This works in dev but once I build the app for production the component doesn't render.
When I replace the path with
src="#/assets/path/file.png"
The component shows up and works properly
Is it something that I can provide to webpack in vue.config.js?
Is there a way to use variables in path without require()?
The expression inside v-bind is executed at runtime, webpack aliases at compile time.
Move require() from html template to data() and it should work in production.
Simple example:
<template>
<img :src="getImg" />
</template>
<script>
export default {
name: 'Example',
data() {
return {
file: 'image',
}
},
methods: {
getImg() {
return require(`#/assets/images/${this.file}.png`)
},
},
}
</script>
I am using VueJS to build a website and I got to the point where I want to include my embedded profile into a page/Component in Vue. It seems to work only if I refresh the page. When I navigate from other pages to this page it is not displayed.
In my public/index.html I included LinkedIn Library Script
<script type="text/javascript" src="https://platform.linkedin.com/badges/js/profile.js" async defer></script>
In my component:
<template>
<!-- some other code -->
<div class="col-md-4 col-sm-12 text-sm-center">
<div class="LI-profile-badge" data-version="v1" data-size="medium" data-locale="en_US" data-type="vertical" data-theme="dark" data-vanity="nicolae-orlov">
</div>
</div>
</template>
I saw some info that I need to reload the component to force it to re-render but I am not sure how. Any help is much appreciated.
If you want to add a script tag only on a specific component, you can use PostScribe to render a script after load.
After installing (npm i postscribe --save) and importing (import postscribe from 'postscribe'), you can add your script tag in the mounted lifecycle hook:
mounted() {
postscribe('#linkedin', '<script src="https://platform.linkedin.com/badges/js/profile.js"><\/script>')
}
where #linkedin refers to the ID of your profile badge element (add an ID if necessary)
Your linkedin badge should now be embedded in your Vue component.
You can add the javascript by injecting script into head and then adding the html into the respective component. This is how you can inject javascript directly into head from the component.
<script>
export default {
head(){
return{
script : [
{
src:
'https://platform.linkedin.com/badges/js/profile.js',
type:
'text/javascript'
}
],
}
}
}
</script>
Is it possible to create a Vue Component by passing a CSS selector instead of the name of a custom HTML tag? And, in turn, is it possible to use non-custom HTML tags for template placeholders?
I ask because I am wary of the SEO implications of custom HTML tags.
Not sure if i get your questions right but vuejs does not actually render these custom-tag like template-placeholders. It will transform all template-placeholders with their actual template. See the following example:
CustomComponent.vue
<template><div class="child">Hello World</div></template>
<script>
export default {
name: 'CustomComponent'
}
</script>
Parent Component:
<template>
<div class="parent"><custom-component></custom-component></div>
</template>
<script>
import CustomComponent from './CustomComponent'
export default {
components: {
CustomComponent
}
}
</script>
This will render a dom that looks something like this
<div class="parent"><div class="child">Hello World</div></div>
If you are really concerned about CEO I would recommend looking into server-side rendering. Otherwise all your view components are rendered using javascript execution on the client. Not sure if the search engine crawlers execute javascript or even if they do, how long they will wait for your page to render.
First yes it is possible to define a component using a selector or the element #id to be specific. However, it does not work quite as you are thinking if I understand correctly what you are wanting.
The method is not widely used or even well documented, link & link, but you can use what is known as an x-template. You define the component as follows.
Vue.component('my-cool-component', {
template: '#my-cool-component', //refers to script tag id
data() {
//
},
methods: {
//
}
});
Then you include the actual template markup in your html within an 'text/x-template' script tag with the template id set from your component.
<script type="text/x-template" id="my-cool-component">
<section>
<h1>Title</h1>
<p>...</p>
</section>
</script>
In the case of above you may use just standard html tags.
However to further clarify the second part of your question, you should be able to use custom html tags when naming your components in templates without concern because these are parsed out by Vue.js during rendering. For example if you were to write all you template markup directly in the component instead using template literals as follows,
Vue.component('my-cool-component', {
template: `<section>
<h1>Title</h1>
<p>...</p>
</section>',
data() {
//
},
methods: {
//
}
});
Then in your page markup when you include your custom html element tags <my-cool-component></my-cool-component> Vue will remove the tags and only render the template markup.
<section>
<h1>Title</h1>
<p>...</p>
</section>
We're using HighCharts.js in a Durandal/Hot Towel template in ASP.NET MVC 4. We are simply showing a proof of concept in using a charting API for a dashboard page. However, the graph is not rendering on the page during page load.
We have a custom .js file that holds the following code (copied and pasted from HighCharts.com):
$(document).ready(function () {
$('#reportgraph').highcharts({
chart: {
type: 'bar'
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: ['Apples', 'Bananas', 'Oranges']
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
name: 'Jane',
data: [1, 0, 4]
}, {
name: 'John',
data: [5, 7, 3]
}]
});
});
And a div in an HTML view that is rendering correctly:
<div class="row-fluid">
<div class="span12">
<div class="widget">
<div class="widget-header">
<div class="title">Highcharts</div>
</div>
<div class="widget-body">
<div id="reportgraph" style="width:100%"></div>
</div>
</div>
</div>
</div>
The script bundler contains the following files:
.Include("~/Scripts/jquery-1.9.1.min.js")
.Include("~/Scripts/highcharts.js")
.Include("~/Scripts/custom.js")
.Include("~/Scripts/bootstrap.js")
.Include("~/Scripts/knockout-{version}.debug.js")
.Include("~/Scripts/sammy-{version}.js")
.Include("~/Scripts/toastr.js")
.Include("~/Scripts/Q.js")
.Include("~/Scripts/breeze.debug.js")
.Include("~/Scripts/moment.js"));
Yet the graph does not render. I've been able to successfully render the graph in a Bootstrap application, working with the scripts listed above.
Is there an extra step that must be done in order to work with functions inside document.ready statements on a single page application?
Thanks in advanced!
In a typical Durandal app there's no need to use document ready as at that point only the content of index.html (applicationHost) has been rendered. Everything else gets injected into the DOM by using Durandal's composition.
In order to work with these composed DOM fragments add a viewAttached callback in the vm that accompanies the html view. viewAttached gets the composed view passed in as parameter, which should be used to restrict the jQuery selector.
function viewAttached(view) {
$('#reportgraph', view).highcharts({
...
});
};
In most instances that should be sufficient to get jQuery plugins working. However in Durandal 1.2 viewAttached just ensures that the composed fragment is attached to its parent element not necessarily to the DOM, so you'd have to check if this is sufficient to get highcharts working. That issue will be addressed in upcoming Durandal 2.0 by introducing a documentAttached callback.