vue-fun-api 使用

原创
2019/10/19 16:54
阅读数 52

 

原文链接: vue-fun-api 使用

上一篇: js 防抖节流和rAF

下一篇: nuxt 使用scss

安装

https://github.com/vuejs/composition-api

npm install @vue/composition-api --save


import Vue from 'vue';
import VueCompositionApi from '@vue/composition-api';

Vue.use(VueCompositionApi);

 

简单使用

生命周期函数会覆盖而不是会按照顺序依次调用

<template>
  <div class="home">
    <h1>cnt:{{cnt}}</h1>
    <button @click="cnt++">add</button>

    <!-- 模板中会自动拆箱, 拿出r.value -->
    <h1>r:{{r}}</h1>
    <!-- js中使用r本身 -->
    <button @click="r++">add</button>
    <button @click="add">add</button>
  </div>
</template>

<script>
// import { createComponent } from '@vue/composition-api';
import { reactive, ref } from "@vue/composition-api";
import { toRefs } from "@vue/composition-api";

export default {
  // props 是传递的属性, ctx是当前vue实例, 取代之前的this
  setup(props, ctx) {
    console.log("setup");
    console.log("props", props);
    console.log("ctx", ctx);
    let r = ref(1);
    function add() {
      console.log("add", r);
      r.value++;
    }

    let state = reactive({
      cnt: 0,
      r,
      add
    });

    console.log(state);
    // return state;
    return toRefs(state);
  },
  created() {
    console.log("created");
  },

  created() {
    console.log("created2");
  },
  beforeCreate() {
    console.log("beforeCreate");
  },
  mounted() {
    console.log("mounted");
  }
};
</script>

计算属性

可以设置set和get, 控制cnt 和 less ,more 的数值关系永远相差1

<template>
  <div class="home">
    <h1>cnt:{{cnt}}</h1>
    <h1>more:{{more}}</h1>
    <h1>less:{{less}}</h1>
    <button @click="add">add</button>
    <button @click="sub">sub</button>
  </div>
</template>

<script>
import { ref } from "@vue/composition-api";
import { computed } from "@vue/composition-api";

export default {
  setup() {
    let cnt = ref(0);

    // 在setup作用域外修改需要使用value
    let more = computed(() => cnt.value + 1);

    let less = computed({
      get: () => {
        console.log("get");
        return cnt.value - 1;
      },
      set: v => {
        cnt.value = v + 1;
        console.log("set", v);
      }
    });

    function add() {
      console.log("add", cnt, less, more);
      cnt.value++;
    }

    function sub() {
      console.log("sub", cnt, less, more);
      less.value = less.value - 1;
    }
    return {
      cnt,
      more,
      less,
      add,
      sub
    };
  }
};
</script>

 

使用toRefs避免结构赋值后丢失响应式数据

<template>
  <div class="home">
    <h1>cnt:{{cnt}}</h1>
    <button @click="add">add</button>
  </div>
</template>

<script>
import { toRefs } from "@vue/composition-api";

export default {
  setup() {
    let state = reactive({
      cnt: 0
    });

    let add = () => state.cnt++;
    return {
      //   ...state,
      ...toRefs(state),
      add
    };
  }
};
</script>

 

使用provide和inject 跨组件传递数据

<template>
  <div>
    <h1>father</h1>
    <child />

    <h1>fa {{cnt}}</h1>
    <button @click="add">add</button>
  </div>
</template>

<script>
import child from "./son";
import { ref, provid, provide } from "@vue/composition-api";

export default {
  components: {
    child
  },
  setup() {
    let cnt = ref(0);
    function add() {
      cnt.value++;
    }

    provide('cnt',cnt)
    return {
      add,
      cnt
    };
  }
};
</script>

<style>
</style>
<template>
  <div>
    <h3>grandson</h3>

    <h3>grand: {{cnt}}</h3>
  </div>
</template>

<script>
import { inject } from "@vue/composition-api";

export default {
  setup() {
    let cnt = inject("cnt");
    return {
      cnt
    };
  }
};
</script>

<style>
</style>

 

使用ref 获取dom和组件实例

<template>
  <div ref="div">hello</div>
</template>

<script>
import { ref, onMounted } from "@vue/composition-api";

export default {
  setup() {
    // 通过这种方式可以获取dom和子组件
    let div = ref(null);

    onMounted(() => {
      setTimeout(() => {
        console.log(div);
        console.log(div.value);
        div.value.style.color = "red";
      }, 1000);
    });
    return {
      div
    };
  }
};
</script>

<style>
</style>

 

使用watch 监听数据变化

注意reactive和ref的写法稍有不同, 一个使用回调函数, 一个使用值

<template>
  <div class="home">
    <h1>cnt:{{cnt}}</h1>
    <button @click="add">add</button>
  </div>
</template>

<script>
import { reactive, watch, ref } from "@vue/composition-api";
import { toRefs } from "@vue/composition-api";

export default {
  setup() {
    let state = reactive({
      cnt: 0
    });

    let add = () => state.cnt++;

    watch(
      // 不能直接写state.cnt
      () => state.cnt,
      //   state.cnt,
      (val, oldVal) => {
        console.log("watch cnt", val, oldVal);
      },
      {
        // lazy用于控制是否在第一次初始化时执行watch
        lazy: true
      }
    );

    let r = ref(0);

    setInterval(() => {
      r.value++;
    }, 500);

    // 对于ref 直接使用值
    watch(
      r,
      //   () => r,
      (val, oldVal) => {
        console.log("watch r", val, oldVal);
      }
    );

    // 使用数组监听多个数据源, 使用返回值取消监听
    let stop = watch([() => state.cnt, r], (val, oldVal) => {
      console.log("watch []", val, oldVal);
    });

    setTimeout(() => {
        stop()
    }, 1000);
    watch(
      [() => state.cnt, r],
      ([cnt, r], [oldCnt, oldR]) => {
        console.log("watch []2", cnt, oldCnt, r, oldR);
      },
      {
        lazy: true
      }
    );

    return {
      //   ...state,
      ...toRefs(state),
      add
    };
  }
};
</script>

 

使用watch实现防抖功能

<template>
  <div class="home">
    <h1>{{msg}}</h1>
    <input type="text" v-model="msg" />
  </div>
</template>

<script>
// import { createComponent } from '@vue/composition-api';
import { reactive, watch, ref } from "@vue/composition-api";
import { toRefs } from "@vue/composition-api";

function asyncFun() {
  return setTimeout(() => {
    console.log("async");
  }, 1000);
}

export default {
  setup() {
    let msg = ref("");

    // cleanUp 是一个函数, 当watch被重复调用或者使用stop停止时调用
    watch(msg, (val, oldVal, cleanUp) => {
      console.log("msg");

      let tid = asyncFun();
      cleanUp(() => clearTimeout(tid));
    });

    return {
      msg
    };
  }
};
</script>

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部