Enhance parts of multi page application with react or vue
I had done a similar kind of stuff in the past. I injected a small react component into the DOM.
Here is how I did it:
Create a React component in JSX, let's call it Demo
:
export class Demo extends React.Component { render() { return <h1>This is a dummy component.</h1> }}
Now use the renderToStaticMarkup function to get the static html.
const staticMarkup = renderToStaticMarkup(<Demo PASS_YOUR_PROPS/>);
You have the HTML, now you can insert this markup at the desired location using the innerHTML.
Apologies if I misunderstood your question.
UPDATE
We could also use the render()
for this purpose. Example:
document.getElementById("button").onclick = () => { render( <Demo PASS_YOUR_PROPS/>, document.getElementById("root") );};
Working solution with render() and renderToStaticMarkup: https://codesandbox.io/s/w061xx0n38
render()
Render a ReactElement into the DOM in the supplied container andreturn a reference to the component.
If the ReactElement was previously rendered into the container, thiswill perform an update on it and only mutate the DOM as necessary toreflect the latest React component.
renderToStaticMarkup()
This doesn't create extra DOM attributes such as data-react-id, thatReact uses internally. This is useful if you want to use React as asimple static page generator, as stripping away the extra attributescan save lots of bytes.
Since you have an existing multi page application without a build step (that is, without webpack/babel), I believe one very simple way of achieving what you want is using Vue.js.
You can define a template and update only the data.
Here's a demo of how you would do the code you showed in the question:
new Vue({ el: '#app', data: { ajaxDataAvailable: false, ajaxData: { title: '', results: [] } }, methods: { fetchUsers() { this.ajaxDataAvailable = false; // hide user list $.getJSON("https://jsonplaceholder.typicode.com/users", (data) => { this.ajaxData.title = 'These are our Users at ' + new Date().toISOString(); this.ajaxData.results = data; this.ajaxDataAvailable = true; // allow users to be displayed }); } }})
/* CSS just for demo, does not affect functionality could be existing CSS */.search-container { border: 2px solid black; padding: 5px; }.title-item { background: gray; font-weight: bold; font-size: x-large; }.result-item { border: 1px solid gray; padding: 3px; }
<script src="https://unpkg.com/vue"></script><script src="https://code.jquery.com/jquery-3.3.1.min.js"></script><div id="app"> <button @click="fetchUsers">Click to fetch the Users</button><br><br> <div class="search-container" v-if="ajaxDataAvailable"> <div class="search-item"> <div class="title-item"> {{ ajaxData.title }}</div> <div class="result-item" v-for="result in ajaxData.results"> Name: {{ result.name }} - Phone: {{ result.phone }} - Edit name: <input v-model="result.name"> </div> </div> </div></div>
In this example, we have:
- A method
fetchUsers
that will perform the ajax call; - The
fetchUsers
method is bound to theclick
event of the<button>
via@click="methodName"
(which is a shorthand tov-on:click="methodName"
). - A
v-if
(v-if="ajaxDataAvailable"
) that makes the.search-container
div hidden until theajaxDataAvailable
property istrue
. - The rendering of some data in the template using interpolation:
{{ ajaxData.title }}
, note that this picks the value from the objects declared in thedata:
part of the Vue instance (thenew Vue({...
code) below and is automatically updated wheneverajaxData.title
changes (what happens inside thefetchUsers
method when the Ajax call completes. - The rendering of a list using
v-for
:v-for="result in ajaxData.results"
. This iterates in theajaxData.results
array, that is too updated inside thefetchUsers
method. - The use of an
<input>
element with thev-model
directive, which allows us to edit theresult.name
value directly (which also updates the template automatically).
There's much more to Vue, this is just an example. If needed, more elaborated demos can be made.
As far as integrating into an existing application, you could paste this very code into any HTML page and it would be already working, no need for webpack/babel whatsoever.
So, there are two things you could do to re-use your code:
- I would recommend React for sharing code as components. This page from Official docs explains how to use react with jquery.Additional resources for integrating react and jquery jquery-ui with react, Using react and jquery together, react-training
- Or, use some template engine so you do not need to go through the trouble of integrating a new library and making it work alongside jquery. This SO answer provides lot of options for doing this.
Unless your planning on migrating your jquery app to react in the long run, I would not recommend using react just for one page. It would be easier to go with the template engine route.