Vue基础

前言

  • vue的响应式
    Vue中的data是响应式,当修改Vue实例中的data属性时,UI页面中data会做出响应,会被Vue监听,会被Vue实例代理,每次对data的读写都会被Vue监控,Vue会在data变化时更新UI,
const data = reactive({
      loginData: {
        username: "",
        password: "",
      },
      num: count,
    });
 return {
      ...toRefs(data),
    };
  },
  • vuex的变量改变规则
state: {
    count: -1,
  },
  // 计算 获取 state的值
  getters: {
    countStatus(state) {
      return state.count > 1;
    },
  },
  // 更新状态的方法-更新state的唯一方法,(记录登录状态)commit mutations
  mutations: {
    setCount(state, num) {
      state.count = num;
    },
  },
  // 异步操作,可以返回promise(更改后的操作),更改数据还是传递到mutations
  actions: {
    setCountPromise(context, num) {
      return new Promise((resolve, reject) => {
        if (num > 100) {
          reject("值不能大于100");
        } else {
          context.commit("setCount", num);
        }
      });
    },
  },
  // 数据比较多,分模块
  modules: {},
  • vuex中的 model
export default createStore({
  modules: { number, uInfo },
});

//子模块1  必须要有 namespaced:true 不然可能回因为 方法重名报错
export default {
  namespaced: true,
  // 全局状态初始化值
  state: {
    // 先判断有无本地存储,在进行需要的数据格式转化,没有的话就是{}
    userInfo:
      (localStorage.getItem("loginData") &&
        JSON.parse(localStorage.getItem("loginData"))) ||
      {},
  },
  // 更新状态的方法-更新state的唯一方法,(记录登录状态)commit mutations
  mutations: {
  },
};


//子模块2
export default {
  namespaced: true,
  // 全局状态初始化值
  state: {
    count: -1,
  },
  // 计算 获取 state的值
  getters: {
    countStatus(state) {
      return state.count > 1;
    },
  },
  // 更新状态的方法-更新state的唯一方法,(记录登录状态)commit mutations
  mutations: {
    setCount(state, num) {
    },
  },
  // 异步操作,可以返回promise(更改后的操作),更改数据还是传递到mutations
  actions: {
    setCountPromise(context, num) {
    },
  },
  // 数据比较多,分模块
  modules: {},
};

  • vue中的路由(分为 hash和history)
import {
  createRouter,
  //hash  和  history的使用区别
  createWebHashHistory,
  // createWebHistory,
} from "vue-router";
import store from "../store/index.js";

// 路由默认hash
// 可以分为  hash 和  history
//路由地址  路由名字  页面组件
const routes = [
  {
    path: "/login",
    name: "login",
    component: () => import("../views/Login/login.vue"),
  },
  // componet懒加载模式
  // {
  //   path: "/",
  //   name: "about",
  //   component: AboutView,
  // },
  //正常是 代码没有走到 component 就引入了组件
  {
    path: "/layOut",
    name: "layOut",
    component: () => import("../views/Layout/layout.vue"),
    // 重定向,子路由首页
    // redirect: "/role",
    //子路由 / 嵌套路由
    children: [
      {
        path: "/role",
        name: "role",
        component: () => import("../views/Pages/rolesList"),
      },
      {
        path: "/user",
        name: "user",
        component: () => import("../views/Pages/usersList"),
      },
    ],
  },
];

const router = createRouter({
//hash  和  history的使用区别
  history: createWebHashHistory(),
  routes,
});

// 路由守卫
router.beforeEach((to, from, next) => {
  /**
   * to:到哪个页面
   * from:从哪来
   * next:只有执行next页面才会进行跳转
   */
  //判断用户是否登录
  // console.log("store", store.state.uInfo);
  const uInfo = store.state.uInfo.userInfo;
  if (!uInfo.username) {
    // 跳回login页面
    if (to.path === "/login") {
      //未登录
      next();
      return;
    }
    next("/login");
  } else {
    // 成功登录
    next();
  }
});

export default router;

  • 引入element-ui 或者其他样式
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
//挂载上App对象即可
createApp(App).use(ElementPlus).mount("#app");
  • 路由守卫(监测登录状态,没有登录的,回到指定页面)
