zoukankan      html  css  js  c++  java
  • Vue实战之【企业开发常见问题】

    1.vue框架使用注意事项和经验

    1.1 解决Vue动态路由参数变化,页面数据不更新

    问题描述:

    遇到动态路由如:/page/:id
    从/page/1 切换到 /page/2 发现页面组件没有更新

    解决方式1:
    增加一个不同:key值,这样vue就会识别这是不同的了。

    <router-view :key="key"></router-view>
      ...
      computed:{
            key(){
                return this.$route.path + Math.random();
            }
        }
    

    解决方案2: 在组件内使用v2.2新增的beforeRouteUpdate

    beforeRouteUpdate (to, from, next) {
        // 在当前路由改变,但是该组件被复用时调用
        // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
        // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        // 可以访问组件实例 `this`
      },
    

    1.2 vue组件里定时器销毁问题**

    问题描述:

    在a页面写一个定时器,每秒钟打印一次,然后跳转到b页面,此时可以看到,定时器依然在执行。
    推荐的解决方式:
    通过$once这个事件侦听器器在定义完定时器之后的位置来清除定时器。

    const timer = setInterval(() => {
        // 定时器操作
    }, 1000)
    // 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
    this.$once('hook:beforeDestroy', () => {            
        clearInterval(timer);                                    
    })
    

    也可以使用生命周期声明的方式:

    export default {
    	beforeDestroy(){
    		clearInterval(timer);
        }
    }
    

    1.3 vue实现按需加载组件的两种方式**

    1.使用resolve => require(['./ComponentA'], resolve),方法如下:

    const ComponentA = resolve => require(['./ComponentA'], resolve)
    

    2 使用 () => import(), 具体代码如下:

    const ComponentA = () => import('./ComponentA')
    

    1.4 组件之间,父子组件之间的通信方案

    组件之间的通信方案:

    • 通过事件总线(bus),即通过发布订阅的方式
    • vuex
    • 父子组件:
      • 父组件通过prop向自组件传递数据
    • 子组件绑定自定义事件,通过this.$emit(event,params) 来调用自定义事件
    • 使用vue提供的$parent/$children & $refs方法来通信
    • provide/inject
    • 深层次组件间的通信 $attrs, $listeners

    1.5 vue中 $event 的用法--获取当前父元素,子元素,兄弟元素

    <button @click = “fun($event)”>点击</button>
      ...
      
      methods: {
       fun(e) {
        // e.target 是你当前点击的元素
        // e.currentTarget 是你绑定事件的元素
        #获得点击元素的前一个元素
        e.currentTarget.previousElementSibling.innerHTML
        #获得点击元素的第一个子元素
        e.currentTarget.firstElementChild
        # 获得点击元素的下一个元素
        e.currentTarget.nextElementSibling
        # 获得点击元素中id为string的元素
        e.currentTarget.getElementById("string")
        # 获得点击元素的string属性
        e.currentTarget.getAttributeNode('string')
        # 获得点击元素的父级元素
        e.currentTarget.parentElement
        # 获得点击元素的前一个元素的第一个子元素的HTML值
      e.currentTarget.previousElementSibling.firstElementChild.innerHTML
      
        }
            }
    

    1.6 axios二次封装http请求

    import axios from 'axios'
    import router from '@/router'
    import {removeSessionStorage} from './storage';
    import Vue from 'vue'
    import { Message } from 'element-ui' // 引用element-ui的加载和消息提示组件
    // 请求超时时间配置
    axios.defaults.timeout = 30000;
    // api地址配置
    axios.defaults.baseURL = "";
    // console.log(process.env.VUE_APP_BASE_API)
    Vue.prototype.$http = axios
    // 在全局请求和响应拦截器中添加请求状态
    let loading = null
    
    // 请求拦截器
    axios.interceptors.request.use(
        config => {
          config.headers = {
            'Content-Type': 'application/json'
          };
          // loading = Loading.service({ text: '拼命加载中' })
          let token = sessionStorage.getItem('-_token_-');
          if (token) {
            config.headers['token'] = token;
          }
          return config
        },
        error => {
          return Promise.reject(error)
        }
    )
    
    // 响应拦截器
    axios.interceptors.response.use(
        response => {
          if (loading) {
            loading.close()
          }
            // 自定义错误码,各公司根据约定都不一样
            // 此处省略业务处理代码
            let errorCode = response.data.errCode;
            if(errorCode==='000000'){
              return Promise.resolve(response.data);
            }else {
                router.push({
                  name: 'error',
                  params: {
                    isTimeout: false,
                    path: router.currentRoute.path,
                    desc: '您请求的资源找不到(错误码:404) ',
                  },
                });
            } 
        },
        error => {
          if (loading) {
            loading.close();
          }
        	// 此处省略业务处理代码
          return Promise.reject(error);
        }
    );
    

    1.7 开发环境中代理的切换配置

    为了应对这样的跨域场景,在代码开发时,devServer要代理到本地后端,测试时,又要去修改代理到测试环境,上线后,调试新问题有可能代理到线上环境

    该代码运行环境为node.js,使用process.env可以获取到系统环境变量,从而区分当前机器是公司的生产机器,还是个人的开发机器

    对vue.config.js的进行配置

    const Timestamp = new Date().getTime();  //当前时间为了防止打包缓存不刷新,所以给每个js文件都加一个时间戳
    const proxyTargetMap = {
        prod: 'https://xxx.xxx.com/',
        dev: 'http://192.168.200.230:6379',
        test: 'http://test.xxx.com',
        local: 'http://localhost:8080/'
    }
    let proxyTarget = proxyTargetMap[process.env.API_TYPE] || proxyTargetMap.local
    module.exports = {
        publicPath: process.env.NODE_ENV === 'production' ? '/' : '/',
        outputDir: 'dist',
        assetsDir: 'static',
        lintOnSave: false, // 是否开启eslint保存检测
        productionSourceMap: false, // 是否在构建生产包时生成sourcdeMap
        // 调整内部的 webpack 配置。
        // 查阅 https://github.com/vuejs/vue-docs-zh-cn/blob/master/vue-cli/webpack.md
        chainWebpack: () => { },
        //configureWebpack 这部分打包文件添加时间戳,防止缓存不更新
        configureWebpack: {
            output: { // 输出重构  打包编译后的 文件名称  【模块名称.版本号.时间戳】
                filename: `[name].${process.env.VUE_APP_Version}.${Timestamp}.js`,
                chunkFilename: `[name].${process.env.VUE_APP_Version}.${Timestamp}.js`
            },
        },
    
        devServer : {
            proxy: {
                '/api' : {
                    target: proxyTarget,
                    changeOrigin: true,
                    pathRewrite: {
                        '^/api' : ''
                    }
                }
            }
        }
    };
    

    对应的package.json配置为

    看下面的cross-env API_TYPE=dev

    cross-env是一个全局命令行工具,可以根据不同的平台更改当前的环境变量,从而实现了可以在开发者的机器上,选择性的调用开发模式或者生产模式

    "scripts": {
      "serve": "vue-cli-service serve --mode development",
    +  "serve:dev": "cross-env API_TYPE=dev vue-cli-service serve --mode development",
    +  "serve:test": "cross-env API_TYPE=test vue-cli-service serve --mode development",
      "build": "vue-cli-service build --mode production",
      "test": "vue-cli-service build --mode test",
      },
    

    图片

  • 相关阅读:
    girdview
    c#中&&,||的应用
    ToString()和Convert.ToString()的区别
    日期格式化
    线程间操作ui
    基于k3cloud做的东西
    格式化金额字段添加千位符
    SQL 分页查询
    xammp 配置虚拟主机
    jQuery事件对象event的属性和方法
  • 原文地址:https://www.cnblogs.com/qidaoxueyuan/p/12341822.html
Copyright © 2011-2022 走看看