项目实践-Vue2

目录

(一) 创建项目#

(1) 创建vue2项目#

 (二)vue2不需要vite,但需要禁用Eslint

(三) 添加vant-ui 

vue2#

(四)vue2,3都可以通用less,scss 

(六) vue路由配置(背诵)#


一) 创建项目#

(1) 创建vue2项目#

01 安装vue-cli脚手架

npm install -g @vue/cli

02 查看vue脚手架版本

vue --version  // 出现版本号表示成功

03 创建一个新项目  

vue create hello-world  // 创建项目

运行项目

cd hello-world  // 进入项目文件夹
npm run serve   // 运行项目

 

 (二)vue2不需要vite,但需要禁用Eslint

// 根目录新增vue.config.js
module.exports = {
    lintOnSave: false
}

如果vue组件提示红色错误,如下图 

 

项目实践-Vue2_第1张图片

 解决办法: 文件 -> 首选项 -> 设置 然后输入eslint -> 选择Vetur -> 把√取消即可 

(三) 添加vant-ui 

vue2#

vant2地址: Vant 2 - Mobile UI Components built on Vue

  1. 安装依赖

  2. 使用

    import Vue from 'vue'
    import App from './App.vue' 
    import Vant from 'vant';
    import 'vant/lib/index.css';  
    Vue.use(Vant)
    
    Vue.config.productionTip = false 
    new Vue({ 
      render: h => h(App),
    }).$mount('#app')

(四)vue2,3都可以通用less,scss 

(五)devtool挂载浏览器 

(六) vue路由配置(背诵)#

(1)一个简单路由配置#

  1. npm i vue-router@3  安装路由插件
  2. 在src创建views文件夹, 创建各个模块的组件
  3. 在src内创建router文件夹, 新建index.js(代码如下)
  4. 在main.js里, 把router挂载到vue的实例
  5. 配置路由出口, 详见下方第(2)点router-view
  6. 使用router-link进行跳转, 详见下方第(3)点路由跳转
import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router); 
// 路由数组
const routes = [
    {
        path: '/product',
        component: ()=>import('@/views/product/index.vue')
    },
    {
        path: '/cart',
        component: ()=>import('@/views/cart/index.vue')
    },
]

const router = new  Router({
    routes
})
export default router;
// main.js 代码
import Vue from 'vue'
import App from './App.vue'
import router from './router/index'

Vue.config.productionTip = false

new Vue({
  // 把router挂载到vue实例
  router,
  render: h => h(App),
}).$mount('#app')

(2) router-view#

  1. 路由出口
  2. 路由匹配到的组件将渲染在这里
  3. 在app.vue配置



(3) 路由跳转#

// 方式一
cart

// 方式二
this.$router.push('/cart');

(4) 子路由配置#

使用子路由进行模块路由配置,结构比较分明 比如我们的网站有商品模块,有列表页面和详情页面, 路由如下 /product   商品模块总路由 /prodcut/list   子路由 /product/detail   子路由

{
    path: '/product',
    component: () => import('@/views/product/index'),
    children: [
        {
            path: 'list',
            component: ()=>import('@/views/product/children/list')
        },
        {
            path: 'detail',
            component: ()=>import('@/views/product/children/detail')
        }
    ]
}

(5) active-class#

active-class是vue-router模块的router-link组件中的属性,用来做选中样式的切换;

  1. 只要路由中包含to里面的路由, 就能匹配到, 就会高亮, 比如: /product, /product/list, /product/detail都会使下面的第二个router-link高亮
  2. exact 表示精确匹配, 只有路由完全一样才能被匹配
首页
product
cart
my
order

(6) history模式#

vue2配置方式

  1. vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。

  2. 如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面

  3. 使用history需要后端支持, vue-cli创建的devServer可以支持

    const router = new VueRouter({
      mode: 'history',  // 默认hash
      routes
    })

(7) redirect重定向#

当访问 '/', 我们使用redirect使它默认跳到 '/product'

{
    path: '/',
    redirect: '/product'
},

(8) 404配置#

假如用户访问了一个没有的路由, 我们让它跳转到404页面

  {
    path: '*',
    component:()=>import('@/components/NotFound')
  }

 

(七) 父子组件通信(背诵)#

知识点(背诵):

  1. 父传子: 父组件通过(绑定)属性的方式传数据给子组件, 子组件使用props接收数据
  2. 子传父: 父组件在子组件上绑定一个自定义事件, 子组件通过$emit触发该自定义事件, 同时可以传入数据

(1) 父传子#

  • 父组件给子组件绑定属性, 属性的值是需要传递的信息

    简单概括就是: 父组件通过属性给子组件传数据

  • 子组件通过props接收父组件的信息

