一、环境准备

前提:

# 安装node环境
node -v
npm -v

# 卸载旧脚手架工具
npm uninstall vue-cli -g
or
yarn global remove vue-cli

# 安装新版的脚手架工具 指定版本@vue/cli@版本号
npm install -g @vue/cli

创建项目

vue create vue3

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Vue CLI v4.5.14
┌─────────────────────────────────────────────┐
│                                             │
│    New version available 4.5.14 → 4.5.15    │
│   Run yarn global add @vue/cli to update!   │
│                                             │
└─────────────────────────────────────────────┘
// 1.手工模式
? Please pick a preset: Manually select features
// 2.安装 Router, Vuex, CSS 插件
? Check the features needed for your project: Choose Vue version, Babel, Router, Vuex, CSS Pre-processors, Linter
// 3. vue3.x版本
? Choose a version of Vue.js that you want to start the project with 3.x
// 4. 选择hash模式 默认历史模式
? Use history mode for router? (Requires proper server setup for index fallback in production) No
// 5. 选择css插件Sass/SCSS
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with dart-sass)
// 6. 格式化配置祖安泽标准
? Pick a linter / formatter config: Standard
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
// 7. 不保存为模板,立即创建项目
? Save this as a preset for future projects? (y/N) n
二、核心组件
2.1. axios封装

安装 axios
使用axios发送ajax请求

npm install axios --save

utils/request.js

import axios from 'axios'

const instance = axios.create({
  baseURL: 'https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd',
  timeout: 10000
})

export const get = (url, params = {}) => {
  return new Promise((resolve, reject) => {
    instance.get(url, { params }).then((response) => {
      resolve(response.data)
    }, err => {
      reject(err)
    })
  })
}

export const post = (url, data = {}) => {
  return new Promise((resolve, reject) => {
    instance.post(url, data, {
      headers: {
        'Content-Type': 'application/json'
      }
    }).then((response) => {
      resolve(response.data)
    }, err => {
      reject(err)
    })
  })
}

后续更新集成请求拦截和响应拦截+模块单独api

案例:获取博文发布作者姓名

<template>
  <div class="about">
    <h1 @click="handleClick">This is an about page</h1>
    <button @click="getBlogData">获取博文数据</button>
  </div>
  <div>{{ name }}</div>
</template>
<script>
import { toRefs } from 'vue';
import { useStore } from 'vuex';
export default {
  name: 'about',
  setup() {
    const store = useStore();
    // 从store.state把name解构出来
    const { name } = toRefs(store.state);
    const handleClick = () => {
      // 异步修改数据
      store.dispatch('getData', 'hello aync');
      // 同步修改数据
      // store.commit('changeName', 'hello2');
    };

    const getBlogData = () => {
      store.dispatch('getBlogData');
    };
    return { name, handleClick, getBlogData };
  },
};
</script>

大家可以直接使用我的调用测试地址,自己的地址会有跨域问题

import { createStore } from 'vuex';
import axios from 'axios';
// VueX 数据管理框架
// VueX 创建一个全局唯一的仓库,用来全局的数据
export default createStore({
  state: {
    name: 'dell',
  },
  mutations: {
    changeName(state, val) {
      state.name = val;
    },
  },
  actions: {
    // 异步逻辑
    getBlogData(store) {
      axios
        .get(
          'https://www.fastmock.site/mock/a4701044176a98816d53ce26897cdd3b/api/hxq'
        )
        .then((res) => {
          console.log(res);
          const name = res.data.name;
          store.commit('changeName', name);
        });
    },
    // 修改名字
    getData(store, val) {
      setTimeout(() => {
        store.commit('changeName', val);
      }, 2000);
    },
  },
  modules: {},
});

后期,api接口具体调用会api目录下的模块具体的xx.js中,然后在,store的index模块的actions下面调用此方法即可

2.2. vuex

store/index.js

VueX 数据管理框架
VueX 创建一个全局唯一的仓库,用来全局的数据,一处修改,全局立即生效
数据声明和数据获取使用:

数据放到state里面
通过计算属性获取到数据
computed: {
    myName() {
      return this.$store.state.name;
    }
  }


数据修改
声明一个事件
触发一个
 /**
       * 1.dispatch方法,派发一个action,名字叫做change
       * 2.vuex中actions就会感知到change 这个action,执行store中actions下面change的方法(在actions中的方法不能直接修改数据,必须通过提交一个commit发送请求)
       * 3.在actions下面change的方法内部,提交一个commit 叫做change的数据改变方法
       * 4.mutation 感知到提交的mutation改变,执行change方法,改变数据
       * 5.
       */
       state中的数据只能在mutations中去修改
       mutation只执行同步的代码逻辑
       actions中写异步的逻辑(不做数据修改具体操作,只是发送commit请求)
       
       
       如果不需要异步操作:也可以
        this.$store.commit('change', 'hello word');
        mutations下的change方法也会感知到,直接修改数据
        
        dispatch是和actions做关联的
        commit是和mutations做关联的
        
        一般  mutations中封装同步代码
              actions封装异步代码

传统方式使用

import { createStore } from 'vuex';
// VueX 数据管理框架
// VueX 创建一个全局唯一的仓库,用来全局的数据
export default createStore({
  state: {
    name: 'dell',
  },
  mutations: {
    //  第4步,对应的mutation 被执行
    change(state, val) {
      //  第5步,在mutation里面修改数据
      state.name = val;
    },
  },
  actions: {
    // 第2步,store感知到你触发一个change的action,执行change方法
    change(store, val) {
      // 第3步,提交一个commit 触发一个mutation
      setTimeout(() => {
        store.commit('change', val);
      }, 2000);
    },
  },
  modules: {},
});

about.vue

<template>
  <div class="about">
    <h1 @click="handleClick">This is an about page</h1>
    <div>{{ myName }}</div>
  </div>
</template>
<script>
export default {
  name: 'about',
  computed: {
    myName() {
      return this.$store.state.name;
    },
  },
  methods: {
    handleClick() {
      /**
       * 1.dispatch方法,派发一个action,名字叫做change
       * 2.感知change 这个action,执行store中actions下面change的方法
       * 3.commit 提交一个叫做change的数据改变
       * 4.mutation 感知到提交的mutation改变,执行change方法,改变数据
       * 5.
       */
      this.$store.commit('change', 'hello word');
      //  this.$store.dispatch('change', 'hello word');
    },
  },
};
</script>

compositionAPI方式
从vuex中引入useStore函数,获取全局数据对象

然后通过useStore获取Store,使用commit调用同步方法改数据

使用dispatch调用异步方法改数据

import { createStore } from 'vuex';
// VueX 数据管理框架
// VueX 创建一个全局唯一的仓库,用来全局的数据
export default createStore({
  state: {
    name: 'dell',
  },
  mutations: {
    changeName(state, val) {
      console.log;
      val;
      state.name = val;
    },
  },
  actions: {
    // 异步逻辑
    getData(store, val) {
      setTimeout(() => {
        store.commit('changeName', val);
      }, 2000);
    },
  },
  modules: {},
});

about.vue

<template>
  <div class="about">
    <h1 @click="handleClick">This is an about page</h1>
  </div>
  <div>{{ name }}</div>
</template>
<script>
import { toRefs } from 'vue';
import { useStore } from 'vuex';
export default {
  name: 'about',
  setup() {
    const store = useStore();
    // 从store.state把name解构出来
    const { name } = toRefs(store.state);
    const handleClick = () => {
      // 异步修改数据
      store.dispatch('getData', 'hello aync');
      // 同步修改数据
      // store.commit('changeName', 'hello2');
    };
    return { name, handleClick };
  },
};
</script>

2.3. vue-router
import { createRouter, createWebHashHistory } from 'vue-router'

