项目实战【vue,react,微信小程序】(1708E)

目录

一、Promise

二、swiper

三、$event

四、transition 过渡动画

五、toast组件

六、解构并不能实现对象的深拷贝

七、修改脚手架默认包管理工具

八、redux

九、react组件props类型检查和默认值

十、使用webpack搭建react开发环境

github源码:


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

一、Promise

async函数会返回一个promise,并且Promise对象的状态值是resolved(成功的)

    //Promise基础用法
    let pro = new Promise(resolve => {
      setTimeout(() => {
        resolve('hello world')
      }, 500)
    })

    pro.then(res => {
      console.log(res) // hello world
    })

    //Promise和async await相结合,async函数会返回一个promise,并且Promise对象的状态值是resolved(成功的)
    const fun = async () => {
      let result
      await new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve({
            code: 200,
            data: { name: 'zhangsan' },
            message: '姓名'
          })
        }, 1000)
      }).then(res => {
        result = res
      })

      return result
    }

    ////Promise和async await相结合二
    fun().then(res => {
      console.log(res)
    })

    const fun2 = async () => {
      return await new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve({
            code: 200,
            data: 'lishi',
            message: '消息'
          })
        }, 1500)
      })
    }

    fun2().then(res => {
      console.log(res)
    })

 

二、swiper

swiper.js:





main.js:

import Vue from 'vue'
import lazyload from 'vue-lazyload'
import App from './App.vue'
import router from './router'
import store from './store'
import VueAwesomeSwiper from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
import './font/iconfont.css'
import './index.css'
import img from './images/loading.png'


Vue.config.productionTip = false

Vue.use(lazyload, {
  loading: img
})

Vue.use(VueAwesomeSwiper)

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

三、$event

有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法。

https://cn.vuejs.org/v2/guide/events.html#%E5%86%85%E8%81%94%E5%A4%84%E7%90%86%E5%99%A8%E4%B8%AD%E7%9A%84%E6%96%B9%E6%B3%95

项目实战【vue,react,微信小程序】(1708E)_第1张图片

四、transition 过渡动画





五、toast组件

Toast.vue:





index.js:

import Vue from 'vue'
import Toast from './Toast'

const ToastConstructor = Vue.extend(Toast)

const toast = (options) => {
  let instance = new ToastConstructor({data: options}).$mount()
  document.body.appendChild(instance.$el)
}

export default toast

css:

.m-toast-mask{display: flex; position: fixed;top: 0;left: 0;right: 0;bottom: 0;}
.m-toast{margin: auto;padding: 0 10px; min-width: 100px;line-height: 40px;border-radius: 3px;background: rgba(0, 0, 0, 0.5);text-align: center;color: #ffffff;}

使用:





注册到全局:

import toast from './components/Toast'

Vue.prototype.$toast = toast

使用:

this.$toast({message: 'test'})

appendChild() 方法在指定元素节点的最后一个子节点之后添加节点。

https://www.w3school.com.cn/xmldom/met_element_appendchild.asp

 

六、解构并不能实现对象的深拷贝

      let obj = {
        a: 1,
        b: {
          c: '1'
        },
        fun() {
          console.log(1)
        },
        time: new Date(),
        d: undefined
      }
      let newObj = { ...obj }

      newObj.b.c = '2'
      console.log(obj)
      console.log(newObj)
      console.log(obj.b.c) // 2

七、修改脚手架默认包管理工具

项目实战【vue,react,微信小程序】(1708E)_第2张图片

八、redux

 

reducer 一定要保持纯净,只要传入参数相同,返回计算得到的下一个 state 就一定相同。没有特殊情况、没有副作用,没有 API 请求、没有变量修改,单纯执行计算。

时刻谨记永远不要在克隆 state 前修改它。

在redux-devtools中,我们可以查看到redux下所有通过reducer更新state的记录,每一个记录都对应着内存中某一个具体的state,让用户可以追溯到每一次历史操作产生与执行时,当时的具体状态,这也是使用redux管理状态的重要优势之一.

若不创建副本,redux的所有操作都将指向内存中的同一个state,我们将无从获取每一次操作前后,state的具体状态与改变,若没有副本,redux-devtools列表里所有的state都将被最后一次操作的结果所取代.我们将无法追溯state变更的历史记录.

创建副本也是为了保证向下传入的this.props与nextProps能得到正确的值,以便我们能够利用前后props的改变情况以决定如何render组件。

直接修改state(错误的):

      const defaultState = {
        count: 0
      }

      //直接修改改state,所有的state都将被最后一次操作的结果所取代.我们将无法追溯state变更的历史记录
      const reducer = (state = defaultState ) => {
        state.count++
        return state
      }

      let previousState = { count: 0 }
      let newState = reducer(previousState)
      console.log(previousState)  //{ count: 1 }
      console.log(newState)       //{ count: 1 }

深拷贝(性能很差):

      const defaultState = {
        count: 0
      }

      //深拷贝可以解决这个问题
      const reducer = (state = defaultState ) => {
        state = JSON.parse(JSON.stringify(state))
        state.count++
        return state
      }

      let previousState = { count: 0 }
      let newState = reducer(previousState)
      console.log(previousState)  //{ count: 0 }
      console.log(newState)       //{ count: 1 }

解构:

      const defaultState = {
        count: 0
      }

      //解构可以解决这个问题
      const reducer = (state = defaultState ) => {
        let newState = {...state}
        newState.count++
        return newState
      }

      let previousState = { count: 0 }
      let newState = reducer(previousState)
      console.log(previousState)  //{ count: 0 }
      console.log(newState)       //{ count: 1 }

解构属于浅拷贝,解决不了嵌套的场景:

      const defaultState = {
        obj: {
          count: 0
        }
      }

      //解构属于浅拷贝,解决不了嵌套问题
      const reducer = (state = defaultState ) => {
        let newState = {...state}
        newState.obj.count++
        return newState
      }

      let previousState = {
        obj: {
          count: 0
        }
      }
      let newState = reducer(previousState)
      console.log(previousState)  //{ obj: { count: 1 } }
      console.log(newState)       //{ obj: { count: 1 } }

非要用解构,也行:

      const defaultState = {
        obj: {
          count: 0
        }
      }

      //解构属于浅拷贝,解决不了嵌套问题,不过可以这样解决,只是比较难理解
      const reducer = (state = defaultState ) => {
        let newObj = {...state.obj}
        newObj.count++
        return {...state, obj: newObj}
      }

      let previousState = {
        obj: {
          count: 0
        }
      }
      let newState = reducer(previousState)
      console.log(previousState)  //{ obj: { count: 0 } }
      console.log(newState)       //{ obj: { count: 1 } }

immutable.js:








  

把业务代码提出来:








  

九、react组件props类型检查和默认值

不需要安装prop-types包,脚手架已经默认安装

import React, { Component } from 'react'
import PropTypes from 'prop-types'

export default class Icon extends Component {
  // static defaultProps = {
  //   type: 'xingxing'
  // }
  render() {
    let { type, className } = this.props
    return (
      
    )
  }
}

Icon.propTypes = {
  type: PropTypes.string,
  className: PropTypes.string
}

Icon.defaultProps = {
  type: 'shubao'
}

参考链接:

https://zh-hans.reactjs.org/docs/typechecking-with-proptypes.html#___gatsby

https://www.npmjs.com/package/prop-types

 

十、使用webpack搭建react开发环境

webpack.config.js:

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HtmeWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode: 'development',
  devtool: 'source-map',
  entry: __dirname + '/index.js',
  output: {
    path: __dirname + '/dist',
    filename: 'bundle-[hash].js'
  },
  devServer: {
    inline: true,
    hot: true,
    port: 9000,
    contentBase: __dirname + '/dist',
    open: true
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ["@babel/preset-react", "@babel/preset-env"]
          }
        },
        exclude: /node_modules/
      }, {
        test: /\.css$/,
        use: [{
          loader: MiniCssExtractPlugin.loader
        }, {
          loader: 'css-loader'
        }]
      }]
  },
  plugins: [
    new HtmeWebpackPlugin({
      template: __dirname + '/public/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: '[name]-[hash].css'
    })
  ]
}

