All Projects → GitHubGanKai → Vue3 Jd H5

GitHubGanKai / Vue3 Jd H5

Licence: mit
🔥 Based on vue3.0.0, 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电商平台!

Projects that are alternatives of or similar to Vue3 Jd H5

Eleme
restructure..
Stars: ✭ 1,635 (+398.48%)
Mutual labels:  vue-cli, vuex, html5, vue-router, css3
Vue Meizi
vue最新实战项目,vue2 + vuex + webpack + es6 干货多多,新手福利
Stars: ✭ 1,476 (+350%)
Mutual labels:  vue-cli, vuex, html5, vue-router, css3
Vue Qq
🎨 Vue family bucket with socket.io and express/koa2 , create a web version of mobile QQ, supporting real-time group chat, real-time private chat, special care, shielding chat, smart IP geographic location, real-time display temperature and other QQ core functions
Stars: ✭ 861 (+162.5%)
Mutual labels:  vuex, html5, vue-router, css3
Vue Music Player
🎵Vue.js写一个音乐播放器+📖One(一个).A music player + One by Vue.js
Stars: ✭ 729 (+122.26%)
Mutual labels:  vuex, html5, vue-router, css3
Echat
基于Vue的点对点聊天项目
Stars: ✭ 130 (-60.37%)
Mutual labels:  vuex, html5, vue-router, css3
Vue Shiyanlou
😘基于vue2和vuex的复杂单页面应用,20+页面53个API(仿实验楼)✨✨
Stars: ✭ 342 (+4.27%)
Mutual labels:  vuex, html5, vue-router, css3
Vue Cnode
🔥Vue.js打造一个开源的CNode社区。CNode by Vue.js
Stars: ✭ 249 (-24.09%)
Mutual labels:  vuex, html5, vue-router, css3
Space Snake
A Desktop game built with Electron and Vue.js.
Stars: ✭ 289 (-11.89%)
Mutual labels:  vue-cli, vuex, vue-router
Github Ranking
🔍GitHub不同语言热门项目排行,Vue.js做页面展示
Stars: ✭ 160 (-51.22%)
Mutual labels:  vue-cli, html5, css3
Vue Zhihu Daily
🤓使用vue编写的练手的知乎日报WebApp(iOS版)
Stars: ✭ 285 (-13.11%)
Mutual labels:  vue-cli, vuex, vue-router
Lvyou
🎒Vue.js 初步进阶案例,路由懒加载,进入页面前登录判断,返回导航判断,RestAPI接口使用,组件封装,Vuex状态封装,keep-alive页面缓存等功能
Stars: ✭ 195 (-40.55%)
Mutual labels:  vue-cli, vuex, vue-router
Awesome Vue Cli3 Example
🦅 Awesome example for rapid Vue.js development using vue-cli3 .
Stars: ✭ 160 (-51.22%)
Mutual labels:  vue-cli, vuex, vue-router
Vuetify Todo Pwa
✔️ A simple Todo PWA built with Vue CLI 3 + Vuex + Vuetify.
Stars: ✭ 160 (-51.22%)
Mutual labels:  vue-cli, vuex, vue-router
Vue Objccn
🔥 Use Vue.js to develop a cross-platform full stack application / 用 Vue.js 开发的跨三端应用
Stars: ✭ 1,993 (+507.62%)
Mutual labels:  vue-cli, vuex, vue-router
Spring Boot Vue Bank
我,请始皇[打钱]是一个前后端分离的工具人系统,项目采用 SpringBoot+Go+Vue 开发,项目加入常见的企业级应用所涉及到的技术点,例如 Redis、RabbitMQ 等(主要是多用用工具多踩踩坑)。
Stars: ✭ 157 (-52.13%)
Mutual labels:  vue-cli, vuex, vue-router
Vue Cnode
🚀 基于vue3 function-based 构建cnode社区
Stars: ✭ 192 (-41.46%)
Mutual labels:  vue-cli, vuex, vue-router
Fantastic Admin
一款开箱即用的 Vue 中后台管理系统框架,基于ElementUI,兼容PC、移动端,vue-admin, vue-element-admin, vue后台
Stars: ✭ 153 (-53.35%)
Mutual labels:  vue-cli, vuex, vue-router
Vue2 Demo
Vue 基于 Genesis + TS + Vuex 实现的 SSR demo
Stars: ✭ 2,072 (+531.71%)
Mutual labels:  vue-cli, vuex, vue-router
Douban
Awesome douban DEMO created with Vue2.x + Vuex + Vue-router + Superagent
Stars: ✭ 2,324 (+608.54%)
Mutual labels:  vue-cli, vuex, vue-router
Vuemmerce
👉 Responsive ecommerce template 🛒 built with Vue.js and Nuxt.js
Stars: ✭ 223 (-32.01%)
Mutual labels:  vue-cli, vuex, vue-router

