vue3-jd-h5

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电商平台!

Stars
868
Committers
4

vue3-jd-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

https://user-images.githubusercontent.com/37830362/173991179-71272ccb-bf69-441f-8f15-46e8da403d2a.mov

vue3

  1. , clone
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
  1. vue-next

  2. IDEA npm install,;

  3. IDEA npm run dev,;

  4. IDEA npm run dll:build,,

node v16.20.2

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);

Composition API

vue vue-cli vue-cli-plugin-vue-next

# in an existing Vue CLI project
vue add vue-next

UI @vue/composition-api vue3

Vue 3.0 Composition-API

setup

setup() vue3 2.x created, vue3 Composition API ,setup 2.x beforeCreate created

vue2.x vue3
beforeCreate setup()
created 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}`);
});
  1. 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 unwrap

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

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

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

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

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

watch(source, cb, options?)

watchAPI 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) => {
    /* ... */
  }
);

watch

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,
  }
);

watchwatch

// watch watch
const stopWatch = watch(
  [work, address], // ref
  ([work, addres], [oldwork, oldaddres]) => {
    //......
  },
  {
    lazy: true,
  }
);

// workaddress
stopWatch();

watch

<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

  1. Mixins

  2. (Higher-order Components, aka HOCs)

  3. Renderless Components ( scoped slots /

  4. mixin mixinHOC

  5. mixin HOC props

  6. 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