{"id":16241605,"url":"https://github.com/tve/node-red-vue","last_synced_at":"2025-04-08T09:53:11.457Z","repository":{"id":65185491,"uuid":"586179013","full_name":"tve/node-red-vue","owner":"tve","description":"Write Node-RED node templates using Vue.js","archived":false,"fork":false,"pushed_at":"2023-02-20T06:47:39.000Z","size":302,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-14T06:51:21.561Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tve.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-07T08:02:20.000Z","updated_at":"2023-12-28T12:21:39.000Z","dependencies_parsed_at":"2024-11-04T11:40:55.671Z","dependency_job_id":"36efadc2-412f-4815-8ecc-7d36f173a3dd","html_url":"https://github.com/tve/node-red-vue","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tve%2Fnode-red-vue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tve%2Fnode-red-vue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tve%2Fnode-red-vue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tve%2Fnode-red-vue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tve","download_url":"https://codeload.github.com/tve/node-red-vue/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247819946,"owners_count":21001394,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-10T14:08:06.655Z","updated_at":"2025-04-08T09:53:11.421Z","avatar_url":"https://github.com/tve.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Node-RED Vue\n\nWrite Node-RED node templates in Vue.js.\nNode templates implement the \"Properties\" pane when editing a node in the flow editor.\nThe standard way to write them is by placing a `\u003cnode-name\u003e.html`\nfile in the directory with the node's `.js` file, and to write a bunch of raw HTML and JS in thet\nfile to implement the editing pane.\nNode-RED Vue replaces this with a`.vue` file that provides\na Vue component that implements the editing pane.\n\n**WARNING**: this is a construction zone, contact the author on the Node-RED forum for info.\n\n## How-to\n\nIn order to write a Node-RED node using Vue:\n\n- Do not write a `node.html` file, instead write a `node.vue` file. The `.vue` file must be in\n  the same directory hand have the same base-name as the `.js` file (i.e. the same requirements\n  as the former `.html` file).\n- In the `node.js` file, register the `node.vue` file by placing\n  after the usual call to `RED.nodes.registerType(\"my-node-name\", ...)` the following:\n  `RED.plugins.get('node-red-vue').createVueTemplate(\"my-node-name\", __filename)`\n- In the `.vue` file write a Vue component to display the node configuration interface using the\n  Vue Options API, not the Vue Composition API (sorry).\n- Define the configuration variables, i.e., what normall goes into the `defaults` object in the\n  standard `node.html` file, as `props` in the Vue component.\n  - Use the Vue types so the values are not strings where desired, e.g. Number, Array, Object, String, ...\n  - Use the Vue `default` property instead of the conventional `value` property.\n  - Use the Vue `required` property the same way as the conventional `required` property.\n  - For variables that are references to config nodes, use a type of String and set a\n    `configType` property to the type of the config node (e.g. 'mqtt-broker', 'flexdash container', ...).\n  - Validations and filters are not yet supported.\n- Place all other standard node type properties into a `node_red` field in the Vue options object,\n  e.g., `category`, `color`, `inputs`, `outputs`, `icon`, `label`, `labelStyle`, `paletteLabel`, etc.\n- Place help text for the help panel in the flow editor side-panel into a `help` field in the Vue\n  options object and write the help using markdown syntax.\n\n### Component life-cycle\n\n- The component for a node is created and mounted when the node is edited, i.e., when the\n  edit pane is to be shown. This happens within the Node-RED oneditprepare callback.\n- The node properties are passed into the component's props.\n- As the user changes values, the component should emit `update:prop` events with the prop\n  name and new value. These values are saved in a temporary object and also fed back into the\n  component's props.\n- If the user clicks the Done button, the component is destroyed and the temporary object\n  values saved to the component properties.\n- If the user clicks the Cancel button, the component is destroyed and the temporary object is\n  discarded.\n- A simple event bus `$bus` is provided to the component for additional events, currently\n  `OnSave` and `OnCancel` events are generated to allow edited values to be saved or discarded\n  \"last-minute\" (this is used by the code editor component, for example).\n\n## Benefits\n\n- Live in 2023, not 2015...\n- Clean abstraction of functionality using components instead of doing JQuery DOM manipulation\n  all over the place.\n- Hot-module reload while developing: no more restarting Node-RED and reloading the browser to\n  see changes, they show up instantaneously\n- Use components for the individual properties and have all the low-level details neatly encapsulated.\n  No more:\n  - conversion from string to the real type of the node property\n  - fiddling with initialization of typedInput in oneditprepare\n  - mistakes matching the various HTML element IDs to the property names\n  - saving of text editor content in oneditsave\n- Use TailWindCSS to style components, not more low-level CSS wrangling (unless you want to).\n- For advanced programmers: write the Vue component using typescript to reduce errors\n\n## Missing features\n\n- validation of inputs (this needs to unify input field validation and node validation to avoid the\n  the current total disconnect between property validation and typedInput validation)\n- support for less-common input types, such as env and credentials.\n- loading CSS is not implemented (but it's easy to do), I'm using Master.CSS and haven't needed\n  it yet...\n\n## Internals\n\n### Repo layout\n\nThere are two applications in this repository: the Node-RED runtime plugin running on the\nserver and the flow editor plugin running in the browser.\n\nThe runtime plugin is in node-red-vue.js, the flow editor plugin is in the `client` directory.\nThe node-red-vue.html file is the \"traditional\" flow-editor template but all it does is kick\noff the loading of the real client, which is a TypeScript+Vue application.\n\nThe Vue app has its own node_modules, which are used to load dev tools as well as build a\npackaged vue application.\n\n### External libraries used\n\nThis plugin leverages primarily 4 libraries:\n\n- The Vue run-time is loaded into the flow editor, it drives the reactive rendering and manages\n  the components\n- The Vue compiler is used to compile the `.vue` files into javascript, this happens in the\n  Node-RED run-time at start-up\n- ES-module-shims is a library that facilitates dynamic loading of modules and is extensively\n  used to load the Vue components, the Vue run-time, and any other dependencies into the flow editor\n- Master.CSS is used to make it easier to style HTML elements without using traditional style\n  sheets. It's similar to TailwindCSS but takes it to the next level and weighs in at a fraction\n  of the size and implementation complexity.\n\n### Overal functioning\n\nThe starting point for a node that uses a Vue template is:\n\n- the traditional node `.js` file that gets loaded into the run-time\n- a `.vue` \"template\" file that replaces the traditional node `.html` file\n- optionally some components in a `components` subdir\n\nWhen Node-RED starts up:\n\n- it loads the node-red-vue plugin, which initialises things\n- it loads the `.js` file and that calls createVueTemplate in the node-red-vue plugin\n- the plugin looks for the `.vue` file and compiles it into a javascript module, plus the\n  node descriptor that needs to be passed to `RED.nodes.registerType`, plus\n  the HTML template with the `\u003cinput\u003e` tags for all the properties of the node, plus the\n  text for the help panel.\n- the plugin then inserts the node descriptor, the HTML template, and the help text into\n  the Node-RED node registry so they get shipped\n  to the flow editor as if they had come from a traditional `.html` file\n- the javascript module is saved separately and is sent to the flow editor via a different route\n\nWhen the flow editor starts up:\n\n- the javascript surrounding the node descriptor gets executed, which causes the node type to\n  be registered with the descriptor (node name, category, number of inputs, etc.) generated\n  from the Vue component definition\n- the descriptor's oneditprepare function links into the plugin\n  to load the Vue component and render it in the edit pane\n\nIn the flow editor, when a user clicks on a node to edit it:\n\n- the flow editor calls oneditprepare, which calls into the node-red-vue plugin\n- a Vue \"app\" is created and mounted in the edit pane, it is fed the current value of the\n  node properties as (properly typed) props\n- when a property value is edited by the user, the Vue component must emit an event (that's a\n  Vue event that propagates up the hierarchy) with the new value\n- this event is processed by the plugin and the new value is saved in a temporary object\n- when the user clicks \"Done\", the plugin is invoked via oneditsave and saves the temporary\n  object into the node properties\n- if the user clicks \"Cancel\", the plugin is invoked via oneditcancel and the temporary\n  object is discarded\n- in either of the two exit cases the Vue app is unmounted and deleted\n- if, during the editing of the node, the user chooses to create or edit a config node then\n  the Vue app is hidden but remains alive so internal state is preserved\n- if the config node also uses Vue then the same process is followed and more than one Vue app\n  ends up being active at a time\n\nIf the user edits the `.vue` file:\n\n- the plugin detects the change and recompiles the `.vue` file, it then sends a notification\n  to any connected flow editors, which load the new version of the component\n- the new version is currently just loaded and the user has to close the edit pane and re-open\n  it to see the changes (further improvement planned...)\n- the node type definition (e.g. the list of properties) cannot be changed this way, this is a\n  limitation of the flow editor.)\n- additional components used by the main Vue component are loaded into the flow editor using the\n  same mechanism (they are sent in bulk at start-up and they can similarly be dynamically updated)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftve%2Fnode-red-vue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftve%2Fnode-red-vue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftve%2Fnode-red-vue/lists"}