vue3-jd-h5

Twitter GitHub issues GitHub forks GitHub stars

English| 简体中文

Project Introduction

vue3-jd-h5 is an e-commerce H5 page front-end project, based on Vue 3.0.0 + Vant 3.0.0 implementation, mainly including homepage, category page, my page, shopping cart, etc. .

📖Local offline code vue2.6 in the branch demo , use mockjs data for development, please click for the renderings 🔗 Here

⚠️The master branch is the code of the online production environment, because part of the background interface has been hung up 😫, the actual effect may not be seen.

📌 There are still many shortcomings in this project. If you have partners who want to contribute to this, please send us a PR or issue;

🔑 This project is free and open source. If you have a partner who wants to carry out secondary development on a secondary basis, you can clone or fork the entire warehouse. If it can help you, I will be very happy. If you think this project is good, please give it back Start! 🙏

Vue3 build steps

  1. First, select a file locally and clone the code locally:
git clone https://github.com/GitHubGanKai/vue-jd-h5.git 
  1. View all branches:
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. Switch to the branch vue-next to start development!

  2. Run the command in the IDEA command line: npm install, download related dependencies;

  3. 🔧 Development environment Run the command in the IDEA command line: npm run dev, run the project;

  4. 📦Run the command in the IDEA command line: npm run dll:build, package the project, 📱scan the QR code below 👇 to view!

Initialization of the project

💡If you are slow when installing the package, it is because the NPM server is abroad. Here is a tool for you to switch NPM mirroring at any time. 👉NRM, sometimes when we are developing, in order to speed up the installation of the installation package, we need to switch the mirror source to domestic, but if we need to publish some of our own components to NPM, we have to switch back and forth again. With this We are much more convenient! Use $ npm install -g nrm to install globally, and then use nrm ls to view all mirrors:

gankaideMacBook-Pro:~ gankai$ nrm ls

  npm -------- https://registry.npmjs.org/
* yarn ------- https://registry.yarnpkg.com/
  cnpm ------- http://r.cnpmjs.org/
  taobao ----- https://registry.npm.taobao.org/
  nj --------- https://registry.nodejitsu.com/
  npmMirror -- https://skimdb.npmjs.com/registry/
  edunpm ----- http://registry.enpmjs.org/

If you need to use Taobao mirror, execute: nrm use taobao You can switch the source at any time, of course, there is also an npm package version management tool nvm, mainly for management In the package version, if you are interested, you can find out for yourself, here is not a long time 😊!

Installation

Enter the root directory of the project that was cloned just now, install related dependencies, and experience the new features of vue3.

npm installation:

npm install

yarn installation:

yarn

CDN

<script src="https://unpkg.com/[email protected]"></script>

use

In the entry file main.js:

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

Vue.use(VueCompositionApi);

After installing the plug-in, you can use the new Composition API to develop components.

⚠️At present, vue officially provides a plug-in for vue-cli vue-cli-plugin-vue-next, you can also directly Add the latest version directly to the project!

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

If you have a small partner who wants to experience the new version from scratch, you can use this method to install it. Since our project relies on third-party libraries, if you install it globally, the third-party UI library of the entire project cannot run! So we still choose to install @vue/composition-api to experience, so as to slowly transition to the latest version of vue3