package.json:

{
  "name": "toast",
  "version": "1.0.0",
  "description": "",
  "main": "/toast/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "start": "webpack-dev-server"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.7.7",
    "@babel/preset-env": "^7.7.7",
    "@babel/preset-react": "^7.7.4",
    "babel-loader": "^8.0.6",
    "css-loader": "^3.4.2",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.9.0",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "style-loader": "^1.1.2",
    "webpack": "^4.41.5",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.10.1"
  }
}

github:

https://github.com/baweireact/m-apps/tree/master/m-app-1708E/react/01%E4%BD%BF%E7%94%A8webpack%E6%90%AD%E5%BB%BAreact%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83

 

十一、webpack搭建react项目时在二级路由页面刷新报404的解决办法

react-router 使用webpack-dev-server做服务器时 单级刷新报错 Cannot GET /xx。多级刷新报错404

 

  output: {
    path: __dirname + '/dist',
    filename: 'bundle-[hash].js',
    publicPath: '/'   //第二处要添加的
  },
  devServer: {
    inline: true,
    hot: true,
    port: 9000,
    contentBase: __dirname + '/dist',
    open: true,
    historyApiFallback: true  //第一处要添加的
  },

参考链接:

https://blog.csdn.net/limonsea/article/details/96865906

十二、webpack图解

项目实战【vue,react,微信小程序】(1708E)_第3张图片

webpack+webpack-dev-server:

https://segmentfault.com/q/1010000005767033/a-1020000005767079

 

通过node启动webpack-dev-server:

https://webpack.docschina.org/guides/hot-module-replacement/#%E9%80%9A%E8%BF%87-node-js-api

 

devServer.overlay:

这个配置属性用来在编译出错的时候,在浏览器页面上显示错误,默认是false,可设置为true

devServer: {
    overlay: true
}

项目实战【vue,react,微信小程序】(1708E)_第4张图片

十三、import对象解构失败问题

用惯了es6语法中的解构赋值,在对于import引入的对象进行解构赋值时发现对象变成了undefined

解决办法:

// main.js
import { foo, bar } from "./static"

// static.js
let foo =  "foo"
let bar = "bar"
export { foo, bar }

参考链接:

https://blog.csdn.net/momDIY/article/details/88375677

十四、FileZilla连接ftp服务器失败,提示"AUTH TLS"解决方法

https://www.cnblogs.com/mytt/p/6684199.html

项目实战【vue,react,微信小程序】(1708E)_第5张图片

 

 

 

 

 

 

 

 

 

 

 

 

github源码:

https://github.com/baweireact/m-apps/tree/master/m-app-1708E

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(web前端)