Abstract: UE2.0 mobile terminal

Recently, I have been using Vue2.0 to do front-end development related to wechat public account. After this development practice, I am sorting out relevant practical plug-ins used in the project and related problems encountered. I hope to communicate with you……

  • cssrem: a CSS value to REM VSCode plug-in;

  • lib-flexible: flexible layout adaptation solution for mobile terminal;

  • vue-touch: mobile terminal related click, slide, drag, multi-touch and other events encapsulation;

  • vee-validate: Suitable for vUE project form validation plug-in;

  • better-scroll: probably the best mobile scrolling plugin available;

  • fastclick: Solve the mobile side click 300ms delay

  • vConsole: Mobile phone front-end development debugging tool

  • The webpack proxyTableSet the cross-domain

  • Communication between VUE components(parent communicates with child, child communicates with parent, non-parent communicates) method example;

  • Ref featureThe use of;

  • The vuesetTimeout.setIntervalThe use of;

  • $nextTick (this.$nextTick);
  • new FormData()Upload images;

  • vue,@click="event()", the difference between adding () and not adding ();

cssrem

A CSS value to REM VSCode plug-in. When we do mobile development, we usually convert the pixel unit PX to REM for web adaptation. When developing with vscode, we can install the cssrem plug-in.

The plugin looks like this:




Default configuration:

RootFontSize: root font size (unit: px), default: 16; "Cssrem. fixedDigits" : the maximum length of the rem decimal point from px to rem, default: 6; "Cssrem. AutoRemovePrefixZero" : automatically remove 0 prefix in the beginning, the default: true,Copy the code

Configuration in the project:

"Cssrem. fixedDigits": 2,//px to REM reserved 2 decimals "cssrem.rootFontSize":75// Px to REM baseline 75pxCopy the code

As I used lib-flexible, taobao’s flexible layout scheme in the project, the UI was designed according to the size of iphone6 (750px). Font size:75px for root HTML when the project is on iphone6 screen, so rem baseline is 75px configured in the project;

"Cssrem. fixedDigits:2", // set the maximum decimal point from PX to REM to 2 digits;Copy the code

Usage:

Here’s how vsCode is configured:

File –> Preferences — Settings –> “Search cSSREM”, put your Settings in the right side to overwrite “Default Settings”, restart the editor can; As shown in figure:




lib-flexible

  • Lib – flexible introduction:

Lib-flexible is a flexible layout adaptation solution for mobile terminals. Many big companies, such as NetEase, Taobao and so on, are using it as a mobile terminal layout.

  • Usage:

Install the lib – flexible:

npm install lib-flexible --saveCopy the code

Introduce lib-flexible in the project entry file main.js

import 'lib-flexible'Copy the code

Remove meta tags from the index.html header of the target file.

< meta name = "viewport" content = "width = device - width, initial - scale = 1.0" >Copy the code

Do not write meta in the above line, flexible will automatically add the value for me based on the screen, if you add it yourself, then flexible will be calculated based on the value you add, and there will be a fixed value, android and Apple will be the same. Data-dpr may now be fixed

Knowledge extension:

Px2rem-loader: Px2REM-Loader: Px2REM-Loader: Px2REM-Loader: PX2REM-Loader: PX2REM-Loader: PX2REM-Loader: PX2REM-Loader

Use method, can refer to the official website; However, it has certain limitations, that is, it can only convert px in the style tag of.vue file into REM, and introduce CSS externally, can PX2REM convert REM?

For third-party frameworks introduced, their styles are written in a different way, and the styles will be converted by flexible, which will break the style of the framework.

If a line of code in the.vue file style does not want to be converted to REM, just comment /* no*/ after it.

vue-touch

  • Vue – touch is introduced:

Vue-touch actually encapsulates hammer.js methods that listen for six major events on the touch screen. Official website.

  • Usage:

Install the vue – touch:

npm install vue-touch@nextCopy the code

Embedded vue – touch:

Register it as a global component in the vue entry file main.js:

var VueTouch = require('vue-touch')
Vue.use(VueTouch, {name: 'v-touch'})Copy the code

Example:

Swipe me! < V-touch V-on :swipeleft="onSwipeLeft(data)">Swipe me! </ V-touch > // Click render as an A tag < V-touch tag=" A "V-ON :tap="onTap"> tap me! </ V-touch > // Click render as p tag < V-touch tag="p" V-ON :tap="onTap"> tap me! </ V-touch > Commonly used events are: swiper(swipe event), tap(click event within a short period of time), press(press event)Copy the code

  • API and related events:

Event Description:

Pan, the drag event in the touch screen. In the specified DOM area, a finger drops and moves the event

The event types are: PAN, panstart, panmove, panend, Pancancel, panleft, panright, panup, pandown; Use the following method: V-on :panstart=”callback”;

Swipe: an event in which a finger swipes across the touch screen quickly in a specified DOM area.

Event types include: Swipe, swipeleft, Swiperight,

swipeup, swipedown

Use the following method: v-on:swipeleft=”callback”;

Tap: This event is triggered when a finger taps or clicks in the specified DOM area (similar to CLICK on the PC side). The maximum click time of this event is 250 milliseconds. If the click time exceeds 250 milliseconds, the Press event is processed.

Event type: tap

V-on :tap=”callback”

4. Press: The touch screen version of the Click event in the specified DOM area. This event is equivalent to the PC side Click event, which cannot contain any movement, and the minimum Press time is 500 milliseconds. This event listens for and handles the following events:

Event type: press, Pressup

Usage: v-on:press = “callback”

Rotate events: Trigger when two or more fingers Rotate in a circle (like two fingers turning a screw) in a specified DOM area. This event listens for and handles the following events

Rotate, rotatestart, rotatemove,

rotateend, rotatecancel,

Method: v-on:rotate = “callback”

Pinch: An event that occurs when two fingers (two by default, multiple fingers need to be set separately) or multiple fingers move towards each other (getting closer) or towards each other (getting farther and farther) in a specified DOM area. This event is used to listen for and handle the following events:

Pinchstart: the multi-touch starts, Pinchmove: the multi-touch process, Pinchend: the multi-touch ends, Pinchcancel: the multi-touch cancels, Pinchin: the two fingers are closer together in the multi-touch, Pinchout: the two fingers are farther apart in the multi-touch

Matters needing attention:

Note: Vue2.0.0 is compatible with vue2.0.0;

Application examples:

Swipe through gestures to switch pages, for example:

swiperleft: function () {
    this.$router.push({'path':'/queuehistory'});
 }Copy the code

vee-validate

  • Vee – validate is introduced:

Vee-validate is a form validation plug-in applicable to vUE projects. Vee-validate is introduced to facilitate form verification. Official website.

  • Install the vee – validate
npm install vee-validate@next --saveCopy the code

Note: @next or Vue1.0

Pay attention to the installation version. Different versions use different methods.

After the installation is complete, if the correct reference is made in main.js, if in the console, the following error message is displayed:

IMPORTED_MODULE_5_vee_validate__.a.addLocale is not a func

If the version you installed is too high, uninstall it again and install a lower version. The version installed in my project is: 2.0.0-RC.25.

  • The vee-validate plugin is referenced in main.js
import Vue from 'vue' import VeeValidate,{ Validator } from 'vee-validate' import zh_CN from 'vee-validate/dist/locale/zh_CN' Vue. Use (VeeValidate, {locale: 'zh_CN'})Copy the code

  • Extend custom validation rules
Extend ('phone', {messages: {zh_CN: field => 'please enter the correct phone number'}, validate: Value = > {return / ^ (13 14 [579] [0-9] | | 15 [0, 3, 5-9] 16 [6] | | 17 [0135678] [0-9] | | 18 19 [89]) \ d {8} $/. The test (value)}}); Extend ('isCard', {messages: {zh_CN: field => 'please enter the correct ID number'}, validate: value => { return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(value) } })Copy the code

  • Chinese Settings of built-in rules
