原文链接: 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>