侧边栏壁纸
博主头像
woku博主等级

成功的路上并不拥挤

  • 累计撰写 50 篇文章
  • 累计创建 13 个标签
  • 累计收到 3 条评论
vue

深入研究methods属性以及实例方法的挂载

woku
2022-03-07 / 0 评论 / 0 点赞 / 76 阅读 / 3,135 字

methods属性是什么

向组件实例添加方法,methods属性中是方法的集合

  • Vue创建实例时,会自动为methods里面的每个方法绑定当前实例this,保证在事件监听时,回调始终指向当前实例

    <body>
        <div id="app">
        </div>
        <script>
            const { createApp } = Vue
            const rootComp = {
                data() {
                    return {
                        a: 1,
                        b: 2
                    }
                },
                template: `
                   <h1>{{ a }}</h1>
                   <button @click="change(1)">改变</button>
                `,
                methods: {
                    change(num) {
                        // this指向当前实例,this.a就是当前实例数据a
                        this.a = num
                    }
                }
            }
            var app = createApp(rootComp)
            var vm = app.mount('#app')
            console.log(vm)
        </script>
    </body>
    

    要避免使用箭头函数,箭头函数中的this是指向外层环境,会阻止Vue正确绑定当前this实例

  • 模板中写 函数+()不是执行符号,是为了给方法传参的一个容器

    @click="change(1)"  经过vue转换为 @click="{ () => change(1) }"(类似于{ change.bind(this, 1) }返回一个新函数)
    
  • 不仅可以用来事件处理函数的绑定,还能直接在视图上直接被调用

                data() {
                    return {
                        a: 1,
                        b: 2
                    }
                },
                template: `
                   <h1>{{ a }}</h1>
                   <h2>{{ myNumberA() }} </h2>
                `,
                methods: {
                    myNumberA() {
                        return this.a
                    }
                }
    

    当a改变的时候,视图中myNumberA()也会变化

    模板直接调用的方法尽量避免副作用操作(尽量避免修改数据,依赖外部数据这些)

  • methods属性里面的方法直接挂载在vm实例上

    methos: {
      change() {
        ....
      },
      myNumberA() {
        ...
      }
    }
    

    在vm实例对象上,会直接有change,myNumberA两个方法。可以直接使用this.change来调用

lodash+vue的使用

lodash 常用JS工具库

<head>
    <script src="https://cdn.jsdelivr.net/npm/vue@3"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
</head>
<body>
    <div id="app">
    </div>
    <script>
        const { createApp } = Vue
        const rootComp = {
            data() {
                return {
                    list: []
                }
            },
            template: `
               <ul>
                  <li v-for="item of list" :key=item.targetId>
                    <img :src="item.imageUrl" width="300">
                    <p>{{item.typeTitle}}</p>
                  </li>
                </ul>
               <button @click="getData">获取数据</button>
            `,
            methods: {
                getData: _.debounce(async function() {
                    const { data } = await axios('https://api-music.heiyg.com/banner')
                    this.list = data.banners
                    console.log(data.banners)
                }, 1000)
            }
        }
        var app = createApp(rootComp)
        var vm = app.mount('#app')
        console.log(vm)
    </script>
</body>
    <script>
        const { createApp } = Vue
        const rootComp = {
            data() {
                return {
                    list: []
                }
            },
            template: `
               <ul>
                  <li v-for="item of list" :key=item.targetId>
                    <img :src="item.imageUrl" width="300">
                    <p>{{item.typeTitle}}</p>
                  </li>
                </ul>
               <button @click="getData">获取数据</button>
            `,
            created() {
                this.debounceGetData = _.debounce(this.getData, 1000)
            },
            unmounted() {
                this.debounceGetData.cancel()
            },
            methods: {
                async getData() {
                    const { data } = await axios('https://api-music.heiyg.com/banner')
                    this.list = data.banners
                    console.log(data.banners)
                }
            }
        }
        var app = createApp(rootComp)
        var vm = app.mount('#app')
        console.log(vm)
    </script>

实例方法挂载

        var Vue = (function() {
            function Vue(options) {
                this.$data = options.data()
                this.$methods = options.methods
                this._init(this)
            }
            Vue.prototype._init = function(vm) {
                initData(vm)
                initMethods(vm)
            }
            function initData(vm) {
                for (var key in vm.$data) {
                    (function(key) {
                        Object.defineProperty(vm, key, {
                            get(){
                                return vm.$data[key]
                            },
                            set(val) {
                                vm.$data[key] = val
                            }
                        })
                    })(key)
                }
            }
            function initMethods(vm) {
                for (var key in vm.$methods) {
                    vm[key] = vm.$methods[key]
                }
            }
            return Vue
        })()
        var vm = new Vue({
            data() {
                return {
                    a: 1,
                    b: 2
                }
            },
            methods: {
                setA(num) {
                    this.a += num
                }
            }
        })
        vm.setA(1)
        vm.setA(1)
        vm.setA(1)
        console.log(vm)

0

评论区