even

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1、vue中的环境变量调整

假如需要添加第三种模式的时候,或者在开发过程中需要添加环境变量的时候,那么就需要做如下配置

 

 先在根目录下添加.env.自定义名字,并且里面的内容模式可以如上图进行配置

  "scripts": {
    "dev": "vue-cli-service serve --mode unit",
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },

在package.json文件中添加dev模式的,并且--mode后指定需要指定的模式

这需要就可以在项目中使用process.env进行访问

 

2、优雅更新props

更新 prop 在业务中是很常见的需求,但在子组件中不允许直接修改 prop,因为这种做法不符合单向数据流的原则,在开发模式下还会报出警告。因此大多数人会通过 $emit 触发自定义事件,在父组件中接收该事件的传值来更新 prop

常规做法:

child.vue:

parent.vue:

 

这种做法没有问题,我也常用这种手段来更新 prop。但如果你只是想单纯的更新 prop,没有其他的操作。那么 sync 修饰符能够让这一切都变得特别简单。

 

相当于语法 @update:属性名 = “value => this.属性名=value”

使用div里的contenteditable属性来模拟v-model

<template>
<div class="container">
  <div>{{text}}</div>
  <div contenteditable="true" v-html="isLock? copyTxt: text" @input="inputEvent" @focus="focusEvent" @blur="isLock = false"></div>
  <el-button type="primary" @click="changeEvent">按钮</el-button>
</div>
</template>
<script>
export default {
  name: 'home',
  data () {
    return {
      text: 'this is text',
      copyTxt: this.text,
      isLock: false
    }
  },
  methods: {
    inputEvent (ev) {
      this.text = ev.target.innerText
    },
    focusEvent () {
      this.copyTxt = this.text
      this.isLock = true
    },
    changeEvent () {
      this.text = 'are you ok???'
    }
  }
}
</script>
<style lang="less" scoped></style>

注意:在通信的过程中,如果存在父组件,子组件, 孙组件,那么孙组件想修改父组件中的属性,那么可以调用this.$parnet.$emit('函数名', 属性值),当然前提要父组件监听该方法,所以注重$parent, $children的使用

3、provide/inject 的使用

这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。

简单来说,一个组件将自己的属性通过 provide 暴露出去,其下面的子孙组件 inject 即可接收到暴露的属性。

 

 

 

4、小型状态管理器

大型项目中的数据状态会比较复杂,一般都会使用 vuex 来管理。但在一些小型项目或状态简单的项目中,为了管理几个状态而引入一个库,显得有些笨重。

在 2.6.0+ 版本中,新增的 Vue.observable 可以帮助我们解决这个尴尬的问题,它能让一个对象变成响应式数据:

 

 

 

 

 5、卸载watch观察

 通常定义数据观察,会使用选项的方式在 watch 中配置:

 

 

 

6、过滤器的复用

过滤器被用于一些常见的文本格式化,被添加在表达式的尾部,由“管道”符号指示。

 

 

 7、render函数的使用

入门案例

render (h) {
  return h('div', 'this is test')
}

延伸案例, 实现多插槽

render (h) {
  return h('div', [this.$slots.title, this.$slots.content])
}
render (h) {
  return h('div', [
    {
      tag: 'div',
      children: [h('span', { domProps: { innerHTML: 'haha' } })]
    },
    this.$slots.title, this.$slots.content
  ])
}

使用option进行配置

render (h) {
  return h('div', {
    class: { // 表示注入动态类名
      item_container: true
    },
    staticClass: 'abc', // 注入静态类名
    style: { // 表示注入style样式
      color: 'red',
      'font-weight': 'bold',
      cursor: 'pointer'
    },
    ref: 'myRef', // 表示注入的ref选项,以便获取元素
    attrs: { // 设置标签上的属性
      'data-id': 'my-id'
    },
    on: { // 绑定事件
      click: this.clickEvent
    },
    // 仅用于组件,用于监听原生事件,而不是组件内部使用
    // `vm.$emit` 触发的事件。
    // nativeOn: {
    //   click: this.clickEvent
    // },
    domProps: {
      innerHTML: '这个是标题',
      value: 'inputValue' // 这个是输入框中的value值
    }
  })
}

 第三个参数可以实现多插槽