const routes = [{
    path: '/',
    name: 'Home',
    component: () => import(/* webpackChunkName: "home" */ '../views/home/Home')
  },{
    path: '/cartList',
    name: 'CartList',
    component: () => import(/* webpackChunkName: "cartList" */ '../views/cartList/CartList')
  },{
    path: '/orderConfirmation/:id/:addressId?',
    name: 'OrderConfirmation',
    component: () => import(/* webpackChunkName: "orderConfirmation" */ '../views/orderConfirmation/OrderConfirmation')
  }, {
    path: '/orderList',
    name: 'OrderList',
    component: () => import(/* webpackChunkName: "orderList" */ '../views/orderList/OrderList')
  },{
    path: '/shop/:id',
    name: 'Shop',
    component: () => import(/* webpackChunkName: "shop" */ '../views/shop/Shop')
  }, {
    path: '/register',
    name: 'Register',
    component: () => import(/* webpackChunkName: "register" */ '../views/register/Register'),
    beforeEnter(to, from, next) {
      const { isLogin } = localStorage;
      isLogin ? next({ name: 'Home'}):  next();
    }
  }, {
    path: '/login',
    name: 'Login',
    component: () => import(/* webpackChunkName: "login" */ '../views/login/Login'),
    beforeEnter(to, from, next) {
      const { isLogin } = localStorage;
      isLogin ? next({ name: 'Home'}):  next();
    }
  }, {
    path: '/chooseAddressList/:shopId',
    name: 'ChooseAddressList',
    component: () => import(/* webpackChunkName: "chooseAddressList" */ '../views/chooseAddressList/ChooseAddressList'),
  },{
    path: '/myAddressList',
    name: 'MyAddressList',
    component: () => import(/* webpackChunkName: "myAddressList" */ '../views/myAddressList/MyAddressList'),
  }, {
    path: '/upsertAddress/:id?',
    name: 'UpsertAddress',
    component: () => import(/* webpackChunkName: "upsertAddress" */ '../views/upsertAddress/UpsertAddress'),
  }, {
    path: '/person',
    name: 'PersonalInfo',
    component: () => import(/* webpackChunkName: "person" */ '../views/personalInfo/PersonalInfo'),
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

router.beforeEach((to, from ,next) => {
  const { isLogin } = localStorage;
  const { name } = to;
  const isLoginOrRegister = (name === "Login" || name === "Register");
  (isLogin || isLoginOrRegister) ? next() : next({ name: 'Login'});
})

export default router

<template>
  <router-view />
</template>

<script>
export default {
  name: 'App',
}
</script>

参数传递

,{
    path: '/shop/:id',
    name: 'Shop',
    component: () => import(/* webpackChunkName: "shop" */ '../views/shop/Shop')
  }

参数接收

<template>
  <div class="wrapper">
    <div class="title">
      <div
        class="iconfont title__back"
        @click="handleBackClick"
      >&#xe6f2;</div>
      <div class="title__text">管理收货地址</div>
      <div class="title__add" @click="handleAddClick">新建</div>
    </div>
    <Address
      v-for="address in addressList"
      :key="address._id"
      :address="address"
      @click="() => handleUpdateClick(address._id)"
    />
  </div>
</template>

<script>
import Address from '../../components/Address'
import useCommonAddressEffect from '../../effects/addressEffect'

import { toRefs } from 'vue'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'

export default {
  name: 'MyAddressList',
  components: { Address },
  setup() {
    const store = useStore()
    const router = useRouter()
    const { addressList } = toRefs(store.state)
    const { getAddressList } = useCommonAddressEffect()
    getAddressList(true)
    const handleBackClick = () => { router.back() }
    const handleAddClick = () => { router.push({ name: 'UpsertAddress'}) }
    const handleUpdateClick = (addressId)=> {router.push(`/upsertAddress/${addressId}`)}
    return { addressList, handleBackClick, handleAddClick, handleUpdateClick }
  }
}
</script>

<style lang="scss" scoped>

</style>
Logo

前往低代码交流专区

更多推荐