// 路由守卫
router.beforeEach((to, from, next) => {
  /**
 * to:到哪个页面
 * from:从哪来
 * next:只有执行next页面才会进行跳转
   */
  //判断用户是否登录
  // console.log("store", store.state.uInfo);
  const uInfo = store.state.uInfo.userInfo;
  if (!uInfo.username) {
    // 跳回login页面
    if (to.path === "/login") {
      //未登录
      next();
      return;
    }
    next("/login");
  } else {
    // 成功登录
    next();
  }
});
  • vue的生命周期
export default {
  name: "about",
  setup() {
    const data = reactive({
      msg: "你好!",
      msg2: "hellow",
      num: 0,
      username: "",
      userInput: "",
    });
    // 渲染前
    onBeforeMount(() => {
      console.log("onBeforeMount", document.querySelector("#dom"));
    });
    // 渲染后
    onMounted(() => {
      console.log("onMounted", document.querySelector("#dom"));
      setTimeout(() => {
        data.msg = "hello";
      }, 2000);
    });
    // dom更新前
    onBeforeUpdate(() => {
      console.log("onBeforeUpdate");
    });
    // dom更新后
    onUpdated(() => {
      console.log("onUpdated");
      // 防止死循环
      data.num += 1;
    });
    //所有要出现在页面的数据都要return
    const handleClick = () => {
      alert("asd");
    };
    const submit = () => {
      alert(`${data.username}的建议是${data.userInput}`);
    };
    const handfocus = () => {
      console.log("handfocus");
    };
    const handblur = () => {
      console.log("handblur");
      if (!data.username) {
        alert("必填");
      }
    };
    const handchange = () => {
      //正则验证手机号
      if (!/^[1][3,4,5,7,8,9][0-9]{9}$/.test(data.username)) {
        console.log("不符合");
      }
    };

    return {
      ...toRefs(data),
    };
  },
};
  • vue页面的语法
<template>
  <div>
    <h2>vue3生命周期</h2>
    <div id="dom">{{ msg }}</div>
    <!-- v-on:事件名="事件方法" 绑定事件 -->
    <!-- 事件及方法直接声明再setup -->
    <button v-on:click="handleClick">click me</button>

    <!-- v-model=双向绑定 -->
    <!-- 之前普通html是用dom保存数据然后取值,一起传递到后端提交 -->
    <!-- input 输入事件
      blur: 失去焦点
      focus: 获取焦点
      change:内容更改 -->
    <input
      type="text"
      placeholder="请输入姓名"
      v-model="username"
      @focus="handfocus"
      @blur="handblur"
      @change="handchange"
    />
    <textarea
      placeholder="请输入"
      cols="30"
      rows="10"
      v-model="userInput"
    ></textarea>
    {{ username }}
    {{ userInput }}
    <!-- @click=""绑定事件 -->
    <button @click="submit">提交</button>
  </div>
</template>
<template>
  <h1>hello</h1>
  <p v-text="name"></p>
  <!-- v-text的简写 -->
  <p>{{ name }}</p>
  <!-- v-html -->
  <p v-html="info"></p>
  <!-- v-bind 动态绑定标签属性 动态绑定变量名-->
  <p v-bind:data="dataVal">aa</p>
  <!-- class类名绑定 -->
  <!-- 可以累加类名 的style -->
  <p class="text" :class="{ red: isRed }">bbb</p>
  <!-- 判断语句v-iffalse 就是不存在-->
  <!-- v-show 为false 只是不展示,但标签存在 -->
  <p v-if="isTrue">我是if存在</p>
  <p v-show="isFalse">我是ishow存在</p>

  <p v-if="isFalse">if</p>
  <p v-else>else</p>

  <!-- v-for=(每一个对象变量,下标) + :key性能,响应式,可以单独修改那一行,不然是修改整个数组 -->
  <ul>
    <li v-for="(item, index) in userList" :key="index">
      学生姓名:{{ item.username }} 学生年龄:{{ item.age }}
    </li>
  </ul>
</template>

配置

1. axios配置

首先是 service.js 其中主要是 做一些请求的初步准备,例如 请求头配置,get,post,put,delete请求的、封装,请求返回数据的处理,请求中的loading动画,返回消息的弹出框,然后export 一些需要用到的变量,比如封装好了的get,post请求,使在request.js中调用时不会有过多的参数而使用麻烦。

service.js

import axios from "axios";
import { ElMessage } from "element-plus";
import store from "../store";
import { ElLoading } from "element-plus";