render (h) {
  return h('div', {
    staticClass: 'abc'
  }, [this.$slots.title, this.$slots.content])
}
render (h) {
  return h('div', [
    {
      tag: 'div',
      children: [h('span', [this.$slots.title, this.$slots.content])]
    }
  ])
}

 注意:通常来讲,在虚拟dom中不使用指令,元素的构成可以使用js进行拼接

 8、属性传值过程中,批量传值的方法

 如果存在多重组件嵌套的时候,父组件通过传值的方式向子组件传递属性,但是子组件没有使用,需要全部传递给孙组件,那么这个时候就可以使用以下方法进行传值

父组件

<template>
  <div class="container">
    <content-item name="aaa" age="20" sex="1" @changeEvent="changeEvent"></content-item>
  </div>
</template>
<script>
import contentItem from './contentItem'
export default {
  name: 'home',
  components: {
    contentItem
  },
  methods: {
    changeEvent () {
      console.log('this is parent changeEvent', arguments)
    }
  }
}
</script>
<style lang="less" scoped></style>

注意:如果父组件传值给子组件,但子组件没有接收的话,那么这些属性会显示在节点树上,如果接收了则不会显示在节点树上,这时候如果不需要其显示在节点树上,那么就可以在子组件中添加属性 inheritAttrs: false,这样就会显示在节点树上

子组件

<template>
<div>
  <span>this is conentItem</span>
  <item v-bind="{...$attrs, 'haha': 'ok'}" v-on="$listeners"></item> <!--这样就可以在子组件不接收的情况下传递给孙组件-->
<!--  这种情况也可以传递事件-->
</div>
</template>
<script>
import item from './item'
export default {
  name: 'contentItem',
  components: {
    item
  },
  inheritAttrs: false // 不显示在节点树上
}
</script>
<style lang="less" scoped></style>

注意:这种情况记得使用v-bind与v-on,以及关键字$attrs, $listeners

孙组件

<template>
  <div>
    <div @click="changeEvent">{{$attrs}}</div>
  </div>
</template>
<script>
export default {
  name: 'item',
  methods: {
    changeEvent () {
      console.log('ok')
      this.$emit('changeEvent', 'haha') // 这样直接这种就可以传递值到根组件上
      console.log(this.$listeners) // 也可以通过这种方式访问
    }
  }
}
</script>
<style lang="less" scoped></style>

注意:孙组件里的$attrs是表示父组件还没有使用的属性,不包含已使用的属性 ,相当于用一个少一个

9、v-model实现多选的情况

  v-model如果遇到checkbox需要进行多选的时候,这个时候把v-model对应的data里的值改成数组,就可以实现多值的选择

<template>
  <div class="container">
    <label><input type="checkbox" v-model="checkList" value="语文">语文</label>
    <label><input type="checkbox" v-model="checkList" value="英语">英语</label>
    <label><input type="checkbox" v-model="checkList" value="数学">数学</label>
    <label><input type="checkbox" v-model="checkList" value="历史">历史</label>
    <ul>
      <li v-for="val of checkList" :key="val">{{val}}</li>
    </ul>
  </div>
</template>
<script>
export default {
  name: 'Home',
  data () {
    return {
      checkList: []
    }
  }
}
</script>

 10、自定义指令的使用

自定义指令有分为全局指令与局部指令,全局指令注册完成后,那么就可以在整个项目中使用, 局部指令则只在指定的页面或者组件中使用

入门案例

import Vue from 'vue'
export const install = vue => {
  vue.directive('bill', (el, binding, vnode) => {
    console.log(el, binding, vnode)
  })
}

Vue.use(install) // 通过use来进行全局指令的注册

自定义指令的生命周期函数有:

  • bind:    只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:   被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update:     所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:     只调用一次,指令与元素解绑时调用。

声明的两种方式

  // vue.directive('bill', {
  //   bind () {
  //     console.log('bind', arguments)
  //   },
  //   inserted () {
  //     console.log('inserted', arguments)
  //   },
  //   update () {
  //     console.log('update', arguments)
  //   },
  //   componentUpdated () {
  //     console.log('componentUpdated', arguments)
  //   },
  //   unbind () {
  //     console.log('unbind', arguments)
  //   }
  // })

vue.directive('bill', (...rest) => { console.log(rest) })

 注意:如果自定义指令中有一个函数的时候,那么这个函数相当于bind使用

11、computed与methods的区别

computed与methods的区别在于,前者在基于Object.defineProperty实现在,也就是当节点数据刷新的时候,computed里的值如果有发生变化,那么对应的函数会被调用,如果没有变化,会调用缓存里的数据,则不会发生变化 ,而后者无论是否变化,当节点刷新时都会被调用

 

posted on 2020-10-19 23:50  even_blogs  阅读(182)  评论(0编辑  收藏  举报