5
头图

background

With the OpenHarmony component development competition, our team members were informed that they had won the second prize. While they were happy, they also wanted to write down our valuable development experience during this period to share with you. When we saw the notification of the competition It's already mid-September, and it's time for the work to be submitted. After referring to some other works, we found that Canvas , so we plan to write one based on Canvas and common components. Components, because we have not developed OpenHarmony application before, our team members have no relevant experience, everyone is exploring from scratch, we first IDE and cooperate, some members are responsible for downloading 061db7d4a0dbd2 and debugging equipment, and some members are responsible for research and read the official documentation. First attach the source code, sharing and summarizing is not easy, please like and follow ⭐️:

https://github.com/Wscats/openharmony-sheet

configure

After reading the official documents, our members made the following environment configurations on their local computers and devices:

  1. Download and install DevEco Studio 2.1 Release and above
  2. Get the OpenHarmony SDK package and unzip it
  3. config OpenHarmony SDK

In DevEco main interface, click on the toolbar File > Settings > Appearance & Behavior > System Settings > HarmonyOS SDK interface, click HarmonyOS SDK Location load SDK :

Then click Next and Finish complete the environment configuration.

  1. Install additional packages, enter the OpenHarmony-SDK-2.0-Canary/js/2.2.0.0/build-tools/ace-loader directory, then run the command line tool in this directory, and execute the following commands respectively until the installation is complete
npm cache clean -f
npm install
  1. Download the OpenHarmonyJSDemos project project and import the project into DevEco Studio
  2. Apply and configure the certificate. Note that the certificates of OpenHarmony and HarmonyOS are not common, so additional application is required
  3. Compile and build, generate a HAP application installation package, generate a HAP application installation package, and install it on the OpenHarmony development board
  4. After installation and running, click the application icon on the screen of the development board to open the application, you can view the running effect of the application example on the device, and perform related debugging
  5. In addition to using real machine debugging, we can also use remote debugging and local Previewer debugging, although it is very convenient, but the actual performance is definitely slightly different from the real machine

foreword

Before realizing the Canvas , we had some discussions and discussions. First of all, we hoped that we could use this development to improve our OpenHarmony and facilitate subsequent business support. Secondly, our team members also hope to get better rankings and rewards. We It is noted that the score of the competition is scored by the judges, and the full score is 100 points. Here, the score will be based on the four dimensions of creativity, practicality, user experience, and code specification. Canvas will be more difficult to implement first than ordinary applications. Canvas to debug, we have little advantage in creativity and practicality, because most of the 061db7d4a0df72 applications that most front-end developers come into contact with are game-related, so this road is destined to be relatively difficult, and the user experience is also A big difficulty, our real machine test found that Canvas is not very good, much worse than the experience of some native components, I have confidence in the code quality of team members, but the code specification has the least proportion of scores. So when we set up the project, we had a big difference.

Selection dimensioninstructionScore
creativeThe degree of innovation of the work30%
practicalityThe degree of practical application of the work in the application scenario30%
user experienceUser experience value, users can easily use components and get a good sense of experience25%
code specificationCode quality, aesthetics, compliance with specifications15%

plan

Because of the above general doubts, we first formulated three plans and one goal:

The rendering engine is our ultimate goal. Although the difficulty is too high, our team members decided to achieve this goal in three steps. First, at least learn to use basic components and container components, then learn to use canvas components, and finally integrate these experiences to achieve a rendering engine.

First Experience

We first implemented a general gallery component as a hands-on project, which mainly uses four basic components and container components:

We place a button to trigger showGallery method to control panel display popups and hidden, where div and button label is hml built-in components, we usually write with html very similar, it supports most of our general properties such as id , class and type etc., are convenient for us to set the basic identification of the component and display the appearance features.

<div class="btn-div">
  <button type="capsule" value="Click Here" onclick="showGallery"></button>
</div>

Then we place a changeable gallery content display window in the panel mode and src variables, so that the gallery component can display different forms according to the mode, and display different shapes according to the incoming image address. Picture content, the syntax here is very similar to the Vue Mustache syntax can be used to control the attribute value.

