Recently, Xiaobian has been working with KKB to adapt ele. me’s Element UI library to the VUE3 environment. After all, VUe3 is about to come out, and XIAobi has been studying composition API about VUe3 recently and would like to take this opportunity to try it out. By the way, try VTU, the official vUE testing framework.

In this article, you can learn about the new development model of the Composition API, the problems encountered during the development process, the problems of component packaging, how to better package the component library, and how to read the source code of the component library.

Cloning of warehouse

Analysis of the catalog

Mode LastWriteTime Length Name -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - d 2020/8/22 17:07 build storing build script, D ----- 2020/8/15 22:46 examples of elementUI official website d----- 2020/8/15 22:46 packages for storing all components d----- D ----- 2020/8/15 22:46 test d----- 2020/8/15 22:46 types D.ts files...Copy the code

Analyzing script Commands

"scripts": {"bootstrap": "npm i"."build:file": "node build/bin/iconInit.js & node build/bin/build-entry.js & node build/bin/i18n.js & node build/bin/version.js"."build:theme": "node build/bin/gen-cssfile && gulp build --gulpfile packages/theme-chalk/gulpfile.js && cp-cli packages/theme-chalk/lib  lib/theme-chalk"."build:utils": "cross-env BABEL_ENV=utils babel src --out-dir lib --ignore src/index.js"."build:umd": "node build/bin/build-locale.js"."clean": "rimraf lib && rimraf packages/*/lib && rimraf test/**/coverage"."deploy:build": "npm run build:file && cross-env NODE_ENV=production webpack --config build/webpack.demo.js && echo element.eleme.io>>examples/element-ui/CNAME"."deploy:extension": "cross-env NODE_ENV=production webpack --config build/webpack.extension.js"."dev:extension": "rimraf examples/extension/dist && cross-env NODE_ENV=development webpack --watch --config build/webpack.extension.js"."dev": "npm run build:file && cross-env NODE_ENV=development webpack-dev-server --config build/webpack.demo.js & node build/bin/template.js"."dev:play": "npm run build:file && cross-env NODE_ENV=development PLAY_ENV=true webpack-dev-server --config build/webpack.demo.js"."dist": "npm run clean && npm run build:file && npm run lint && webpack --config build/webpack.conf.js && webpack --config build/webpack.common.js && webpack --config build/webpack.component.js && npm run build:utils && npm run build:umd && npm run build:theme"."i18n": "node build/bin/i18n.js"."lint": "eslint example/**/* src/**/* test/**/* packages/**/* build/**/* --quiet --fix"."pub": "npm run bootstrap && sh build/git-release.sh && sh build/release.sh && node build/bin/gen-indices.js && sh build/deploy-faas.sh"."test": "npm run lint && npm run build:theme && cross-env CI_ENV=/dev/ BABEL_ENV=test karma start test/unit/karma.conf.js --single-run"."test:watch": "npm run build:theme && cross-env BABEL_ENV=test karma start test/unit/karma.conf.js"."test:unit": "jest"
}
Copy the code

It’s too messy up here, so let me explain the following, and I’ll just write the commands THAT I used

  • Bootstrap installs dependencies
  • Build :file Automatically builds globally-imported JS filessrc/index.jsThere is a small hole where you can view the modified document
  • Build :theme build:theme, this should be executed after editing SCSS command, temporary modification has not been used, CSS pathpackages/theme-chalk
  • Build: UMD builds browser-only components
  • Clean Indicates the packaged file
  • Dev turns on development mode, and after startup you can open the native elementUI instance official website in your browser
  • Dev :play opens the development mode of a component. This is also my common command. Here you can develop a component separatelyexamples/play/index.vue
  • Dist Executes all build commands
  • Test: Unit Performs unit tests