// demo.vue 充当父组件



 

// AAA.vue 充当子组件



 

(2) 子传父#

  1. 父组件在子组件上绑定一个自定义事件(事件名称我们自己定义的, vue本身是没有这个事件的)
  2. 父组件给自定义事件绑定一个函数, 这个函数可以接受来自子组件的数据
  3. 子组件使用$emit触发(调用)该事件, 并把数据以参数形式传给父组件
// 例子1: 一个简单的例子
// demo.vue


 

// 子组件


  

(八) axios拦截器(背诵)#

  1. 对ajax请求进行拦截
    1. 在请求头添加token
  2. 对ajax响应数据进行拦截
    1. 统一处理请求失败的情况, 这样就不需要在每个组件里处理失败的情况
    2. 有些接口需要登录才能访问, 在没登录的情况下跳转到登录页面
import axios from "axios";
import Vue from "vue";
import { Toast } from "vant";
Vue.use(Toast);

const service = axios.create({
  baseURL: "http://huruqing.cn:3003",
  timeout: 50000, // 请求超时时间(因为需要调试后台,所以设置得比较大)
});

// request 对请求进行拦截
service.interceptors.request.use(
  (config) => {
    // 开启loading
    Toast.loading({
      message: "加载中...",
      forbidClick: true,
      loadingType: "spinner",
    });
    // 请求头添加token
    config.headers["token"] =
      "gg12j3h4ghj2g134kj1g234gh12jh34k12h34g12kjh34kh1g";
    return config;
  },
  (error) => {
    Promise.reject(error);
  }
);

// response 响应拦截器
service.interceptors.response.use(
  (response) => {
    Toast.clear();
    const res = response.data;
    if (res.code == 666) {
      return res;
    } else {
      // 成功连接到后台, 但是没有返回正确的数据
      Toast.fail(res.msg);
    }
  },
  (error) => {
    Toast.clear();
    // 跟后台连接失败
    Toast.fail("网络异常,请稍后再试");
  }
);

export default service;

 

(九) 路由传参方式(背诵)#

知识点:

  1. 通过params传参, 使用$route.params接收参数

  2. 动态路由传参, 使用$route.params接收参数

  3. 通过query传参, $route.query接收参数

    注意: router和route不是一回事

(1) 通过path+query传参#

// 带查询参数,query传参会把参数拼接到地址栏,变成 /register?plan=aaa, 使用了path,参数不能通过params传递
this.$router.push('/goods?name=张三');

this.$router.push({ 
    path: '/goods', 
    query: { plan: 'aaa' }
})
// 获取参数
this.$route.query;

(2) 通过name+params传参#

// 1.配置路由的时候添加name
  {
        path: "detail",
        name: 'product-detail',
        component: () => import("@/views/order/children/detail"),
  },


// 2.跳转
 this.$router.push({
        // 要跳转到的路由名称
        name: 'product-detail',
         params: { productId: '123' }
      })

// 3.接收参数
this.$route.params.productId

(3) 动态路由传参#

// 1.配置路由
{
  path: "detail/:productId", 
  component: () =>   		  import("@/views/product/children/detail.vue"),
},
  
// 2. 跳转
this.$router.push('/product/detai/22222')
传参

  
// 3.接收参数
 created() {
    let params = this.$route.params;
    console.log('params',params); 
  },
  

(十) slot插槽#

元素作为承载分发内容的出口 一个内存插槽, 当内存插上之后,插槽就可以接收来自内存的信息, slot取名插槽含义也贴切, 在子组件配置插槽slot, 当父组件"插"信息进来的时候, 插槽slot就能接收到这个信息. slot插槽大大的扩展子组件的功能。 

项目实践-Vue2_第2张图片

1. vant有赞ui库中slot的例子#

 
   

2. 普通插槽#

// 父组件demo.vue代码


 

// 子组件Son.vue
 

3. 具名插槽#

// father.vue代码




接收父组件带 slot="footer" 的内容
接收不带slot="xxx" 的内容

// Child.vue代码

自定义组件

// demo.vue





// Nav-Bar.vue


 


(十一) vue过滤器#

作用: 格式化数据

// 组件内的过滤器
   



// 全局过滤器
Vue.filter('fMoney', (money)=> {
  let num = money/100;
  return num.toFixed(2);
})
new Vue({})

// 定义好全局过滤器后, 组件内可以直接使用
   


(十二) vuex(背诵)#

vuex是什么: ** vuex是一个专为 Vue.js 应用程序开发的状态管理模式**。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