<panel
  id="gallery"
  class="gallery"
  type="foldable"
  mode="{{modeFlag}}}"
  onsizechange="changeMode"
>
  <div class="panel-div" onclick="closeGallery">
    <image class="panel-image" onclick="closeGallery" src="{{galleryUrl}}}"></image>
    <button
      class="panel-circle"
      onclick="closeGallery"
      type="circle"
      icon="/common/images/close.svg"
    ></button>
  </div>
</panel>

After implementing the view and layout, we can add the logic of the gallery component in index.js ES6 syntax, we can write very comfortable and efficient. The data here is the data model of the gallery component, and the type can be Object or function, if the type is a function, the return value must be an object. Note that the attribute name cannot start with $ or _ , and do not use reserved words. We set default values modeFlag and galleryUrl

export default {
  data: {
    modeFlag: "full",
    galleryUrl:
      "https://pic1.zhimg.com/v2-3be05963f5f3753a8cb75b6692154d4a_1440w.jpg?source=172ae18b",
  },
};

The display and hiding logic is relatively simple, you only need to get panel , and then trigger the show or hide method. Of course, in addition to this method, we can also use the rendering attribute to achieve:

  • for Expand the current element according to the set data list
  • if Add or remove the current element according to the set boolean
  • show According to the set boolean , show or hide the current element
showGallery(e) {
    this.$element('gallery').show()
},
closeGallery(e) {
    if(e.target.type==='image') return
    this.$element('gallery').close()
},

index.css in the same level directory, which can make our gallery show better effects. The animation style also supports dynamic rotation, translation, zoom and gradient effects, which can be set in style or css .