const dictionary = { zh_CN: { messages: { required: (val) => { let msg = '' switch (val) { case 'ownerPhone': Numeric: (val) => {let MSG = 'switch (val) {case 'houseShi': MSG = 'bedroom' break} MSG = MSG + 'only for digital return MSG}}}} the Validator. UpdateDictionary (dictionary)Copy the code

  • Use in components

Plug-in shipped and custom rules, writing: v – validate = “‘ required | ownerPhone ‘”, set the name attribute, through the v – show =” errors. From the () “for the name attribute to monitor, show and hide the message;

<form class="form" autocomplete="off" @submit.prevent="validateBeforeSubmit"> <div class="form-item"> <input Type = "number" placeholder = "please enter your phone number" v - model = "params. OwnerPhone" v - validate = "' required | ownerPhone '" name =" ownerPhone "> <span v-show="errors.has('ownerPhone')" class="help is-danger"> {{ errors.first('ownerPhone') }} </span> </div> <button Class ="form- BTN bg-blue" type="submit">Copy the code

For more details about the syntax, see vee-validate.

better-scroll

  • Better – scroll is introduced:

Better Scroll, the official website, Better Scroll is a plug-in that focuses on solving the needs of various scrolling scenarios on mobile terminals (PC terminals are now supported). Its core is the implementation of iscroll reference, its API design is basically compatible with IScroll, on the basis of IScroll and extended some features and do some performance optimization.

Better Scroll is implemented based on native JS and does not rely on any framework. It is a very lightweight JS lib with a compiled size of 63KB, compressed size of 35KB, and gzip size of 9KB.

  • Method of use

Installation method

npm install --save better-scroll;Copy the code

start

The most common application scenario of Better-Scroll is list scroll, let’s take a look at its HTML structure:

<div class="wrapper"> <ul class="content"> <li>... </li> <li>... </li> ... </ul> <! -- You can put some other DOM here, but it won't affect scrolling --> </div>Copy the code

In the code above, the better-scroll is applied to the outer Wrapper container, and the scroll part is the Content element. Note that the Better scroll handles only the first child of the Wrapper and all other elements will be ignored.

The simplest initialization code is as follows:

import BScroll from 'better-scroll'
let wrapper = document.querySelector('.wrapper')
let scroll = new BScroll(wrapper)Copy the code

Load more data with interface drop-down refresh

export default { methods:{ async getMyBillList() { const res = await getMyBillList(reqData); if (res.status.code == "200") { this._houseScroll(); }else{console.log(" interface call failed ~"); } }, _houseScroll(){ this.$nextTick(() => { if (! this.houseScroll) { let wrapper = document.querySelector('.wrapper'); // Scroll // new Bscroll(), initialize the container; this.houseScroll = new Bscroll(wrapper,{ scrollY: true, probeType: 3, click: true, pullUpLoad: { threshold: -100 // Trigger pullingUp when the pull-up reaches beyond the bottom 20px}}); // Initialize pull-up refresh to load more methods this.housescroll. on("pullingUp", () => {this.pageno ++; if (this.totalPage >= this.pageNo) { this.pageNo++; // Add data to the second page by pageNo this.getMyBillList(); this.loading = true; } else { this.loading = false; this.loadingOver = true; }}); } else { this.houseScroll.finishPullUp(); this.houseScroll.refresh(); }}); }}}Copy the code

Fastclick plugin: solves mobile click 300ms latency

In the mobile terminal project, the click event delay of 300ms exists in some browsers of some models, which affects user satisfaction. The reason: The mobile browser waits about 300 milliseconds between clicking on an element on the screen and the click event that triggers that element because it wants to see if you’re going to double tap.

In the Vue project, this can be resolved by introducing fastClick third-party dependencies.

Installation method:

npm  install --save fastclickCopy the code

Usage:

In the main. In js

import fastclick from 'fastclick'
fastclick.attach(document.body)Copy the code

You can also download Fastclick.js directly and reference it in the corresponding page.

Mobile phone front-end development and debugging tool – vConsole

Introduction to vConsole: a lightweight, scalable front-end developer debug panel for mobile web.

For the mobile terminal project, the console cannot be opened on the mobile terminal, so the console information cannot be viewed as intuitively as the Chrome console on the PC. However, we can use the vConsole plug-in for debugging.

The usage method is as follows:

Install vConsole:

npm install vconsole --save-devCopy the code

Reference and instantiate in main.js:

import VConsole from 'vconsole'; const vConsole = new VConsole(); // When not in use, this sentence can be masked;Copy the code

In this case, you can use the console.log principle: rewrite the console.log, rewrite the implementation, and use the vConsole agent

The result is a button that floats as shown in the figure. When clicked, you can see the console information inside.




Webpack’s proxyTable setup is cross-domain

In the usual project development environment, cross-domain problems are often encountered, especially when using vuE-CLI scaffolding tool development. Since the project itself needs to occupy a port to start local services, cross-domain problems will inevitably occur. In projects that use WebPack as a build tool, cross-domain implementation using the proxyTable agent is a convenient option.

ProxyTable configuration and usage:

When we build the project with vue-CLI, we need to find the proxyTable object under dev object in config/index.js file for cross-domain setting, and the configuration is as follows:

dev: { env: require('./dev.env'), port: 8080, autoOpenBrowser: true, assetsSubDirectory: 'static', assetsPublicPath: '/', cssSourceMap: false, proxyTable: {'/ API ': {target: 'http://www.abc.com', // changeOrigin: PathRewrite: {'^/ API ': '/ API '/ / Override interface}}}Copy the code

ProxyTable uses the string “/ API “instead of the target interface domain name. If the interface address is “user/getUserInfo”, we can set the proxy by adding “/ API /” to all interface addresses. Such as:

'http://localhost:8080/api/user/getUserInfo' ===> 'http://www.abc.com/api/user/getUserInfo'Copy the code

If you don’t want to have “/ API /” in the address every time you request it, you can

PathRewrite: {'^/ API ': '// can be overridden after the new path, generally do not change}Copy the code

The performance results are:

'http://localhost:8080/api/user/getUserInfo' ===> 'http://www.abc.com/user/getUserInfo'Copy the code

Alternatively, we don’t need to add “/ API /” to each interface address, just use the address of the interface itself, and don’t need a new path. If the interface is “/v2/cotton/get_app_list”, use “/v2” as the proxy. As follows:

Dev: {proxyTable: {'/v2': {target: 'http://www.abc.com', // Target interface domain name changeOrigin: true, // Whether cross-domain secure: False, // allow HTTPS requests // resetting the new path is removed, because the interface address itself begins with "/v2/"; } } 'http://localhost:8080/v2/cotton/get_app_list' ===> 'http://www.abc.com/v2/cotton/get_app_list' // http://localhost:8080/v2 said http://www.abc.comCopy the code

By default, backend servers running over HTTPS with invalid certificates are not accepted. If you want to accept, modify the configuration as follows:

proxy: {
  "/api": {
    target: "https://www.abc.com",
    secure: false
  }
}Copy the code

Communication between VUE components

  • The parent passes data to the child via props
/** Parent code: **/ <template> <header-box :title="text"></header-box> </template> <script> import HeaderBox from './header' export default { name: 'index', components: { HeaderBox }, data () { return { text: </template> <header> {{thisTitleTxt}} </header> </template> <script> export default { name: 'headerbox', props: { text: String }, data () { return { thisTitleTxt: this.text } } } </script>Copy the code

  • The child passes data to the parent

There are two types of child component passing to parent. 1. The child component changes the props passed by the parent component. (You can see that the child component can change the content of the data passed by the props Object parameter. This approach is possible, but not recommended, because prop is officially one-way binding); $on and $emit; That is, the child component fires the event via $emit(); The parent component responds to events with the: on method attached to the valence element.

* * * * by $on, $emit the parent component code * * < template > < div id = "counter - event - example" > < p > {{total}} < / p > <! <button-counter V-on :increment="incrementTotal"></button-counter> </div> </template> <script> import ButtonCounter from './buttonCounter' export default { name: 'index', components: { 'button-conuter': ButtonCounter }, data () { return { total: 0 } }, methods: {incrementTotal () {this.total++}}} </script> ** child component code ** <template> <button @click="incrementCounter">{{counter}}</button> </template> <script> export default { name: 'button-counter', data () { return { counter: 0 } }, metheds: { incrementCounter () { this.$emit('increment'); $emit('key',value) {this.counter++}}} </script>Copy the code

  • Non-parent components pass data;

By using an empty Vue instance as the central event bus.

**main.js**
let bus = new Vue()
Vue.prototype.bus = bus;Copy the code

Adjacent component 1, which passes data through $emit()

This. Bus. $emit (" toChangeTitle ", "home page");Copy the code

Adjacent component 2, receives data via $on()

mounted(){
   this.bus.$on('toChangeTitle', function (title) {
       console.log(title)
  })
}Copy the code

Use of the REF feature

Ref is used to register reference information for an element or child component. The reference information will be registered with the parent component’s $refs object.

If used on a normal DOM element, the reference refers to the DOM element. If used on a child component, the reference refers to the component instance:

<div id="app"> <input type="text" ref="input1" v-model="name"/> <button @click="add"> </button> <! -- `vm.$refs.child` will be the child component instance --> <child-component ref="child"></child-component> </div> <script> export default{ data(){ return { name:"xiaoming" } }, created(){ this.$nextTick(()=>{ console.log(this.$refs.input1.value); }); }, methods:{ add(){ this.$refs.input1.value = "22"; //this.$refs.input1 reduces the cost of retrieving dom nodes}}} </script>Copy the code

When v-for is used for elements or components, the reference information will be an array containing DOM nodes or component instances.

Important note about ref registration times: Because ref’s are themselves created as render results, you can’t access them during initial render – they don’t exist yet! $refs is also not reactive, so you should not attempt to use it to do data binding in templates.

The parent component calls the child component’s methods and properties by using the ref attribute on the referenced child component

Reference the child component in the parent component and define the ref

<``v-food ref="selectfood"></``v-food``>

Call the method show defined in the child component

this.$refs.selectfood.show(); // You can also invoke properties in child components

The use of setTimeout in vue

Use setTimeout or setInterval in vue if you follow the method in original JS, such as

setTimeout(function(){ this.isFlag = true; }, 3000);Copy the code

The variable isFlag defined in data is not available. Solutions are as follows:

  • Using setTimeout passes es6 syntax, as does setInterval
import { setTimeout } from "timers"; export default{ data(){ return { time:"", isFlag:false } }, methods:{ add(){ clearTimeout(this.time); this.time = setTimeout(() =>{ this.isFlag = true; }}}}, 2000)Copy the code

  • Define external self instead of global this
export default { methods: { add() { const self = this clearTimeout(this.time) this.time = setTimeout(function() { self.isFlag = true }, 2000)}}}Copy the code

We’ll see that the first way to use the example, using this to get the variable, will result in an error. This is the age-old javaScript this problem. Function () {} this is a global function (in this case, window) and myFunc is not in the window. Using es6’s -> notation, this inherits from an external object and points to an instance of vue, i.e. (new vue);

Monitor mouse rolling events to achieve the head suspension effect

$nextTick is invoked after the next DOM update loop, and the mouse scroll event needs to be listened for via window.addeventListener (” Scroll “, “).

$nextTick(function() {window.addeventListener ('scroll', NeedToTop) // Scrollevent listener})}, methods: (1) {{needToTop const curHeight = document. The documentElement. The scrollTop | | document. The body. The scrollTop const / / scroll bar from the top of the distance Function: function function: function function: function function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function: function this.$refs['title'].style.background = 'rgba(255, 255, 255, ' + opacity + ')' this.$refs['title'].style.boxShadow = '0 0 .27rem rgba(204, 204, 204, ' + opacity + ')' } } }Copy the code

Vue uploads images

Create a form object with new FormData() and add data to the form object with Append.

The HTML code is as follows:

<template> <div class="txarea"> <input type="file" class="txfile" name="file" id="upimg" accept="image/*" @change="fileChange($event)"> <p class="tx" @click="chooseType"> methods: ChooseType () {document.getelementById ('upimg').click()}, FileChange (e) {const file = e.target.files[0] const param = new FormData() // Create a form object param.append('file', file, // Add data to form object via append const config = {headers: {' content-type ': 'multipart/form-data'} this.axios.post(uploadUrl, param, config). Save to the database; const reqData = { phone: this.loginInfo.phone, pic: Response.data. url} this.setUserinfo (reqData)})}, setUserInfo() {// Save user image}}} </script>Copy the code

Vue,@click=”event()”, the difference between adding () and not adding ()

Vue has wrapped the function call expression with an extra function. The difference between parentheses and no parentheses is in the handling of the event object parameter.

Without parentheses, the first argument to the function defaults to event; After parentheses, you need to manually pass in $event to get the event object.

<template> <div class="btn-item"> <button class=" btn-success" @click="sure($event)"> </button> <button class=" BTN Btn-default "@click="quit"> cancel </button> </div> </template> <script> export default{name:'test', data(){return {}}, methods:{ sure(e){ console.log(e.target); }, quit(e){ console.log(e.target); } } } </script>Copy the code

Project practice: Based on vue2.0 + VUEX + Element-UI background management system

The second post will be updated later:

  • Use of VUX-VUE mobile UI component library;
  • Vuex: Introduction to vUE status management tool.
  • Application of Baidu Map API in VUE project:
  1. Vue2 how to add housing overlay to the map;
  2. How to add custom positioning control to the map and change the control icon;
  3. Several commonly used API (map zoom, drag, get the current location) and other functions;
  • Application of wechat API in VUE project:
  1. Vue2 can share pit points and experience with wechat;
  2. Vue2 realized wechat payment pit point and experience;
  • Unified management of FETCH encapsulation interface;

Welcome to join the discussion group, together to learn to use vue, vuex, element, express, directing to build the background management system;

Let’s use the project to deepen our understanding of knowledge.

Article recommendation:

Here are some of the top tips for interviewing in 2018

Super easy to use development tools, programmer utility collation

Collect quality Chinese front-end blogs (updated irregularly)

In-game Search (laravel Scout + ElasticSearch)

Vue Axios encapsulation and API interface management


Original link:

Share dry goods: Vue2.0 mobile terminal development used by the relevant plug-ins and experience summary – meow Rongpanmiaorong.top