Is it good to access DOM in vue js? - javascript

I want to know is it OK to access DOM in a Vue js application?
For example, if I want to append an element (div) to body tag is this recommended to use document.getElementById in a Vue js method?
I have no data that can be used to make or remove elements based on data.
I really just want to know is it common to use document to access DOM in Vue js?
Something like this :
methods:{
appendToBody(){
let node = document.createElement("div");
document.getElementById("#body").appendChild(node);
}
}

It depends on what part of the DOM you are referring too.
If you want to change the subtree that is handled by Vue, you shouldn't do that. You should rely on reactive properties, conditional rendering, components. If you need to access an DOM element that is a child of the current component you can use refs.
If you need to change a part of the DOM which is outside of Vue's realm then by all means do it.
In your case is not clear what you want to achieve and is hard to give a clear answer.

You can use DOM functions like document.getElementById in Vue to find elements, but never use DOM functions to change the DOM. Always do modifications within Vue by changing variables and react to it in the template.

Related

Access dom element with reactjs

I have an AntD component, and i don't have access to the html markup to use useRef to apply a style to next class , depending by a condition:
span.ant-descriptions-item-content
This is why i used:
if(my condition) {
document.querySelector('span.ant-descriptions-item-content').style.background="red"
}
demo: https://codesandbox.io/s/basic-ant-design-demo-fdwxd?file=/index.js
It is ok to use native ways of accessing dom element like document.querySelector, or exists another method to do this in my case?
It is generally not recommended to mix different tools that handle changing how the web page is rendering. This can cause unpredictable behavior and components not updating correctly. If you want to change the appearance of a component using React you should be rendering that component within React.

HTML Template element vs document.createDocumentFragment

I'm trying to figure out the difference between using document.createDocumentFragment versus using an HTML <tamplate> element.
Is there a difference between them in behavior or performance?
Both <template> and document.createDocumentFragment are used for storing HTML-like data without rendering it, but the use cases are somewhat different.
The <template> tag's main purpose is to, as the name applies, store HTML for a later time, and or to be used repeatedly across the document. This tag is useful when using a template engine where the contents are usually never changed but the input may be different.
document.createDocumentFragment is used to create an entire DOM tree in JS without the browser rendering it, while still having the ability to use the DOM API with it. This useful when dynamically generating HTML by leveraging the DOM API, and to later inject the results in the actual document's DOM.
More: Template Tag and DocumentFragment

Can you "hijack" rendering part of a Ractive template?

I have a "SuperSelect" control currently implemented as a Ractive component, which augments a regular drop-down select list with searching, filtering, extended option descriptions, and various other goodies. This generally works really well, except that I now need to fill one of these SuperSelects with approximately 7,800 options, and it gets really slow, and slows down the rest of the page as well. The problem seems to be Ractive's internal memory usage; if I re-implement the SuperSelect in vanilla JS, most of the problem goes away. Unfortunately, I can't see a good way to actually make use of my more-efficient SuperSelect without tearing out Ractive completely every place that it's used, which seems like throwing the baby out with the bathwater.
So, basically, I need a way to insert a chunk of DOM that's managed by other code into the middle of a Ractive template, while still allowing the controlling code to be notified when relevant keypaths are updated by the containing Ractive instance, and as far as I can tell none of the existing plugin/extension methods quite fit the bill. So far, I've come up with two hacks combining multiple plugin methods that might work:
Combine an adapter and a decorator. In this case, the decorator would simply replace whatever element it was attached to with the DOM fragment for the SuperSelect. A special SuperSelect control object would then be added to the Ractive instance's data with an adaptor that would let it participate in 2-way binding with the rest of the template, and independently communicate with the decorator code to update the SuperSelect DOM.
Combine a decorator with a mini-component and ractive.observe. In this case, the decorator would again replace a particular template element with the SuperSelect DOM fragment, but it would only be used locally within a component whose template consists of nothing but that one decorated element. The component would serve as a means of resetting the keypath root, so that the decorator code can observe a static set of keypaths in order to update the state of the SuperSelect DOM regardless of how the SuperSelect is embedded in a larger parent ractive instance.
Is there any simpler way to do what I need?
Yes – you could create a component with an empty DOM node and re-render its contents inside an observe handler:
const SuperSelect = Ractive.extend({
template: `
<div><!-- we'll render this bit ourselves --></div>`,
onrender () {
const div = this.find( 'div' );
this.observe( 'items', items => {
// render the items however we want
});
}
});
More complete demo here: http://jsfiddle.net/9w9rrr9s/

Polymer create element dynamically

I need to create an custom-element dynamically.
I tried
var newElement= document.createElement('custom-element');
this is work. but My problem is when I want to add attribute to this element, to bind an array to this element.
I tried
newElement.setAttribute('data','{{data}}')
But it says that it expected to array and received '{{data}}'
How can I add this binding to dynamically elements?
I dont think this is possible right now, please see from kevinpschaaf:
https://github.com/Polymer/polymer/issues/1778
No, we don't currently support this, outside of dom-bind, which is the
only template implementation that late-binds instance children. You
can document.createElement('template', 'dom-bind'), then you can
dynamically append children with binding annotations to its content,
and the bindings will only be evaluated once the dom-bind is attached
to the document. See tests here that show this usage of it:
https://github.com/Polymer/polymer/blob/master/test/unit/dom-bind.html#L95
Note that dom-bind does not currently allow binding to outer scope, so
it has limited use in custom element templates (it's main use case is
for binding between elements in the main document), and that's not
likely to change short-term.
We are achieving a lot of performance optimization by baking the
binding connections into the prototype at registration time for an
element (rather than at instance time), and we haven't built up enough
of the machinery to easily allow runtime addition/removal of bindings.

Adding content to react elements

I am new to react.js and I have heard that this js library reacts badly to anything that modifies it's component structure.
Is there any specific procedure to add content into react elements using Jquery. For example, if we want to add content into react's div field, can we directly use Jquery append method to insert text to that div or is there any other way to implement things?.
The idea is that you either use a traditional approach, or you ditch jQuery and use react and this means using the react rendering tree, probably build tasks, client-side router/SPA.
You should not modify the DOM generated by react components from outside it since it maintains an internal state and a virtual DOM that would become out of sync. You either use one ecosystem or another; they are two very different approaches to writing a website.
If you want to introduce react on a small part of the website first, I would suggest to gather all your data with jquery and then transmit the data into the react component.
Roughly
// gather data with jquery or whatever
var data_array = gatherData();
ReactDOM.render(<MyCustomComponent data={data_array}/>, $('#my-react-root')[0])
Rendering changes during runtime can be managed the same way. Just gather the data again and change the state of the react component accordingly.
If you don't want to extract the data or the html is to complex, you can use dangerouslySetInnerHTML to just path a plain text html string.
From the docs:
<div dangerouslySetInnerHTML={{__html: getMarkup()}} />
Best wishes
Andreas

Categories

Resources