.panel-div {
  width: 100%;
  height: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

The overall effect is shown in the figure below. The effect is simple and rude. After writing this DEMO , our team members have the most basic understanding of the application of the basic components OpenHarmony



Advanced

Although we have mastered the use of the most basic components above, we still haven't used the Canvas canvas component, so we continued to read the official documentation and found that OpenHarmony provides a complete canvas interface:

We used the classic FlappyBird game as our first attempt at the canvas component.

collect material

First of all, let's prepare the pictures and animation materials of the game:

material
background
bird
ground
water pipe

Then we prepare the canvas, set the height and width, and listen to the canvas press method ontouchend .

<div class="container">
  <canvas ref="canvas" style="width: 280px; height: 512px;" ontouchend="moveUp"></canvas>
</div>

Data initialization

After preparing the canvas, we need to initialize the initial data of the game. The core mainly involves several:

elcanvas element
gapPipe spacing
scoreScore
bXBird X-axis coordinate
bYBird Y-axis coordinate
gravityGravity Index
pipepipeline data
birdHeightbird height
birdWidthbird width
pipeNorthHeightUpper side pipe height
pipeNorthWidthLower pipe height
cvsHeightcanvas height
cvsWidthcanvas width
fgHeightground height
fgWidthground width

Before implementing this game, we not only need to master the basic components, but also need to understand part of the life cycle. OpenHarmony has two life cycles, namely the application life cycle and the page life cycle. We use the life cycle onShow first time here, which is Triggered when the page is opened, and the application is in the foreground, we need it to help us initialize some key data at the beginning, get the nodes of the canvas, save the context scope of the canvas ctx , clear the pipeline data and trigger the game frame drawing.

onShow() {
    this.el = this.$refs.canvas;
    this.ctx = this.el.getContext('2d');
    this.pipe[0] = {
        x: this.cvsWidth,
        y: 0,
    };
    requestAnimationFrame(this.draw);
},

The this.draw method here is the core logic of the whole game, involving the bird's flight animation, motion trajectory, boundary processing and score calculation.

First we draw the background of the game from the top left corner of the canvas at X and Y

const ctx = this.ctx;
ctx.drawImage(this.bg, 0, 0);

Then we draw the pipes that appear in the sky and the ground during the flight of the bird. Here we need to calculate the position of the pipe in the sky. The position of the upper pipe needs to be calculated from the preset distance between the two pipes and the height of the lower pipe. When the position is calculated After that, you only need to cooperate with the timer or requestAnimationFrame to update the position of the pipe and the bird in real time, so that the user can perceive the effect of the dynamic picture of the game. Here I use requestAnimationFrame request animation frames. The experience will be better, but it only supports API Version 6 You do not need to import, so readers need to pay attention to SDK is a relatively new version.

for (let i = 0; i < this.pipe.length; i++) {
  this.constant = this.pipeNorthHeight + this.gap;
  ctx.drawImage(this.pipeNorth, this.pipe[i].x, this.pipe[i].y);
  ctx.drawImage(this.pipeSouth, this.pipe[i].x, this.pipe[i].y + this.constant);
  this.pipe[i].x--;
}

Impact checking

Here we use a conditional judgment to do boundary processing, that is, collision detection, that is, if the bird touches the ground, the pipeline in the sky or the pipeline on the ground will stop all animations, that is, the game is over, and if the game is over, the results will be settled. And use the OpenHarmony remind players if they need to restart a new game.

if (
  (this.bX + this.birdWidth >= this.pipe[i].x &&
    this.bX <= this.pipe[i].x + this.pipeNorthWidth &&
    (this.bY <= this.pipe[i].y + this.pipeNorthHeight ||
      this.bY + this.birdHeight >= this.pipe[i].y + this.constant)) ||
  this.bY + this.birdHeight >= this.cvsHeight - this.fgHeight
) {
  prompt.showDialog({
    buttons: [{ text: "重来一次" }],
    success: (data) => this.restart(),
  });
  clearInterval(this.interval);
}

When the boundary is processed, we also need to deal with the fact that when the bird keeps flying, new pipelines must be created, and the old pipelines are recycled to calculate the score. This logic is also quite simple, and it is essentially a kind of collision detection. When the pipeline position X axis on the left side of the screen 5 , that is, the bird has passed safely, and the score is successful. When the latest pipe is changed to X axis is 125 , that is, the next pipe the bird will fly, then Create the next new pipeline in advance. If the bird’s flying distance is relatively long, we also need to consider optimizing the pipeline array. We can’t let the array grow indefinitely. We can also optimize, so when the old pipeline has completely disappeared from the picture , we can consider deleting the old pipe data from the array.

if (this.pipe[i].x == 125) {
  this.pipe.push({
    x: this.cvsWidth,
    y: Math.floor(Math.random() * this.pipeNorthHeight) - this.pipeNorthHeight,
  });
}
if (this.pipe[i].x == 5) {
  this.score++;
}

All of the above logic is essentially the animation of the drawing pipeline. We can easily draw the flight trajectory of the bird by combining the offset and gravity factors. We also draw the score to the lower left corner of the screen by the way, so that it can be real-time. Display the player's score.

ctx.drawImage(this.fg, 0, this.cvsHeight - this.fgHeight);
ctx.drawImage(this.bird, this.bX, this.bY);
this.bY += this.gravity;
ctx.fillStyle = "#000";
ctx.font = "20px Verdana";
ctx.fillText("Score : " + this.score, 10, this.cvsHeight - 20);

Action and Scoring

And our players only need one operation to participate in the whole game, that is to click on the screen with a finger, try to let the bird fly safely between the pipes, so we need to monitor the click event of the screen, which is essentially the click event of the canvas, when the user clicks time, we let the bird move a little distance up.

moveUp() {
    this.bY -= 25;
},

The logic of resetting the game is very similar to the initialization, as long as the player's score, the position of the bird and the data of the pipeline are all restored to the default state:

restart() {
    this.pipe = [];
    this.pipe[0] = {
        x: this.cvsWidth,
        y: 0,
    };
    this.constant = 0;
    this.score = 0;
    this.bY = 150;
},

Package components


Since the competition requires us to implement a general component, in case 2, we hope to go further and try to encapsulate this game into a general component. Check the official documentation and find that it is very simple to implement. The details are in Custom component , The so-called custom component is a new component that the user combines and encapsulates the existing components according to the business needs, which can be called multiple times in the project, thereby improving the readability of the code. To sum up, we only need to use the <element> component to introduce the component we just implemented into the host page.

<element name="Flappy" src="./flappy//pages//index/index.hml"></element>
<div class="container">
  <Flappy></Flappy>
</div>

ultimate challenge

With the accumulation of the previous two cases, our team has OpenHarmony , and we are about to enter the final exciting challenge. We need to completely transplant a Canvas engine. At the beginning, we considered implementing a game However, considering that the remaining time of the game is not enough, and the practicality and creativity of the game engine are not conducive to display, after comprehensive consideration by our team, we finally decided to implement a document table rendering engine.

输入图片说明

think

Some people may ask why they choose to transplant a document rendering engine. Here I remember that there was a similar discussion on the how long will it take China to develop an alternative software similar to Excel, and its functions cover 95% of the functions of Excel? , this road is very rough and difficult, please quote the answers of some big Vs with the highest praise:

  • Microsoft Wheel Brother: There are so many things that can't be done, and it will take several years to write the requirements document well.
    Microsoft's Belleve: Programmers can try to implement recalc first (update the cell value according to the formula), and then you will know the difficulty. As the most complex C++ project in China, the document project is by no means a vain name.
  • Microsoft's monster brother: As an engineer of Excel, my brother seriously answered one, no, because our group next door has already tried it, and it has covered about 40% in two years.
  • IBM's Caspar Cui: If you are developing common Excel functions, WPS is already a good alternative. And Microsoft and Kingsoft also have cross-licensing. But Excel, which says it's 95% functional, has already done that. . . Still a bit underestimated by Excel. As far as the amount of help documentation is concerned, WPS has to work harder.
  • University of Science and Technology of China: If Microsoft is brainstorming and loses the Excel source code, it cannot be recovered. That's the end of the world, and it's all over together. Even if Microsoft brought back the original team of Excel team, resigned from resignation, revived premature death, and then re-developed an Excel. There is no way he can guarantee that the functions of Excel will be restored to 95%, and that 95% of the Excel files will be opened normally.
  • Bbcallen : Impossible, Microsoft can't do it themselves.

No matter what anyone says, we must take this road. Just like the meaning behind the birth of Hongmeng, we choose to meet this challenge. Every hurdle and pit in it is worth leaving a Chinese footprint.

From the perspective of technology and goals, what we should achieve is not a local personal document that has solidified the market and user habits, but an online collaborative document. Local documents only need to consider individuals, not multi-person collaboration scenarios, only need to consider Offline, do not need to consider online scenarios, only need to consider client scenarios, do not need to consider server scenarios, etc...

The host environment of online documents is the browser, and the local document is behind the system. There is no support for any online document in China based on Google Chrome, and there is no support for Microsoft Office based on Microsoft Windows system. In fact, based on all this, we should also 95% that it is difficult to do 061db7d4a0ed10. You must know that Google has invested thousands of people and tens of billions of people for more than ten years to develop the browser, Windows system. We may not have such a technical background in China, but we are still trying to narrow the gap and catch up.

Implementation plan

Before talk about implementation, let's talk about how complex form rendering , table rendering in general, there are two implementations:

  • DOM rendering.
  • Canvas rendering.

The well-known handsontable open source library in the DOM for rendering. The same rendering results require DOM node, but it is obvious that DOM rendering with 100,000 or one million cells will cause major performance problems. So, now many online forms implementations are based on Canvas and superimposed DOM to achieve, but the use of Canvas realize the need to consider the visible area, the scroll operation, canvas hierarchy, there Canvas some performance issues facing their own, including Canvas how straight out etc., the requirements for development are higher, but for better user experience, the implementation scheme of Canvas

Since most of the front-end project rendering layers are rendered layer by layer according to the layout model tree structure, the entire rendering tree corresponds to the layout model tree one by one. Therefore, the number of nodes in the entire rendering is also very large. When the project is larger, performance suffers more.

[External link image transfer failed, the source site may have an anti-leech mechanism, it is recommended to save the image and upload it directly (img-ACtSdVX6-1637535201140) ( https://p3-juejin.byteimg.com/tos-cn-i- k3u1fbpfcp/9d7f39b369da4fca9abbd5827be03b17~tplv-k3u1fbpfcp-zoom-1.image "screenshot.png")]

In order to improve the rendering performance and provide a better editing experience DOM replaced by Canvas , which is convenient for developers to build large-scale online document projects. companies that implement similar engines at home and abroad, such as: Tencent Documents, Jinshan Docs and Google Docs etc.

top floor
DOMContainer plugin input box, etc.
CanvasHighlight selection, etc.
CanvasContent font background color, etc.
bottom layer

We view collection element, and then rendered by category manner, reducing Canvas number of switching graphics engine state machine, reduce performance losses optimize the rendering time consuming, the entire core engine control codes 1500 around line, the other supplementary demo code 500 line , which is convenient for everyone to understand and read and carry out secondary development.

The engine ported here mainly refers to a commercial project and an open source project:

Canvas initialization

We construct a table class, create a canvas during initialization, set the height and width, and put it into DOM , and mount the commonly used properties to the prototype chain and expose it to the global window variable.

class Table {
  constructor(container, width, height) {
    const target = document.createElement("canvas");
    document.querySelector(container).appendChild(target);
    this.$target = target;
    this.$draw = Canvas2d.create(target);
    this.$width = width;
    this.$height = height;
  }
}

<div id="table"></div> on the page, and instantiate the canvas directly in the global environment. id attribute, you can use the id obtain the component object and call the relevant component method.

const table = new Table("#table", 800, 500);
upper left areacol columncol column
row rowcell cellcell cell
row rowcell cellcell cell

Coordinate system establishment

With the canvas, we will start preparing for rendering. We encapsulate the render method in the table render method mainly draws four areas, which is similar to the mathematical Cartesian Cartesian coordinate system The four imaginations involve grid line segments, grids information, column headers (columns AZ), row headers, and freeze areas.

2 - Top left area1 - Top right area
3 - Lower left area4 - Bottom right area

These area are initialized area.js of Area

  • Areas 2 to 1 are the headers of the AZ column
  • Areas 2 to 3 are the line headers
  • 4 Areas are most commonly used and are editable cells
renderBody.call(this, draw, area4);
renderRowHeader.call(this, draw, iarea3);
renderColHeader.call(this, draw, iarea1);
renderFreezeLines.call(this, draw, area4.x, area4.y);

Most of the core ideas of these four areas are essentially drawing grids, all of which use the renderLinesAndCells method, which has methods for drawing the lines and grid information of the renderCells will traverse the area and trigger renderCell draw each For individual cells, some special cells are also processed here, such as merged cells and selected cells, while renderLines will traverse each row and column to draw the interval lines of all rows and columns.

function renderLinesAndCells() {
  renderLines(draw, area, lineStyle);
  renderCells(draw, type, area, cell, cellStyle, selection, selectionStyle, merges);
}

cell rendering

After drawing the cells of the table, you need to render the data and format to each cell. Here, cell method is mounted Table prototype chain, which accepts a callback function and saves it to the static property $cell . When renderCell function is triggered, this method is called and the row and column numbers are passed into the $cell method to obtain cell information.

Table.prototype["cell"] = function (callback) {
  this[`$$cell`] = callback;
  return this;
};
const sheet = [
  ["1", "1", "1"],
  ["1", "0", "1"],
  ["1", "1", "1"],
];
table.cell((ri, ci) => sheet?.[ri]?.[ci] || "").render();

<img width="250" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6d88f654f3b04af1a1b7fdb54eb89472~tplv-k3u1fbpfcp-zoom-1.image" />

So we can $cell method. Of course, you can only pass in plain text here, and you can also pass in complex data structures to decorate cells. Here style will have the default The value is from $cellStyle .

bgcolor#ffffff
alignleft
valignmiddle
textwraptrue
underlinefalse
color#0a0a0a
boldfalse
italicfalse
rotate0
fontSize9
fontNameSource Sans Pro

These styles are essentially using Canvas interface provided draw.attr() to show.

const c = cell(ri, ci);
let text = c.text || "";
let style = c.style;
cellRender(draw, text, cellRect, style);

With the most basic method above, we already have the function of displaying table data. At this time, we can expose richer interfaces to third parties, such as commonly used merged cells. We call the merges method to inform the table class, and we are in the X axis G9 The cells in the range from H11 to Y axis B9 to D11

Table.create("#table", 800, 500).merges(["G9:H11", "B9:D11"]);

At this time, renderCells will do special processing to the grid in this area and render it into the state of merged cells.

eachRanges(merges, (it) => {
  if (it.intersects(area)) {
    renderCell(draw, it.startRow, it.startCol, cell, area.rect(it), cellStyle);
  }
});

Data can be edited

In addition to cell merging, the event processing of the canvas is also commonly used, because all the methods just now only view the state of the table, and the table will also be edited by the user, so we have to listen to the events of the user's click and input, so we render the table When binding click , mousedown , mousemove and mouseup events, etc., we can monitor the user's click behavior and Z DOM element, and provide the user with the function of inputting and modifying the cell. .

bind($target, "click", (evt) => {});
bind($target, "mousedown", (evt) => {});

So DOM node in addition to our place <canvas> elements can also be arranged on <textarea> elements, where we can notice that inline styles have areaTop and areaLeft to control our input box specific location, this location is also very easy to get, we just need to Get the click event objects evt.offsetX and evt.offsetY , and then calculate whether it is in the four quadrant areas according to the position of the coordinates and return the row and column information. Combined with the information of the areaTop and areaLeft input box can be accurately calculated, and then let The input box is switched to the displayable state, and the user can see the input box on the corresponding cell of the table.

<div
  if="{{isShowArea}}"
  style="width: 100px; height: 25px; top: {{areaTop}}px; left: {{areaLeft}}px"
>
  <textarea
    if="{{isShowArea}}"
    focus="{{isFocus}}"
    value="{{content}}"
    selectchange="change"
    onchange="change"
  ></textarea>
</div>

With the input box, we can monitor the user's input operation. We bind the input event to the textarea component. When the component reaches the event trigger condition, the corresponding event callback function in JS UI view and page JS logic Layer interaction, the event callback function can carry additional information through parameters, such as the data object dataset event-specific callback parameters on the component, when the component triggers the event, the event callback function will receive an event object by default, through the event object Corresponding information can be obtained. We get the value entered by the user through the event object, and call the cell method to re-update the value of the corresponding cell in the table. Of course, the actual situation is sometimes complicated. For example, the user modifies the color of the cell text, so here The data format will be determined.

textarea.addEventListener("input", (e) => {
  let input = e.target.value;
  table.cell((ri, ci) => {
    if (ri === row && ci === col) {
      return (window.data[ri][ci] =
        typeof value === "string" || typeof value === "number"
          ? input
          : { ...value, text: input });
    }
    return window.data[ri][ci];
  });
});

The following picture is the actual measurement effect of our real machine. You can see that we have introduced the built-in library @system.prompt . Click the corresponding cell pop-up window to display the corresponding row and column information, which is convenient for us to develop and debug. We use the built-in input method of the mobile phone to input the content to test, input The box will accurately obtain the information and update it to the table, but the IDE built in Previewer is invalid. The guess is that the input event of the keyboard on the PC

Toolbar implementation

With the most basic functions of viewing and editing tables, we can consider implementing the toolbar in the next step. The implementation of the toolbar generally provides settings such as setting row and column height, text bolding, centering, italics, underline and background color. In fact, the above cell style method cooperates with the row and column position or range information to repackage various interface implementations.

We introduce a few commonly used ones here. colHeader can set your list row header and its height. If you do not set a value for it, it will also have a default height.

table.colHeader({ height: 50, rows: 2 }).render();

In some cases, when we look up the table, we may need to fix the cells of some rows and some columns to improve the readability of the table. At this time, .freeze can come in handy. The following settings will help you freeze the C6 within 061db7d4a0fa79. List.

table.freeze("C6").render();

scrollRows generally used with the frozen area, so that the selection outside the frozen area can be scrolled.

table.scrollRows(2).scrollCols(1).render();

We can use the following method to update the data in the second row and second column of the cell to be 8848 and the color to be red:

table
  .cell((ri, ci) => {
    if (ri === 2 && ci === 2) {
      return {
        text: "8848",
        style: {
          color: "red",
        },
      };
    }
    return this.sheet?.[ri]?.[ci] || "";
  })
  .render();

Since there are too many forms of cells that can be set, we will not expand them here. For details, you can refer to the following interfaces, which support a variety of rich and diverse changes. It can be seen that it is actually very similar to CSS

{
  cell: {
    text,
    style: {
      border, fontSize, fontName,
      bold, italic, color, bgcolor,
      align, valign, underline, strike,
      rotate, textwrap, padding,
    },
    type: text | button | link | checkbox | radio | list | progress | image | imageButton | date,
  }
}

We have made some demonstrations of the common interfaces above, run OpenHarmonySheet , long-press any cell to pop up the dialog box and click the corresponding option to view the running results of common interfaces. This demonstration is for reference only, more practical use Please refer to the documentation for the scenario:




Lifecycles and Events

After completing the above functions, we need to consider exposing the life cycle and events and encapsulate them into a common component for the access party to use.

  • @sheet-show table display
  • @sheet-hide table hidden
  • @click-cell-start before cell click
  • @click-cell-end cell 061db7d4a0fd0e is clicked
  • @click-cell-longpress long press the table
  • @change Modify cell data

Because OpenHarmony provides a series of lifecycle callback methods for custom components, it is convenient for developers to manage the internal logic of custom components. The life cycle mainly includes: onInit , onAttached , onDetached , onLayoutReady , onDestroy , onPageShow and onPageHide . Our form component can use the timing of each lifecycle callback to expose its own lifecycle.

this.$emit("eventName", data);

Here, the name attribute refers to the custom component name. The component name is not case-sensitive, and lowercase is used by default. src attribute refers to the file path of the hml name attribute is hml file name is used as the component name by default. Binding components and custom events using subassembly onXXX or @XXX syntax subassembly by this.$emit and traditional values triggering event parameter passed upwardly through custom event bindings, parent component performs bindParentVmMethod method of transmitting and receiving subassembly parameter.

<element name="Sheet" src="../../components/index.hml"></element>
<Sheet
  sheet="{{sheet}}"
  @sheet-show="sheetShow"
  @sheet-hide="sheetHide"
  @click-cell-start="clickCellStart"
  @click-cell-end="clickCellEnd"
  @click-cell-longpress="clickCellLongpress"
  @change="change"
></Sheet>

We packaged all the above, and improved the introduction documents and access documents and uploaded them to Gitee - [OpenHarmonySheet
]( https://github.com/Wscats/sheet) In the warehouse, our table engine component is completed.

Looking back on the whole process, although it was difficult and challenging, our team still managed to solve it. During the entire competition, our team also learned a lot about Hongmeng. We never had the opportunity to learn about it before. We took the opportunity of this competition. I can re-understand Hongmeng, and I have also met some like-minded developers. Let’s make a summary for the time being. Before participating in the competition, you must find a certain direction. It is best to be familiar with this field and not overlap with other entries. In this way Be responsible for your own work, be friendly to other people's works, and respect the competition. After you have grasped the direction, you must formulate every small plan and final goal, and make specific plans for the early, middle and late stages, and you can't step over the ground. It is too big to be too ambitious. We must complete every small plan down-to-earth. This process is a win-win for the team and ourselves. Although we may not reach the end, looking back at each of our footprints is a reward for our own efforts. The team Members must unite, complete each task in a targeted manner, be conscientious and responsible, help each other, and make progress together. Just like what Hongmeng has experienced, a complete system requires millions of developers to work together to build and polish. I hope There can be more and more good OpenHarmony open source projects, and we can build our own ecology together without accumulating small steps.

Finally, I sincerely hope that 061db7d4a0ff2d can develop more and more powerfully and smoothly. Although this road is difficult, it is worth it. There will be long winds and waves, and OpenHarmony


wscats
7.1k 声望13k 粉丝

分享和总结不易,求关注一下⭐️