let loadingObj = null;
// 使用create创建axios实例
//请求公共信息
const Service = axios.create({
  timeout: 8000,
  // 前缀URL
  baseURL: "http://127.0.0.1:8888/api/private/v1/",

  headers: {
    "Content-Type": "application/json;chartset=utf-8",
    Authorization: store.state.uInfo.userInfo.token,
  },
});

//请求拦截-增加loading,对请求做统一处理
Service.interceptors.request.use((config) => {
  loadingObj = ElLoading.service({
    lock: true,
    text: "Loading",
    background: "rgba(0, 0, 0, 0.7)",
  });
  return config;
});
// 响应拦截-对返回值做统一处理
Service.interceptors.response.use(
  (response) => {
    loadingObj.close();
    const data = response.data;
    if (data.meta.status != 200 && data.meta.status != 201) {
      ElMessage.error(data.meta.msg || "服务器出错");
      // 请求出错
      return data;
    }
    return data;
  },
  (error) => {
    loadingObj.close();
    ElMessage({
      message: "服务器错误",
      type: "error",
      duration: 2000,
    });
    console.log(error);
  }
);

//post请求  数据为  一个对象体
export const post = (config) => {
  return Service({
    ...config,
    method: "post",
    data: config.data,
  });
};
// get请求 数据为 params 问号传值
export const get = (config) => {
  return Service({
    ...config,
    method: "get",
    params: config.data,
  });
};

导入在service.js  export出来的 get,post,并进行不同业务方法的封装,

request.js

import { post, get } from "./service";
// 登录
export const loginApi = (data) => {
  return post({
    url: "/login",
    data,
  });
};
// 获取用户列表
export const userListApi = (data) => {
  return get({
    url: "/users",
    data,
  });
};
// 新增用户列表s
export const userAddApi = (data) => {
  return post({
    url: "/users",
    data,
  });
};

element-ui应用

  1. element-ui的应用

分成 顶部面包屑区域 和 白色内容区域

<template>
  <div>
    <!-- 面包屑 -->
    <el-breadcrumb :separator-icon="ArrowRight">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>商品列表</el-breadcrumb-item>
    </el-breadcrumb>
    
    <!-- 白色内容区域 -->
    <div class="page_content">
      <div class="flex">
        <div class="input_box">
        <!-- 搜索框 -->
          <el-input
            v-model="searchParams.query"
            placeholder="搜索关键字"
            class="input-with-select"
          >
          <!-- 内嵌 搜索按钮 -->
            <template #append>
              <el-button @click="searchList"
                ><el-icon><Search /></el-icon
              ></el-button>
            </template>
            
          </el-input>
          
        </div>
      </div>
      <!-- 表格 -->
      <!-- 
              el-table  的  data:要展示的数据数组
              el-table-column:列 prop每条数据的对应属性
                label:列标题
                scope.row:相当于一条数据,通过这个属性传递到函数里
             -->
      <el-table :data="goodsList" style="width: 100%">
        <el-table-column prop="goods_name" label="商品名" width="180" />
        <el-table-column prop="goods_price" label="价格(¥)" width="180" />
        <el-table-column prop="goods_weight" label="商品重量(kg)" />
        <el-table-column prop="goods_state" label="商品状态">
          <template #default="scope">
          
            <!-- 转换数字为 文字,传递值到函数中 -->
            <p>{{ switchState(scope.row.goods_state) }}</p>
            
          </template>
        </el-table-column>
      </el-table>
      <!-- 
      v-model:currentPage 当前页
      v-model:page-size 当前页展示列数
      layout 选择展示那些组件
       -->
      <!-- 分页 -->
      <el-pagination
        v-model:currentPage="searchParams.pagenum"
        v-model:page-size="searchParams.pagesize"
        :page-sizes="[2, 5, 10, 20]"
        :small="small"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="searchList"
        @current-change="searchList"
      />
      
    </div>
  </div>
</template>
  1. 正则表达式应用
rules2: {
        email: [
          {
            required: false,
            pattern: /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
            message: "请填写正确邮箱",
            trigger: "blur",
          },
        ],
        mobile: [
          {
            required: false,
            pattern:
              /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/,
            message: "请填写正确手机号",
            trigger: "blur",
          },
        ],
      },

vue部分成果展示

请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值