术语解读:

  1. vuex可以共享状态, 用来进行跨组件通信的
  2. 这些状态具备响应式的特性, 也就是某个状态改变了, 依赖这个状态的所有组件也会发生响应的变化
  3. 把所有要共享的状态都放在一起

知识点#

  1. 给项目添加vuex

  2. state 定义状态

  3. getters 派生状态

  4. mutation 修改状态(同步)

  5. action 修改状态(异步)

  6. module 模块化

  7. vuex持久化

  8. 项目实践

    注: 前第2-6个是vuex的核心概念, 第7和第8是项目的应用

(1) 在项目中使用vuex#

  1. 安装依赖

    npm i vuex@3
    
  2. 创建并导出store

    // src/store/index.js

    // 创建并导出store
    import Vuex from 'vuex';
    import Vue from 'vue';
    Vue.use(Vuex); 
    
    const store = new Vuex.Store({
    
    })
    
    export default store;
    
  3. 挂载store

    // src/main.js

    import store from './store/index';
    
    new Vue({
      router,
      store,
      render: (h) => h(App),
    }).$mount("#app");
    

(2) state 定义状态#

// 定义状态 src/store/index.js

const store = Vuex.Store({
  state: {
    username: "张三",
  },
});

// 获取状态方法(1) demo.vue



 

// 获取状态方法(2) demo.vue



 

(3) mutation 修改状态(同步)#

mutatiaon改变, 定义一个mutation, 本质上就是定义一个用来修改state的函数

// 创建并导出store
import Vuex from "vuex";
import Vue from "vue";
Vue.use(Vuex);

const store = new Vuex.Store({
  // 定义状态
  state: {
    username: "张三",
    age: 100
  },

  mutations: {
      // 定义修改名字的mutation
      set_username(state,payload) {
         state.username = payload;   
      },
      // 定义修改age的mution
      set_age(state,payload) {
          state.age = payload;
      }
  }
}); 
export default store;

// 绑定事件来触发修改状态



 

(4) getters 派生状态#

跟computed差不多意思, computed是由一个或多个属性计算出另外一个属性, 你也可以说派生出另外一个属性

getters: 由一个或多个状态计算出一个新的状态

import Vuex from "vuex";
import Vue from "vue";
Vue.use(Vuex);

const store = new Vuex.Store({
  // 定义状态
  state: {
    cartId: 452520199508150320,
  },

  getters: {
    // 由cartId派生出生日
    birthdate(state) {
      // 字符串才能使用slice方法
      let cartId = state.cartId + '';
      let Y = cartId.slice(6, 10);
      let M = cartId.slice(10, 12);
      let D = cartId.slice(12, 14);
      return `${Y}-${M}-${D}`;
    },
  }, 
});
export default store;

(5) action 修改状态(异步)#

  1. 定义action 注意, 修改状态必须使用mutation, mutation必须是同步函数

  2. 一个action的全流程: 用户点击按钮 => 派发响应的action => action去commit响应的mutation => mutation 去修改state => state改变了, 界面跟着发生改变

// 定义action

// 创建并导出store
import Vuex from "vuex";
import Vue from "vue";
Vue.use(Vuex);
import $axios from '@/api/request'

const store = new Vuex.Store({
  // 定义状态
  state: { 
    smsCode: "请先获取验证码",
  }, 

  mutations: { 
    set_smsCode(state,payload) {
        state.smsCode = payload;
    }
  },

  actions: {
    ['SMSCODE'](store,phone) {
        $axios.post('/user/getSmsCode',{phone}).then(res=> {
            store.commit('set_smsCode',res.smsCode);
        })
    },
  },
});
export default store;

// 使用dispatch方法来派发action



 

(6) module 模块化#

// 定义cart模块的store src/store/modules/cart.js

const cartStore = {
    state: {
        cartNum: 0,
    },
    getters: {},
    mutations: {
        set_cartNum(state,payload) {
            state.cartNum = payload;
        }
    },
    actions: {}
}

export default cartStore;

// 合并store

// 创建并导出store
import Vuex from "vuex";
import Vue from "vue";
Vue.use(Vuex); 
import cart from "./modules/cart";

const store = new Vuex.Store({
  // 定义状态
  state: {},
  modules: { cart },
  mutations: {},
  actions: {},
});
export default store;

// 使用 demo.vue



 

(7) vuex持久化#

  1. 安装插件 vuex-persistedstate

  2. 配置插件

    import createPersistedState from "vuex-persistedstate"; 
    
    // 创建仓库 - 就是Vuex.Store() 的实例对象
    const store = new Vuex.Store({
      plugins: [createPersistedState({
        storage: window.sessionStorage, // 使用的缓存, 默认是localStorage
      })],
    })

你可能感兴趣的:(vue.js,javascript,前端)