Vue 3.0 Composition-API Basic Features Experience

setup function

The setup() function is a new attribute specially provided for components in vue3, which is equivalent to the created function in the 2.x version. The component logic options of the previous version are now handled in this function. It provides a unified entry point for us to use the new features of vue3 Composition API. The setup function will be executed after beforeCreate and before created relative to 2.x ! For details, please refer to the following:

vue2.x vue3
beforeCreate setup(replace)
created setup(replace)
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeDestroy onBeforeUnmount
destroyed onUnmounted
errorCaptured onErrorCaptured

New hook

In addition to the 2.x life cycle equivalent, the Composition API also provides the following debugging hooks:

-onRenderTracked -onRenderTriggered

Both hooks received the options of DebuggerEvent and onTrack and onTrigger observers:

export default  {
    onRenderTriggered(e){
      Debugger
      //Check which dependency caused the component to re-render
    }
}

Dependency Injection

provider and inject enable dependency injection similar to the 2.x provide/inject option. Both can only be called during the current active instance of 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 accepts an optional default value as the second parameter. If no default value is provided, and the property cannot be found in the Provide context, then inject returns undefined.

Inject responsive data

In order to maintain the responsiveness between the provided value and the injected value, you can use ref

// in the parent component
const themeRef = ref('dark')
provide(ThemeSymbol, themeRef)

// in the component
const theme = inject(ThemeSymbol, ref('light'))
watchEffect(() => {
   console.log(`theme set to: ${theme.value}`)
})
  1. Because the setup function receives 2 formal parameters, the first is initProps, which is the value passed by the parent component! , The second parameter is a context object

setupContext, the main attributes of this object are:

attrs: Object // equivalent to this.$attrs in vue 2.x
emit: ƒ () // equivalent to this.$emit()
isServer: false // Is it server-side rendering
listeners: Object // equivalent to this.$listeners in vue2.x
parent: VueComponent // equivalent to this.$parent in vue2.x
refs: Object // equivalent to this.$refs in vue2.x
root: Vue // This root is the globally unique instance object returned when we use newVue() in main.js. Be careful not to confuse this with this in the single file assembly
slots: {} // equivalent to this.$slots in vue2.x
ssrContext:{} // server-side rendering related

⚠️Note: The this cannot be accessed in the setup() function, regardless of whether this this refers to the global vue object (ie: the global generated by using new in main.js The vue instance object), still refers to the object of the single file component.

But what if we want to access the instance object of the current component? We can introduce the api of getCurrentInstance, and the return value is the instance of the current component!

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 automatically expand (unwrap)

The ref() function is used to create a reactive data object according to the given value. The return value of the ref() function call is a wrapped object (RefImpl), There is only one .value property on this object. If we want to access the value of the object in the setup function, we can get it through .value, but if it is in the <template>** template **, just visit directly, no need for .value!

import {ref} from'@vue/composition-api'

setup() {
     const active = ref("");
     const timeData = ref(36000000);
     console.log('output ===>',timeData.value)
     return {
        active,
        timeData
     }
}
<template>
   <p>Activity status: {{active}}</p>
   <p>Activity time: {{timeData}}</p>
</template>

⚠️Note: Do not put Array in ref, the array index property cannot be expanded automatically, and **do not use Array to directly access the ref object:

const state = reactive({
   list: [ref(0)],
});
// will not be expanded automatically, you must use `.value`
state.list[0].value === 0; // true

state.list.push(ref(1));
// will not be expanded automatically, you must use `.value`
state.list[1].value === 1; // true

When we need to manipulate the DOM, such as when we use swiper in a project to get the DOM, then we can still do this 👇!

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

Then define a const mySwiper = ref(null); in the setup function. Previously in vue2.x, we used this.$refs.mySwiper to get the DOM object. Now you can also use ref Instead offunction, the returned mySwiper should be the same as the ref bound in the template!