requirements

  • Develop using the Composition API
  • Write unit test files/packages/*/__tests__/*.spec.js

To prepare

  • The node of the latest version
  • npm/yarn
  • Know vue3’s Composition API

start

First install dependencies using YARN or NPM I.

Then run yarn dev:play to run the examples/play/index.vue demo

Write an example in this demo, you can directly paste the first instance of the official real example Radio

<template>
  <el-radio v-model="radio" label="1">Alternatives to the</el-radio>
  <el-radio v-model="radio" label="2">Alternatives to the</el-radio>
</template>

<script>
  export default {
    data () {
      return {
        radio: '1'}; }}</script>
Copy the code

Then create packages/radio/radio. Vue file, modify the packages/radio/index, js component in the path of development analysis of the old file code, old files in the packages/radio/SRC/radio. The vue

When I opened this file, I was a little confused. In fact, I mostly changed the JS part of the code, but I still encountered the following problems:

  • What is tabIndex?

  • What are role and aria-* in the tag?

  • Vue3’s two-way data binding is different from VUe2’s?

  • What’s an Emitter library for?

    .

And so on a lot of problems, so the first step is to supplement their own knowledge blind spot

TabIndex is an attribute that controls tabIndex positioning. If it is -1, tabIndex cannot be located. If it is >=0, tabIndex is allowed to be located.

Role roughly means giving a name to this type of tag, and ARIA -* is the accessibility related attribute.

These two problems are knowledge blind spots encountered before writing the component. The next step is the pit step, because vuE3 is used, although most of the features of VUE2 are officially retained, some details are still different.

Vue2 uses the value props to receive the value of a bidirectional binding variable. If the variable changing the binding is passing the change and the value to the parent element via an input event, then assigning the value to the bound variable. Vue3 uses the update:modelValue function to change the values of the variables to be bound, and vue2 uses the update:modelValue function to change the values of the variables to be bound.

vue2
<template>
	<input :value="value" @input="$emit('input', $event)" />
</template>
<script>
export default{
	props: {value:String,}}</script>

vue3
<template>
	<input :value="modelValue" @input="$emit('update:modelValue', $event)" />
</template>
<script>
export default{
	props: {modelValue:String,}}</script>
Copy the code

This is the difference between vue2 and vue3 bidirectional binding, but when you write this, you will notice that a WARN is reported in the console after running. After a brief translation, you will find that vue3 has a new option emits. Functions are similar to props, which declare properties to be passed, and emits, which declare events to be emitted. Props and emits are also used as living documents. For more information about emis and props, see the vue3 website at v3.vuejs.org

<template>
	<input :value="modelValue" @input="$emit('update:modelValue', $event)" />
</template>
<script>
export default{
	props: {modelValue:String,},emits: ['update:modelValue'],}</script>
Copy the code

We added emits and refreshed the page to see that console successfully eliminated a WARN.

Another big change in vue3 is that vue3 does not have three functions: on, on, on, off, and $once.

transform

The approach I used was to go from easy to hard, starting with basic checkbox functionality without changing the template. We then look at the original code step by step to add functionality, and finally wrap functionality as a function of useXXX to expose events and states. To see the effect while writing, you can run the examples/play/index.vue file by executing yarn dev:play to see the effect.

test

Because of this project, I used the knowledge of testing for the first time. Although I had known it before, I just knew it

In this project the real first use, also learned VTU this VUE testing framework

In fact, testing is very easy, you can look at the demo written before and see their style

But when writing a test script, do you want to test from a user’s point of view, or do you want to test from a user’s point of view

Then run the test file. After you PASS, you can change the document

To change the document

I’m just modifying the schedule and the demo code on the website, and there’s one pit, no, there’s several pits

The first is if you can’t use the component directly when testing with the dev:play command

There is no component in the SRC /index.js file. Your component is generated by build:file

The js script that generates this file is build/bin/build-entry.js, which is about 72 lines of code

You need to add the name of the component you wrote to that array and then execute YARN Build :file or NPM run build:file

You can then use it directly, although you can also import tests directly, but this is ultimately not to solve the problem here, but to use global imports in the demo

And if you don’t do that you’re not going to show up in the demo

Speaking of demo, there is also a pit where you will find that the site does not render after executing the dev command, and you have solved the above problem

But it still doesn’t show up, and there’s a very magic trick here, which is that you need to remove the template tag from the sample in the MD file to show up, which is very magic

After you remove the template tag, you can display it, then modify the details document, and finally commit it

submit

It took me about two days to write the radio component

However, there is another pit in the commit, because the test command is automatically triggered before the commit, and if the test fails, the commit will not be able

Since this project is not a zero-based project, he will still run the legacy test files, but some components have not been changed

If the test fails, the commit cannot be verified. If the test fails, the commit cannot be verified. If the test fails, the commit cannot be verified

Also note that the specification for the submitted text is the component name: everything is done in English

Finally the submission is successful, and then the PR

I used to think PR was carried out in the warehouse of the other party, but later I found it was not

PR needs to be carried out in your warehouse Fork, and then successful PR, waiting for the big guy review

After waiting for two days, I successfully passed the PR. I was also very excited, because this was my first PR

conclusion

First of all, large projects must comply with some specifications, after all, the code is to be read by many people

And the test file is also very important, you write the test file is like your safety wall, in the first time after a big problem reported wrong