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 files
src/index.js
There 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 path
packages/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 separately
examples/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