import { ref, onMounted } from "@vue/composition-api";
setup(props, { attrs, slots, parent, root, emit, refs }) {
	const mySwiper = ref(null);
  onMounted(() => {
    // You can get the DOM object through mySwiper.value!
     // At the same time, refs.mySwiper in vue2.x can also be used. In fact, mySwiper.value is the same DOM object!
    mySwiper.value.swiper.slideTo(3, 1000, false);
  });
  return {
    mySwiper
  }
}

reactive

The reactive() function receives an ordinary object and returns a reactive data object, which is equivalent to the Vue.observable() function in vue 2.x. vue 3.x provides reactive' () function, used to create a reactive data object Observer, in ref we generally store basic type data, if it is a reference type, we can use the reactive function.

When the received type in the reactive function is an array of Array, we can wrap a layer of objects outside the Array, and then add an attribute to the object such as: value (this attribute name is your You can call it whatever you want), his value is this array!

<script>
// Must be introduced before using related 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);
    // Turn each object in the tabImgs array into a responsive object
    const tabImgs = reactive({
      value: []
    });
    const ball = reactive({
      show: false,
      el: ""
    });
    return {
      active,
      timeData,
      tabImgs,
      ...toRefs(ball),
    };
  }
};
</script>

So when we want to access this array in the template template, we need to use the form of .value to get the value of this array.

<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() is used to determine whether a value is an object created by ref(); when you need to expand a value that may be created for ref(), you can use isRef to judge!

import { isRef } from '@vue/composition-api'

setup(){
  const headerActive = ref(false);
  // In the setup function, if it is a responsive object, when accessing properties, you must add .value to access!
  const unwrapped = isRef(headerActive) ? headerActive.value : headerActive
  return {}
}

toRefs

The toRefs function will convert the reactive object into an ordinary object, where each attribute on the returned object is a ref that points to the corresponding attribute in the original object, and all the objects on an object It will be very useful when the attribute is converted to responsive!

import { reactive,toRefs } from '@vue/composition-api'
setup(){
  // ball is a Observer
  const ball = reactive({
    show: false,
    el: ""
  });
  // ballToRefs is an ordinary Object, but all the attributes in ballToRefs are responsive (RefImpl)
  const ballToRefs  = toRefs(ball)
  // ref and original attributes are "linked"
  ball.show = true
  console.log(ballToRefs.show) // true
  ballToRefs.show.value = false
  console.log(ballToRefs.show) // false
  return {
    ...ballToRefs    // Expand the ballToRefs object, we can directly use all the attributes on this object in the template template!
  }
}

Click the add button, the ball flies into the shopping cart animation:

<template>  
  <div class="ballWrap">
      <transition @before-enter="beforeEnter" @enter="enter" @afterEnter="afterEnter">
       <!-- You can use v-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

The first parameter of the computed function can receive a function or an object! If it is a function, it defaults to a getter function, and returns a read-only ref object for the value returned by getter.

import { computed } from '@vue/composition-api'

const count = ref(1)
// computed receives a function as an input parameter
const plusOne = computed(() => count.value + 1)

console.log(plusOne.value) // 2

plusOne.value++ // Error, plusOne is read-only!

Or it can be an object, you can use objects with get and set functions to create writable ref objects.

const count = ref(1)
// computed receives an object as an input parameter
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?)

The watch API is exactly equivalent to 2.x this.$watch (and the corresponding watch option).

Observe a single source

The observer data source can be a getter function that returns a value, or it can be directly a ref:

// watching a getter function
const state = reactive({ count: 0 })
watch(
  () => state.count, // Getter function for return value
  (count, prevCount,onCleanup) => {
    /* ... */
  }
)

// directly watching a ref
const count = ref(0)
watch(
  count, // It can also be directly ref
  (count, prevCount,onCleanup) => {
  /* ... */
})

watch multiple sources

Observers can also use arrays to monitor multiple sources at the same time:

const me = reactive({ age: 24, name:'gk' })
// reactive type
watch(
  [() => me.age, () => me.name], // To monitor multiple reactive data sources, you can pass in an array type and return a getter function
  ([age, name], [oldAge, oldName]) => {
    console.log(age) // new age value
    console.log(name) // new name value
    console.log(oldAge) // old age value
    console.log(oldName) // new name value
  },
  // options
  {
    lazy: true //default. The code in the callback function is executed when the watch is created. If lazy is true, how can it not be executed when it is created!
  }
)

setInterval(() => {
  me.age++
  me.name ='oldMe'
}, 7000000)

// ref type
const work = ref('web')
const addres = ref('sz')
watch(
  [work,address], // monitor multiple ref data sources
  ([work, addres], [oldwork, oldaddres]) => {
   //...
  },
  {
    lazy: true
  }
)

watch is bound to the life cycle of the component. When the component is uninstalled, the watch will automatically stop. In other cases, it returns a stop handle, which can be called to stop the watcher explicitly:

// watch returns a function handle, we can decide the stop and start of the watch!
const stopWatch = watch(
  [work,address], // monitor multiple ref data sources
  ([work, addres], [oldwork, oldaddres]) => {
   //...
  },
  {
    lazy: true
  }
)

// Call the stop function to clear the monitoring of work and address
stopWatch()

Clear invalid asynchronous tasks in watch

<div class="search-con">
  <svg-icon class="search-icon" icon-class="search"></svg-icon>
  <input v-focus placeholder="search, keyword" v-model="searchText" />
</div>
setup(props, {attrs, slots, parent, root, emit, refs }){
  const CancelToken = root.$http.CancelToken
  const source = CancelToken.source()
  // Define responsive data searchText
  const searchText = ref('')

  // Send an asynchronous request to the background
  const getSearchResult = searchText => {
   root.$http.post("http://test.happymmall.com/search",{text:searchText}, {
     cancelToken: source.token
   }).then(res => {
    // .....
   });
  return source.cancel
}

// define watch monitor
watch(
  searchText,
  (searchText, oldSearchText, onCleanup) => {
    // Send an axios request and get the cancel function to cancel the axios request
    const cancel = getSearchResult(searchText)

    // If the watch is repeatedly executed, the last unfinished asynchronous request will be cleared first
    onCleanup(cancel)
  },
  // watch is not executed when it is just created
  {lazy: true}
)

  return {
    searchText
  }
}

At last

Vue3 adds Composition API. The new API is compatible with Vue2.x. You only need to introduce the @vue/composition-api package separately in the project to solve our current individual problems in Vue2.x. For example: how to organize logic, and how to extract and reuse logic among multiple components. Based on the current API of Vue 2.x, we have some common logic reuse patterns, but there are more or less problems:

These modes include:

  1. Mixins
  2. Higher-order Components (aka HOCs)
  3. Renderless Components (components based on scoped slots / scoped slots encapsulation logic)

In general, the above models have the following problems:

  1. The source of the data in the template is not clear. For example, when multiple mixins are used in a component, it is difficult to tell which mixin a property comes from by just looking at the template. HOC has similar problems.
  2. Namespace conflict. There is no guarantee that mixins developed by different developers will not use exactly the same attribute or method name. HOC has similar problems in injected props.
  3. Performance. Both HOC and Renderless Components require additional component instance nesting to encapsulate logic, resulting in unnecessary performance overhead.

In vue3, Composition API is added. And the new API is compatible with Vue2.x, only need to introduce the package @vue/composition-api separately in the project, which can solve most of our current problems. At the same time, if I directly upgrade to Vue3.x, I will have more things to do. As long as the third-party ui library used in the current project needs to be remodeled, and many pits after the upgrade have to be filled! At the beginning, I installed and upgraded the vue add vue-next directly on the basis of the current scaffolding, but as long as there are places that rely on third-party ecological libraries, there are many pitfalls. . .

Vue3.x does not export the default object export default. In the third-party ecosystem, Vue.xxx() is often used for dependency. Now these grammars need to be rewritten, and the workload is not small!

If it is a new team or a small project, you can try to use vue3 for trial development, and gradually overstep it. When Vue3.x is officially released and the surrounding ecology keeps up, you can use vue3 directly!

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].