• vue API 知识点(1) --- 全局 API 总结


    1.Vue.extend(options)

      构造器,创建一个 子类 。参数是一个包含组件选项的对象

      data 选项是特例,需要注意 在 Vue.extend() 中它必须是一个函数,

      <div id="test"></div>
      // 创建构造器
      let MyTest = Vue.extend({
        template: '<p>{{name}} {{age}}</p>',
        data(){
          return {
            name: 'zhangning',
            age: '24'
          }
        }
      })

      创建 MyTest 实例,并挂载到一个元素上

      new MyTest().$mount('#test')

      最终结果如下

      <p>zhangning 24</p>

      上面 extend 创建的是 Vue 构造器,而不是一个具体的组件实例,所以不能够通过 new Vue({components: testExtend}) 来直接使用,需要通过 new MyTest().$mount('#test') 来挂载到指定的元素上

      *调用 Vue.extend() 创建的是一个组件构造器

      *通常在创建组件构造器时,传入 template 代表我们自定义组件的模板

      *该模板就是在使用到组件的地方,要显示的 HTML 代码

      *但是,这种写法在vue2之后几乎就不再使用了,都是直接使用语法糖,不过我们还是要学习的,为后面的学习打下基础

      现在我们通常不使用 Vue.extend() 来注册组件了,使用语法糖的写法,直接把对象放在 Vue.component() 来注册组件,可以看第 7 个API进行学习

        调用Vue.component() 是将刚才的组件构造器注册为一个组件,并且给它起一个组件的标签名字

        所以需要传递两个参数:1.注册组件的标签名 2.组件构造器

      组件必须挂在在某个Vue实例下,否则不会生效

      示例:封装一个全局提示组件

      首先创建一个 message.vue 组件

      <template>
        <transition>
          <div v-show='show'>{{message}}</div>
        </transition>
      </template>
    
      <script>
        export default{
          data(){
            return {
              show: false,
              message: ''
            }
          }
        }
      </script>
    
      <style scoped>
        div {
          padding: 10px;
          color: #ddd;
          background: red;
          text-align: center;
          position: fixed;
          top: 30%;
          left: 50%;
        }   </style>

      然后在 main.js 中配置

      import Message from './components/Message.vue'
    
      const MessageM = {
        install: function(Vue) {
          // 创建一个 vue 的子类组件
          const MessageConstructor = Vue.extend(Message)
          // 创建子类实例,并挂载到动态创建的元素上,并将元素添加到全局结构中
          const inst = new MessageConstructor().$mount(document.createElement('div'))
          document.body.appendChild(inst.$el)
          // 在 vue 原型链上注册方法,控制组件
          Vue.prototype.$message = (msg, time = 1000) => {
            inst.message = msg
            inst.show = true
            setTimeout((
              inst.show = false
            ), time)
          }
        }
      }
      Vue.use(MessageM)

      在组件内使用

      this.$message('消息提示')

      以上就是一个简单的全局消息提示

    2.Vue.nextTick

      在写词DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM

    <template>
      <div>
        <div ref='valRef'>{{ val }}</div>
        <div>{{ val1 }}</div>
        <div>{{ val2 }}</div>
        <div>{{ val3 }}</div>
        <el-button type="primary" @click.once='handleClick'>改变val</el-button>
      </div>
    </template>
    
    <script>
    export default {
      name: 'index',
      data() {
        return {
          val: 'zhangning',
          val1: '',
          val2: '',
          val3: ''
        }
      },
      methods: {
        // 点击按钮时,val1和val3获取的是初次加载时候的val的值,因为vue的DOM是异步加载,
        // 而使用了nextTick的val2的值在msg改变之后,就立刻获取到了val更新之后的值
        handleClick() {
          this.val = '我已改变';
          // DOM 未更新,获取不到最新的dom
          this.val1 = this.$refs.valRef.innerHTML;
          this.$nextTick(() => {
            // DOM 已更新,获取最新的dom
            this.val2 = this.$refs.valRef.innerHTML;
          })
          // DOM 未更新,获取不到最新的dom
          this.val3 = this.refs.valRef.innerHTML;
        }
      }
    }
    </script>

      官方给出的解释和例子(异步更新队列)

      Vue 在更新 DOM 时是异步执行的。只要监听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更,如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然而在下一个的事件循环 tick 中,Vue 刷新队列并执行实际(已去重)工作。Vue 在内部对异步队列尝试使用原生的Promise.then、MutationObserver 和 setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替。

      例如,当设置 vm.someData = 'newVlaue',该组件不会立即重新渲染,当刷新队列时,组件会在下一个事件循环 tick 中更新。多数情况我们不需要关心这个过程,但是如果想基于更新后的 DOM 状态做点什么,这就有点棘手。虽然Vue鼓励我们使用数据驱动的方式思考,避免直接接触 DOM ,但是有时我们必须要这么做。为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新完成之后被调用。例如

    <div id="example">{{message}}</div>
    var vm = new Vue({
      el: '#example',
      data: {
        message: '123'
      }
    })
    vm.message = 'new message' // 更改数据
    vm.$el.textContent === 'new message' // false
    Vue.nextTick(function () {
      vm.$el.textContent === 'new message' // true
    })

    在组件内使用 vm.$nextTick() 实例方法特别方便,因为它不需要全局 Vue ,并且回调函数中的 this 将自动绑定到当前的 Vue 实例上

    Vue.component('example', {
      template: '<span>{{ message }}</span>',
      data: function () {
        return {
          message: '未更新'
        }
      },
      methods: {
        updateMessage: function () {
          this.message = '已更新'
          console.log(this.$el.textContent) // => '未更新'
          this.$nextTick(function () {
            console.log(this.$el.textContent) // => '已更新'
          })
        }
      }
    })

      因为 $nextTick() 返回一个 Promise 对象,所以你可以使用新的语法 async/await 完成相同的事情

    methods: {
      updateMessage: async function () {
        this.message = '已更新'
        console.log(this.$el.textContent) // => '未更新'
        await this.$nextTick()
        console.log(this.$el.textContent) // => '已更新'
      }
    }

    3.Vue.set

      Vue.set(target, key, value)

        target:要更改的数据源(可以是对象或者数组)

        key:要更改的具体数据

        value:重新赋的值

      由于 js 的限制,Vue 不能检测出数据的改变,但是通过这种方法修改数组中的数据,就会检测到数组的改变,是响应式的

      用法:向响应式对象中添加一个 property, 并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 arr[1] = 110)

    export default {
      name: 'index',
      data() {
        return {
          arr: [1,2,3]
        }
      },
      methods: {
        // 修改 arr[1] 变为 200
        handleChange(){
          this.$set(this.arr, 1, 200);// arr: [1, 200, 3]
        },
        // arr 数组添加元素 600
        handleAddArr(){
          this.$set(this.arr, this.arr.length, 600);
        }
      }
    }

    4.Vue.delete()

      Vue.delete(target, key, value)

        target:要删除的数据源(可以是对象或者数组)

        key:要删除的具体数据

      用法:删除对象的 property。如果对象是响应式的,确保删除能触发更新视图。这个方法主要用于避开 Vue 不能检测到 property 被删除的限制,虽然很少使用,但直到要会用

    export default {
      name: 'index',
      data() {
        return {
          zhangning: {
            height: 187,
            name: 'zhangning',
            sex: '男'
          }
        }
      },
      methods: {
        // 删除 name
        handleDeleteName() {
          this.$set(this.zhangning, 'name');
        }
      }
    }

    5.Vue.directive()

      Vue.directive(string, Function | Object)

      注册或获取全局指令

      声明周期:

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

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

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

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

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

      钩子函数参数

        el:指令所绑定的元素,可以用来直接操作 DOM

        binding:一个对象,包含以下 property:

          name:指令名,不包括 v- 前缀

          value:指令的绑定值,例如:v-my-directive='1+1'中,绑定值为 2

          oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用,无论值是否改变都可用

          expression:字符串形式的指令表达式。例如 v-my-directive='1+1' 中,表达式为 ‘1+1’

          arg:传给指令的参数,可选。例如 v-my-directive: foo 中,参数为 'foo'

          modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 {foo: true, bar: true}

        vnode:Vue 编译生成的虚拟节点

        oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用

        <div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
        Vue.directive('demo', {
          bind: function (el, binding, vnode) {
            var s = JSON.stringify
            el.innerHTML =
            'name: '       + s(binding.name) + '<br>' +
            'value: '      + s(binding.value) + '<br>' +
            'expression: ' + s(binding.expression) + '<br>' +
            'argument: '   + s(binding.arg) + '<br>' +
            'modifiers: '  + s(binding.modifiers) + '<br>' +
            'vnode keys: ' + Object.keys(vnode).join(', ')
          }
        })
    
        new Vue({
          el: '#hook-arguments-example',
          data: {
            message: 'hello!'
          }
        })

        页面展示效果如下

        name: 'demo'
        value: 'hello!'
        expression: 'message'
        argument: 'foo'
        modifiers: {a: true, b: true}
        vnode keys: tag,data,children,text,elm,ns,context...

      动态指令参数,指令的参数可以是动态的,例如,在 v-mydirective:[argument]='value'中,argument 参数可以根据组件数据进行更新,这可以让我们的自定义指令灵活使用。

      创建一个自定义指令,把元素固定在距离顶部 200px 的位置

      <div id="test">
        <p>Scroll down the page</p>
        <p v-pin="200">距离顶部200px</p>
      </div>
      Vue.directive('pin', {
        bind: function(el, binding, vnode){
          el.style.position = 'fixed'
          el.style.top = binding.value + 'px'
        } 
      })
    
      new Vue({
        el: '#test' 
      })

      当我们需要固定在左侧而不是顶部的时候,这时候我们就需要用到动态指令

      <div id="test">
        <p>Scroll down the page</p>
        <p v-pin:[direction]="200">距离顶部200px</p>
      </div>
      Vue.directive('pin', {
        bind: function(el, binding, vnode){
          el.style.position = 'fixed'
          let s = binding.arg == 'left' ? 'left' : 'top'
          el.style[s] = binding.value + 'px'
        } 
      })
    
      new Vue({
        el: '#test' ,
        data(){
          return {
            direction: 'left'
          }
        }
      })

        以上这个自定义指令现在的灵活性就足以支持一些不同的用例了

      函数简写

        很多时候,我们想在 bind 和 update 时触发相同行为,而不关心其他的钩子。

        Vue.directive('pin', function(el, binding){
          el.style.top = binding.value + 'px'
        })

        如果指令需要多个值,可以传入 js 对象,指令函数能够接收所有合法的 js 表达式

        <div v-demo="{ color: 'red', text: 'hello'}"></div>
        Vue.directive('demo', function(el, binding){
          console.log(binding.value.color) // red
          console.log(binding.value.text) // hello
        })

      在项目中使用的案例

        通过权限控制每个页面的按钮,

      先定义一个 directive.js,写上全局指令 

    import Vue from 'vue';
    import store from './store';
    
    Vue.directive('permission', {
      inserted: (el, binding) => {
        if (store.getters.userButtons.length) {
          const buttons = store.getters.userButtons;
          if (buttons.indexOf(binding.value) < 0) el.parentNode.removeChild(el);
        } else {
          store.dispatch('getInfo').then(data => {
            const { buttons } = data.buttons;
            if (buttons.indexOf(binding.value) < 0) el.parentNode.removeChild(el);
          });
        }
      }
    });

      在 main.js 中全局引入

    import './directive.js'

      在 vue 组件中使用,判断有没有下载按钮权限

        <el-button
              round
              icon="el-icon-document"
              type="primary"
              v-permission="'SJML_SQXZ'"
              @click="applyForDownload"
        >下载文档</el-button>

    6.Vue.filter()

      定义过滤器,可被用于常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式,过滤器应该被添加在 js 表达式的尾部,由管道符号指示:'|'

      <!-- 在双花括号中 -->
      {{ message | capitalize }}
      
    <!-- 在 `v-bind` 中 -->   <div v-bind:id="rawId | formatId"></div>

      在一个组件的选项中定义本地过滤器

      filters: {
        capitalize: function (value) {
          if (!value) return ''
          value = value.toString()
          return value.charAt(0).toUpperCase() + value.slice(1)
        }
      }

      在创建 Vue 实例之前全局定义过滤器

      Vue.filter('capitalize', function() {
        if (!value) return ''
        value = value.toString()
        return value.charAt(0).toUpperCase() + value.slice(1)
      })
      new Vue({
        // ...
      })

      注意:当全局过滤器和局部过滤器重名时,会采用局部过滤器

      过滤器函数总接收表达式的值作为第一个参数

      过滤器可以串联:

        {{ message | filterA | filterB }}

      这个例子中,filterA 被定义为接收单个参数的过滤器函数,表达式 message 的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数 filterB,将 filterA 的结果传递给 filterB 中。

      过滤器时 js 函数,因此可以接收参数

        {{ message | filterA('arg1', arg2) }}

      这个例子,filterA 被定义为接收三个参数的过滤器函数,其中 message 的值作为第一个参数,普通字符串 'arg1' 作为第二个参数, arg2 作为第三个参数

      在项目中使用的案例

      先定义一个 filters.js 

    export { formatBoolean, formatDate, formatNum, formatStatus };
    
    // 布尔值
    function formatBoolean(value) {
      return value ? "是" : "否";
    }
    
    // 状态
    function formatStatus(value) {
      return value ? "成功" : "失败";
    }
    // 时间戳转换
    function formatDate(value) {
      let date = new Date(parseInt(value));
      let Y = date.getFullYear();
      let M =
        date.getMonth() + 1 < 10
          ? "0" + (date.getMonth() + 1)
          : date.getMonth() + 1;
      // let D = date.getDate();
      let D = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
      let h = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
      let m = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
      let s = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
      return Y + "." + M + "." + D + " " + h + ":" + m + ":" + s;
    }
    
    // 数值加逗号
    function formatNum(num) {
      num = (num || 0).toString();
      let result = "";
      while (num.length > 3) {
        result = "," + num.slice(-3) + result;
        num = num.slice(0, num.length - 3);
      }
      if (num) {
        result = num + result;
      }
      return result;
    }

      然后在 main.js 中进行全局引入

      import * as filters from './filters.js'
      Object.keys(filters).forEach(item => {
        Vue.filter(item, filters[item])
      })
      
    // 这里讲一下 Object.keys() 方法,表示给定对象的所有可枚举属性的字符串数组   let zn = {name: 'zhangning', age: '24', height: '187'}   Object.keys(zn);// ['name', 'age', 'height'] 返回可枚举属性组成的数组   // 处理数组,返回索引值数组   let arr = [100, 200, 300, 400, 500]   Object.keys(arr);// ['0', '1', '2', '3', '4'] 返回索引值字符串组成的数组   // 处理字符串,返回索引值数组   let str = 'zhang';   Object.keys(str);// ['0', '1', '2', '3', '4']   // 常用技巧   let zn = {name: 'zhangning', age: '25', address: '合肥', getName: function()}   Object.keys(person).map(item => {     person[item] // 获取到属性对应的值,做一些处理   })

    7.Vue.component()

      // 定义一个名为 button-counter 的新组件
      Vue.component('button-counter', {
        data: function () {
          return {
            count: 0
          }
        },
        template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
      })

      data 必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝,如果不是一个函数,就会影响到组件所有实例

      在项目中自定义全局组件案例

      首先创建一个组件 download.vue

      然后创建一个 download.js,在 js 中引入组件

      // 引入组件
      import DLFLoading from './index.vue';
      // 自定义组件对象
      const DownloadDialog = {
        // install 是默认的方法。当外界在 use 这个组件的时候,就会调用本身的 install 方法,同时传一个 Vue 这个类的参数
        install: function(Vue) {
          // Vue.component() 与正常的全局注册组件用法相同,可以理解为通过 install 和 Vue.use()函数注册了全局组件
          Vue.component('DownloadDialog', DLFLoading);
        }
      }
      // 导出
      export default DownloadDialog;

      接着在 main.js 中全局引入组件

      // 全局引入自定义下载 loading
      import DownloadDialog from '@/components/DownloadDialog/download.js';
      Vue.use(DownloadDialog);

      最后在项目中直接就可以使用

      <DownloadDialog
          @cancelDownload="cancelDownload"
          :downloadOver="downloadOver"
          :downloadLoading="downloadLoading"
        ></DownloadDialog>

    8.Vue.use()

      安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。

      该方法需要在 new Vue() 之前被调用

      当 install 方法被同一个插件多次调用,插件将只会被安装一次。

      插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制 一般有以下几种

        1.添加全局方法或者property

        2.添加全局资源:指令/过滤器/过渡等

        3.通过全局混入来添加一些组件选项

        4.添加 Vue 实例方法,通过把他们添加到 Vue.prototype 上实现

        5.一个库,提供自己的 api,同时提供上面提到的一个或多个功能

      使用插件

        通过全局方法 Vue.use() 使用插件。它需要在你调用 new Vue() 启动应用之前完成

        // 调用 MyPlugin.install(Vue)
        Vue.use(MyPlugin)
        new Vue({
    
          // ...组件选项
        })

        也可以传入一个可选的选项对象

       Vue.use(MyPlugin, {someOption: true})

        Vue.use 会自动阻止多次注册相同插件,即使多次调用也只会注册一次该插件

    9.Vue.mixin()

      全局注册一个混入,影响注册之后所有创建的每个 Vue 实例。插件作者可以使用混入,向组件注入自定义的行为(官方不推荐使用)

      官网全局混入案例。混入也可以进行全局注册,使用时格外小心,一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。使用恰当时,它可以用来自定义选项注入处理逻辑。

      // 为自定义的选项 myOption 注入一个处理器

      Vue.mixin({
        created: function(){
          var myOption = this.$options.myOption
          if(myOption) {
            console.log(myOption)
          }
        }
      })
    
      new Vue({
        myOption: 'zhangning'
      })
      // => 'zhangning'

      注意:要谨慎使用全局混入,因为它影响每个单独创建的 Vue 实例(包括第三方组件)。大多数情况下,之应当应用于自定义选项,就像上面实例一样,推荐将其作为插件发布,以避免重复应用混入

      使用案例

      定义一个 mixin.js

      let MiXin = {
        data(){
          return {
            name: 'zhangning'
          }
        },
        created(){
          console.log('这是mixin中的name', this.name)
        },
        mounted(){},
        methods: {}
      }
      export default MiXin
      // 全局引入
    
      import mixin from './mixin'
      Vue.mixin(mixin)
    
      // 在 vue 组件中局部引入
      import '@/mixin'
      export default {
        mixins: [mixin]
      }

      混入和组件的合并注意事项

      1.数据对象 data 在内部进行递归合并,在和组件的数据发生冲突时以组件数据优先

      2.同名钩子函数(created,mounted)将混合为一个数组,都将被调用。另外混入对象的钩子将在组件自身钩子之前调用

      3.值为对象的选项(methods,components,directives)将被混合为同一个对象,两个对象键名冲突时,去组件对象的键值对

    10.Vue.compile() -- 模板渲染

      将一个模板字符串编译成 render 函数。旨在完整版时可用

      let res = Vue.compile('<div><span>{{ massage }}</span></div>')

      new Vue({

        data: {

          message: 'hello'

        },

        render: res.render,

        staticRenderFns: res.staticRenderFns

      })

      以上是官网给的一个小实例。

      以后深入理解之后,再回来更新

    11.Vue.observable() -- 可用于组件间共享数据

      让一个对象可响应,Vue 内部会用它来处理 data 函数返回的对象。

      返回的对象可以直接用于渲染函数和计算属性内,并且会在发生变更时出发相应的更新。

      处理简单的跨组件共享数据状态的问题,可以说是个精简的 vuex

      示例

      创建store.js

      import Vue from 'vue'
      export const store = Vue.observable({num: 0})
      export const mutations = {
        setNum (num) {
          store.num = num
        }
      }

      在组件中使用(所有的说明都没有举例子来的实在,理解的更快)

      <template>
        <div>
          <span>选择数量</span>
          <button @click="setNum(num + 1)"> + </button>
          <span>count</span>
          <button @click="setNum(num - 1)"> - </button>
        </div>
      </template>
    
      <script>
        import { store, mutations } from '@/store/store' 
        export default {
          name: 'numIndex',
          computed: {
            count() {
              return store.num
            }
          },
          methods: {
            setNum: mutations.setNum
          }
        }
      </script>

    12.Vue.version()

      提供字符串形式的 Vue 安装版本号。这对社区的插件和组件来说非常有用,你可以根据不同的版本号采取不同的策略

      let version = Number(Vue.version.split('.')[0])

      if (version == 2) {

      } else if (version == 1) {

      } else {}

      就是获取当前使用的 vue 版本号,原理就是读取 package.json 中的 version 字段

      以上就是 vue API 全局 API 的所有内容,

      宝剑锋从磨砺出,梅花香自苦寒来。

  • 相关阅读:
    给大家分享两款正在使用的reflector插件
    Win32汇编项目总结——猎杀潜航
    SQL Server2008 数据库误删除数据的恢复方法分享
    DataGridView中使DataGridViewComboBox可编辑
    将SQL数据库还原到某个时间点
    SQL Server 2005对海量数据处理
    SQL Server 2005对海量数据处理(1)
    ILDASM的使用
    QT简介以及配置
    Reflector插件介绍
  • 原文地址:https://www.cnblogs.com/zhangning187/p/vueapiqjapizj.html
Copyright © 2020-2023  润新知