Note: The code address for this article is as follows

Back-end code address URL: gitee.com/hotstrip/up…

Front-end code address URL: gitee.com/hotstrip/Wa…

The contents of this article:

  • How is WangEditor introduced into the project — the front end
  • Upload picture realization principle
  • Picture upload interface realization – back end
  • conclusion

How is WangEditor introduced into the project — the front end

How to get started with an unfamiliar component? Generally speaking, the official website and documentation are the best choices. The official website is: WangEditor

In the above official website documentation, there are three installation methods:

  • Download the source file js import
  • Import using package management tools (such as NPM)
  • Using online JS (CDN)

Either way, the principle is the same, loading js files into your project. This field chat uses vue. js for front-end development, so NPM is the most convenient way to introduce.

To do this, simply install the Node environment and type the following command in the command line tool:

NPM install -s wangeditor /** * -s indicates that the Vue project will automatically update its dependencies in package.json file. * Execute NPM install to install * / along with other package.json dependenciesCopy the code

How do I initialize it after installation? Regardless of the code implementation, mentally there are two steps:

  • You need to provide a DOM node for HTML
  • Call the methods of the WangEditor component, associated with the DOM node above

We then leave it to the WangEditor component to create the rich text editor. It’s like a black box, we give it what we need and it will give us what we want.

Understand the idea, then the rest is simple, the core part of the code is as follows:

/** * <div ref= <div ref="editorForm"/> This line * provides an HTML DOM node corresponding to the first step above * / <template> <div class="editor">
    <div ref="editorForm"/>
  </div>
</template>
Copy the code

For step 2, let’s consider the fact that the editor is likely to be called in multiple places, right, so a standalone component would be more appropriate. The usage scenario might look something like this — a rich text editor is rendered free in a child component, other pages import the component on demand, and pages can set and fetch the contents of the rich text editor in real time. The standalone component then faces several problems:

  1. The page passes content parameters to the rich text editor component
  2. After the editor content is updated, pages that introduce rich text editor components can fetch data in real time

The parent component to the child component uses the props property, and the child component to the parent component uses the $emit function. The core code is as follows:

// The editor content parameter passed to set the editor content: {type: String,
      default: ' '}},data() {
    return{// editorContent in the real editor:' ', // Editor object Editor: null}}, watch: {// watch means to listen for the content of the editor to be updated when the content of the parent component changescontent() {this.editor.txt.html(this.content)}}, /** * uses Vue mounted hooks, which are part of the Vue life cycle */mounted() {// Initialize this.editor = new E(this).$refsEditorForm) / / when the editor content change notify the parent component. This editor. CustomConfig. Onchange = (HTML) = > {enclosing editorContent = HTML / / notify the parent control method, The rich component can retrieve the latest editorContent this via the editorContent event.$emit('editorContent', html)
    }
    this.editor.create()
    this.editor.txt.html(this.content)
}
Copy the code

This is the core code of the child component. For the parent component, it is easy to import the child component and add the editorContent event defined by the child component. The core code is as follows:

<template>
  <div id="app"> <h1>WangEditor Demo</h1> // This is where the child component will render the specified initialization data and events that listen for updates to the data < wang-Editor :content="content" @editorContent="getEditorContent"/> <h2> effect area: </h2> <div ref="preview" v-html="content"></div> </div> </template> <script> // introduces the child component import WangEditor from'@/components/wang-editor'
export default {
  name: 'app',
  components: {
    WangEditor
  },
  data() {
    return {
      // 编辑器内容
      content: ' 'GetEditorContent (data) {this.content = data}}} </script>Copy the code

Once this is done, the basic editor is ready and looks like this:

Upload picture realization principle

The former converts an image to Base64 encoding, and then adds data:image/ JPEG in the SRC attribute of the IMG tag. Base64, the prefix is rendered by the browser; The latter is uploading to the server using HTTP and then accessing the image resource through the URI.

With Base64, images don’t need to be uploaded to the server. They can be saved as strings, but the string length is very long. The latter occupies server resources for storage, but is returned to the front end as a string of URI addresses.

If you go back to the form and upload the image, since you’re uploading the image over HTTP, it’s definitely going to involve the back end. Either way, the image is taken from the HTTP request body, the file stream is read, stored on the server, and the URI resource accessible to the image is returned.

WangEditor also provides two ways of uploading pictures: Base64 uploading and interface uploading. The following is the implementation of the interface of uploading pictures at the back end.

Picture upload interface realization – back end

As mentioned above, the background provides an interface for uploading images. The main purpose of this interface is to retrieve the file flow information from the HTTP request, save it to the server, and return the file access address URI. Focus is to deal with the image storage and return to the image storage address, no more nonsense, directly on the code:

/** * Created by Administrator on 2019/9/6. */ @restController public class UploadImageController { private static Logger logger = LoggerFactory.getLogger(UploadImageController.class); / upload pictures interface address * * * * @ param multipartHttpServletRequest * @ return * / @ PostMapping (value = "/ uploadImage") public Object UploadImage (MultipartHttpServletRequest MultipartHttpServletRequest) {/ / photo storage path String path = "src/main/resources/static"; // return value HashMap map = new HashMap(); List<String> data = new ArrayList<>(); / / request all the file names in the Iterator < String > Iterator. = multipartHttpServletRequest getFileNames (); While (iterator.hasnext ()) {// Get the file MultipartFile MultipartFile = multipartHttpServletRequest.getFile(iterator.next()); if (multipartFile ! = null) {/ / file name String fileName = multipartFile. GetOriginalFilename (); String extName = fileutil. getExtName(fileName); If (stringutils.isempty (extName)) {logger.error(" file suffix isEmpty, file may be wrong..." ); map.put("errno", 1); map.put("data", data); return map; } // File fileDir = new File(path); if (! fileDir.exists()){ fileDir.mkdirs(); } File file = new File(fileDir, fileName); / / file copy file stream to the upper FileUtil copyInputStreamToFile (multipartFile, file); / / build images accessible address String webUrl = multipartHttpServletRequest. GetScheme () + ": / /" + multipartHttpServletRequest.getServerName() + ":" + multipartHttpServletRequest.getServerPort() + multipartHttpServletRequest.getContextPath(); String imageUrl = file.getPath().substring(path.length()).replaceAll("\\\\", "/"); Logger. info(" file path: {}", webUrl + imageUrl); // Add (webUrl + imageUrl); }} // Return the format required by the front end, map.put("errno", 0); map.put("data", data); return map; }}Copy the code

The above code provides an interface address to upload the image, which will be stored in the static directory under the project’s classpath. The format of the returned value needs to be the same as that required by WangEditor.

At the same time, the front-end rich text editor component also needs to configure the interface address of uploading pictures, as follows:

conclusion

At this point, the chat is over. Finally, I will sort out the overall logic.

The best place to start when you encounter new requirements and unfamiliar components is with the official documentation, from which you can see a lot. For example, how to start steps, provided functions, design ideas, etc., and then need to combine their own needs to make trade-offs and adjustments, for some harsh requirements can be indirectly realized with the provided functions.

Then it provides the design idea and code implementation of WangEditor rich text editor front-end based on Vue framework, and then simply explains the advantages and disadvantages of two ways to upload pictures.

Finally, Java and Spring Boot were used to complete the image uploading interface of the back end, and then a simple case was solved by modifying the configuration of the front end.

Note: The code address is as follows

Back-end code address URL: gitee.com/hotstrip/up…

Front-end code address URL: gitee.com/hotstrip/Wa…