Based on vue3.x,vite5.x, vant3.0.0, vue-router v4.0.0-0, vuex^4.0.0-0, vue-cli3, mockjs, imitating Jingdong Taobao, mobile H5 e-commerce platform! 基于vue3.0.0 ,vant3.0.0,vue-router v4.0.0-0, vuex^4.0.0-0,vue-cli3,mockjs,仿京东淘宝的,移动端H5电商平台!
vue3-jd-h5
H5 Vue 3.0.0 + Vant 3.0.0
vue2.6demomockjs
master
PR issue
clone fork start
2024 Vue3.x ,Vite5.x, Vant,TypeScript vue3-vite-vant-ts
git clone https://github.com/GitHubGanKai/vue-jd-h5.git
gankaideMacBook-Pro:vue-jd-h5 gankai$ git branch -a
demo
vue-next
dev
feature
gh-pages
* master
remotes/origin/HEAD -> origin/master
remotes/origin/demo
remotes/origin/vue-next
remotes/origin/dev
remotes/origin/feature
remotes/origin/gh-pages
remotes/origin/master
vue-next
IDEA npm install,;
IDEA npm run dev
,;
IDEA npm run dll:build
,,
clone vue3
npm
npm install
yarn
yarn;
CDN
<script src="https://unpkg.com/vue@next"></script>
main.js
import Vue from "vue";
import VueCompositionApi from "@vue/composition-api";
Vue.use(VueCompositionApi);
vue vue-cli vue-cli-plugin-vue-next
# in an existing Vue CLI project
vue add vue-next
UI @vue/composition-api
vue3
setup()
vue3 2.x created
, vue3 Composition API
,setup 2.x beforeCreate created
vue2.x | vue3 |
---|---|
setup() | |
setup() | |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeDestroy | onBeforeUnmount |
destroyed | onUnmounted |
errorCaptured | onErrorCaptured |
2.x Composition API debug hooks
onRenderTracked
onRenderTriggered
DebuggerEvent``onTrack``onTrigger
export default {
onRenderTriggered(e) {
debugger;
// inspect which dependency is causing the component to re-render
},
};
provide``inject
2.x provide/inject``setup()
import { provide, inject } from "@vue/composition-api";
const ThemeSymbol = Symbol();
const Ancestor = {
setup() {
provide(ThemeSymbol, "dark");
},
};
const Descendent = {
setup() {
const theme = inject(ThemeSymbol, "light" /* optional default value */);
return {
theme,
};
},
};
inject
Provide inject``undefined
ref
//
const themeRef = ref("dark");
provide(ThemeSymbol, themeRef);
//
const theme = inject(ThemeSymbol, ref("light"));
watchEffect(() => {
console.log(`theme set to: ${theme.value}`);
});
setup
2 initProps
****setupContext
attrs: Object; // vue 2.x this.$attrs
emit: (); // this.$emit()
isServer: false; //
listeners: Object; // vue2.xthis.$listeners
parent: VueComponent; // vue2.xthis.$parent
refs: Object; // vue2.xthis.$refs
root: Vue; // rootmain.jsnewVue()this
slots: {
} // vue2.xthis.$slots
ssrContext: {
} //
**** setup()
this``this
vue ( main.js new vue )
getCurrentInstance
api,
import { computed, getCurrentInstance } from "@vue/composition-api";
export default {
name: "svg-icon",
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String
}
},
setup(initProps,setupContext) {
const { ctx } = getCurrentInstance();
const iconName = computed(() => {
return `#icon-${initProps.iconClass}`;
});
const svgClass = computed(() => {
if (initProps.className) {
return "svg-icon " + initProps.className;
} else {
return "svg-icon";
}
});
return {
iconName,
svgClass
};
}
};
</script>
ref()
********ref()
RefImpl .value
setup``.value``<template>
****.value
import { ref } from '@vue/composition-api'
setup() {
const active = ref("");
const timeData = ref(36000000);
console.log('===>',timeData.value)
return {
active,
timeData
}
}
<template>
<p>{{active}}</p>
<p>{{timeData}}</p>
</template>
Array``ref
**** Array
ref
:
const state = reactive({
list: [ref(0)],
});
// , `.value`
state.list[0].value === 0; // true
state.list.push(ref(1));
// , `.value`
state.list[1].value === 1; // true
DOM swiper
DOM,
<div class="swiper-cls">
<swiper :options="swiperOption" ref="mySwiper">
<swiper-slide v-for="(img ,index) in tabImgs.value" :key="index">
<img class="slide_img" @click="handleClick(img.linkUrl)" :src="img.imgUrl" />
</swiper-slide>
</swiper>
</div>
setup``const mySwiper = ref(null);
vue2.x this.$refs.mySwiper
DOM ref``mySwiper``template``ref
import { ref, onMounted } from "@vue/composition-api";
setup(props, { attrs, slots, parent, root, emit, refs }) {
const mySwiper = ref(null);
onMounted(() => {
// mySwiper.value DOM
// vue2.xrefs.mySwiper mySwiper.value DOM
mySwiper.value.swiper.slideTo(3, 1000, false);
});
return {
mySwiper
}
}
reactive()
vue 2.x
Vue.observable()
vue 3.x
reactive()
Observer``ref
****reactive
reactive``Array``Array``value
<script>
// aip
import { ref, reactive } from "@vue/composition-api";
export default {
name: "home",
setup(props, { attrs, slots, parent, root, emit, refs }) {
const active = ref("");
const timeData = ref(36000000);
// tabImgs
const tabImgs = reactive({
value: []
});
const ball = reactive({
show: false,
el: ""
});
return {
active,
timeData,
tabImgs,
...toRefs(ball),
};
}
};
</script>
template``.value
<template>
<div class="swiper-cls">
<swiper :options="swiperOption" ref="mySwiper">
<swiper-slide v-for="(img ,index) in tabImgs.value" :key="index">
<img
class="slide_img"
@click="handleClick(img.linkUrl)"
:src="img.imgUrl"
/>
</swiper-slide>
</swiper>
</div>
</template>
isRef()
ref()
ref()
isRef
import { isRef } from '@vue/composition-api'
setup(){
const headerActive = ref(false);
// setup.value
const unwrapped = isRef(headerActive) ? headerActive.value : headerActive
return {}
}
toRefs
********ref
import { reactive,toRefs } from '@vue/composition-api'
setup(){
// ball Observer
const ball = reactive({
show: false,
el: ""
});
// ballToRefs ObjectballToRefsRefImpl
const ballToRefs = toRefs(ball)
// ref
ball.show = true
console.log(ballToRefs.show) // true
ballToRefs.show.value = false
console.log(ballToRefs.show) // false
return {
...ballToRefs // ballToRefstemplate
}
}
<template>
<div class="ballWrap">
<transition
@before-enter="beforeEnter"
@enter="enter"
@afterEnter="afterEnter"
>
<!-- show-->
<div class="ball" v-if="show">
<li class="inner">
<span class="cubeic-add" @click="addToCart($event,item)">
<svg-icon class="add-icon" icon-class="add"></svg-icon>
</span>
</li>
</div>
</transition>
</div>
</template>
computed``getter``getter``ref
import { computed } from "@vue/composition-api";
const count = ref(1);
// computed
const plusOne = computed(() => count.value + 1);
console.log(plusOne.value); // 2
plusOne.value++; // plusOne
get``set``ref
const count = ref(1);
// computed
const plusOne = computed({
get: () => count.value + 1,
set: (val) => {
count.value = val - 1;
},
});
plusOne.value = 1;
console.log(count.value); // 0
watch(source, cb, options?)
watch
API 2.x this.$watch``watch
getter ref
// watching a getter
const state = reactive({ count: 0 });
watch(
() => state.count, // getter
(count, prevCount, onCleanup) => {
/* ... */
}
);
// directly watching a ref
const count = ref(0);
watch(
count, // ref
(count, prevCount, onCleanup) => {
/* ... */
}
);
const me = reactive({ age: 24, name: "gk" });
// reactive
watch(
[() => me.age, () => me.name], // reactivegetter
([age, name], [oldAge, oldName]) => {
console.log(age); // age
console.log(name); // name
console.log(oldAge); // age
console.log(oldName); // name
},
// options
{
lazy: true, // watch lazytrue
}
);
setInterval(() => {
me.age++;
me.name = "oldMe";
}, 7000000);
// ref
const work = ref("web");
const addres = ref("sz");
watch(
[work, address], // ref
([work, addres], [oldwork, oldaddres]) => {
//......
},
{
lazy: true,
}
);
watch
watch
// watch watch
const stopWatch = watch(
[work, address], // ref
([work, addres], [oldwork, oldaddres]) => {
//......
},
{
lazy: true,
}
);
// workaddress
stopWatch();
<div class="search-con">
<svg-icon class="search-icon" icon-class="search"></svg-icon>
<input v-focus placeholder="" v-model="searchText" />
</div>
setup(props, { attrs, slots, parent, root, emit, refs }){
const CancelToken = root.$http.CancelToken
const source = CancelToken.source()
// searchText
const searchText = ref('')
//
const getSearchResult = searchText => {
root.$http.post("http://test.happymmall.com/search",{text:searchText}, {
cancelToken: source.token
}).then(res => {
// .....
});
return source.cancel
}
// watch
watch(
searchText,
(searchText, oldSearchText, onCleanup) => {
// axiosaxios cancel
const cancel = getSearchResult(searchText)
// watch
onCleanup(cancel)
},
// watch
{ lazy: true }
)
return {
searchText
}
}
vue3 Composition API API Vue2.x @vue/composition-api Vue2.x Vue 2.x API
Mixins
(Higher-order Components, aka HOCs)
Renderless Components ( scoped slots /
mixin mixinHOC
mixin HOC props
HOC Renderless Components
vue3 Composition API``API
Vue2.x
@vue/composition-api
Vue3.x
ui vue add vue-next
Vue3.x
export default``Vue.xxx()
vue3 Vue3.x
vue3
bilibiliEvan You vue3 beta ******** API