• vue中实用小技巧,长期更新


    1、在vue 中使用webpack require.context工程化配置组件,不用一个一个import注册了

    main.js中

    import Vue from 'vue'
    //使用lodsh插件
    import upperFirst from 'lodash/upperFirst' import camelCase from 'lodash/camelCase' const requireComponent = require.context( // 其组件目录的相对路径 './components', // 是否查询其子目录 false, // 匹配基础组件文件名的正则表达式 /Base[A-Z]w+.(vue|js)$/ ) requireComponent.keys().forEach(fileName => { // 获取组件配置 const componentConfig = requireComponent(fileName) // 这个地方直接传入filename其实就是内部会调用了resolve方法,会返回对应的文件内容(不理解可以console一下看看) // 获取组件的 PascalCase 命名 const componentName = upperFirst( camelCase( // 获取和目录深度无关的文件名 fileName .split('/') .pop() .replace(/.w+$/, '') ) ) // 全局注册组件 Vue.component( componentName, // 如果这个组件选项是通过 `export default` 导出的, // 那么就会优先使用 `.default`, // 否则回退到使用模块的根。 componentConfig.default || componentConfig ) })

     解释

    实际上是 webpack 的方法,vue 工程一般基于 webpack,所以可以使用
    require.context(directory,useSubdirectories,regExp)
    接收三个参数:
    directory:说明需要检索的目录
    useSubdirectories:是否检索子目录
    regExp: 匹配文件的正则表达式,一般是文件名

     2、$attrs和$listeners

    1.$attrs
    场景:如果父传子有很多值,那么在子组件需要定义多个 props
    解决:$attrs获取子传父中未在 props 定义的值

    // 父组件
    <home title="这是标题" width="80" height="80" imgUrl="imgUrl"/>
    
    // 子组件
    mounted() {
      console.log(this.$attrs) //{title: "这是标题",  "80", height: "80", imgUrl: "imgUrl"}
    },

    相对应的如果子组件定义了 props,打印的值就是剔除定义的属性

    props: {
       {
        type: String,
        default: ''
      }
    },
    mounted() {
      console.log(this.$attrs) //{title: "这是标题", height: "80", imgUrl: "imgUrl"}
    },

    2.$listeners
    场景:子组件需要调用父组件的方法
    解决:父组件的方法可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用

    // 父组件
    <home @change="change"/>
    
    // 子组件
    mounted() {
      console.log(this.$listeners) //即可拿到 change 事件
    }

    如果是孙组件要访问父组件的属性和调用方法,直接一级一级传下去就可以

    正常情况下 我们使用emit就可以解决父子之间执行函数的问题 但是当孙子组件需要执行爷爷组件的函数时,我们可以使用这种方法,一层一层绑定 第二层绑定$listeners.xxx

    3.动态组件

    场景:做一个 tab 切换时就会涉及到组件动态加载

    <component v-bind:is="currentTabComponent"></component>

    但是这样每次组件都会重新加载,会消耗大量性能,所以<keep-alive> 就起到了作用

    <keep-alive>
      <component v-bind:is="currentTabComponent"></component>
    </keep-alive>

    这样切换效果没有动画效果,这个也不用着急,可以利用内置的<transition>

    <transition>
    <keep-alive>
      <component v-bind:is="currentTabComponent"></component>
    </keep-alive>
    </transition>
    transition效果参考:https://cn.vuejs.org/v2/guide/transitions.html#%E5%8D%95%E5%85%83%E7%B4%A0-%E7%BB%84%E4%BB%B6%E7%9A%84%E8%BF%87%E6%B8%A1



    4.extend

    场景:vue 组件中有些需要将一些元素挂载到元素上,这个时候 extend 就起到作用了
    是构造一个组件的语法器
    写法: 

    // 创建构造器
    var Profile = Vue.extend({
      template: '<p>{{extendData}}</br>实例传入的数据为:{{propsExtend}}</p>',//template对应的标签最外层必须只有一个标签
      data: function () {
        return {
          extendData: '这是extend扩展的数据',
        }
      },
      props:['propsExtend']
    })
    
    // 创建的构造器可以挂载到元素上,也可以通过 components 或 Vue.component()注册使用
    // 挂载到一个元素上。可以通过propsData传参.
    new Profile({propsData:{propsExtend:'我是实例传入的数据'}}).$mount('#app-extend')
    
    // 通过 components 或 Vue.component()注册
    Vue.component('Profile',Profile)

    demo参考:https://www.jianshu.com/p/b931abe383e3

    5 transformToRequire

    场景:以前在写 Vue 的时候经常会写到这样的代码:把图片提前 require 传给一个变量再传给组件

    // page 代码
    <template>
      <div>
        <avatar :img-src="imgSrc"></avatar>
      </div>
    </template>
    <script>
      export default {
        created () {
          this.imgSrc = require('./assets/default-avatar.png')
        }
      }
    </script>

    现在:通过配置 transformToRequire 后,就可以直接配置,这样vue-loader会把对应的属性自动 require 之后传给组件

    // vue-cli 2.x在vue-loader.conf.js 默认配置是
    transformToRequire: {
        video: ['src', 'poster'],
        source: 'src',
        img: 'src',
        image: 'xlink:href'
    }
    
    // 配置文件,如果是vue-cli2.x 在vue-loader.conf.js里面修改
      avatar: ['default-src']
    
    // vue-cli 3.x 在vue.config.js
    // vue-cli 3.x 将transformToRequire属性换为了transformAssetUrls
    module.exports = {
      pages,
      chainWebpack: config => {
        config
          .module
            .rule('vue')
            .use('vue-loader')
            .loader('vue-loader')
            .tap(options => {
          options.transformAssetUrls = {
            avatar: 'img-src',
          }
          return options;
          });
      }
    }
    
    // page 代码可以简化为
    <template>
      <div>
        <avatar img-src="./assets/default-avatar.png"></avatar>
      </div>
    </template>

    6.为路径设置别名

    1.场景:在开发过程中,我们经常需要引入各种文件,如图片、CSS、JS等,为了避免写很长的相对路径(../),我们可以为不同的目录配置一个别名

    2.vue-cli 2.x 配置

    // 在 webpack.base.config.js中的 resolve 配置项,在其 alias 中增加别名
    resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          'vue$': 'vue/dist/vue.esm.js',
          '@': resolve('src'),
        }
      },

    3.vue-cli 3.x 配置

    // 在根目录下创建vue.config.js
    var path = require('path')
    function resolve (dir) {
      console.log(__dirname)
      return path.join(__dirname, dir)
    }
    module.exports = {
      chainWebpack: config => {
        config.resolve.alias
          .set(key, value) // key,value自行定义,比如.set('@@', resolve('src/components'))
      }
    }

    7.img 加载失败

    场景:有些时候后台返回图片地址不一定能打开,所以这个时候应该加一张默认图片

     
    // page 代码
    <img :src="imgUrl" @error="handleError" alt="">
    <script>
    export default{
      data(){
        return{
          imgUrl:''
        }
      },
      methods:{
        handleError(e){
          e.target.src=reqiure('图片路径') //当然如果项目配置了transformToRequire,参考上面 27.2
        }
      }
    }
    </script>

    8、slot插槽

    9、mixins混入

    10、$parents与$ref 

    demo:https://www.cnblogs.com/hy96/p/12195131.html

     



  • 相关阅读:
    [BZOJ] IOI2015 Boxes纪念品盒
    [BZOJ] 聚会
    [BZOJ] 地精部落
    [BZOJ] 最长距离
    正则
    cookie实例 记住用户名密码
    cookie封装
    碎片整合 例子
    闭包 tab切换 实例
    闭包
  • 原文地址:https://www.cnblogs.com/hy96/p/13576334.html
Copyright © 2020-2023  润新知