最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

环球要闻:C#中的WebAPI

来源:博客园
前端用:vue3,后端:net6,的结合代码vue3手动创建:勾选1、路由配置:router。2、vuex状态管理:store类似全局变量。3、在加上UI库:element-plus模板大致UI库模板如下:安装ui库命令:npm install element-plus --save,UI库图标命令:npm install @element-plus/icons-vueApp.vueCategoryView.vue
import { createApp } from "vue" //框架实例import App from "./App.vue" import router from "./router" //路由import store from "./store" //状态管理vuex--类似全局变量import ElementPlus from "element-plus"//ui库import "element-plus/dist/index.css" //ui库的样式import * as ElementPlusIconsVue from "@element-plus/icons-vue"//ui库图标const app = createApp(App)for (const [key, component] of Object.entries(ElementPlusIconsVue)) {    app.component(key, component)//注册icon图标,ui库图标  }app.use(store).use(router).use(ElementPlus).mount("#app")
main.js入口的挂载
{    path:"/category",    name:"category",    component:()=>import("../views/CategoryView.vue")}
index.js路由的配置

一、后台webAPI的搭建

创建asp.net core web api项目:搭建数据库连接1.创建【Models】文件夹保存实体类:Category.cs


(资料图片)

public class Category{    public int Id { get; set; }    public string Name { get; set; }}

2.创建【Data】文件夹保存数据库上下文类:ShopDbContext.cs

using Microsoft.EntityFrameworkCore;using ShoopingWeb.Models;namespace ShoopingWeb.Data{    public class ShopDbContext:DbContext    {        public ShopDbContext(DbContextOptions options) : base(options)        {            //参数DbContext选项值创建的这个新的类型,包装后用base关键字传给父类        }        public DbSet Categories { get; set; }//添加表    }}

3.在【appsettings.json】文件中配置数据库连接字符串,这里用的vs自带数据库

"ConnectionStrings": {    "ShopConn": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=OA;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"  }

4.把数据库添加到服务全局【Program.cs】

builder.Services.AddDbContext(option => { //添加数据库上下文类    option.UseSqlServer(builder.Configuration.GetConnectionString("ShopConn"));//拿到数据库连接字符串,在appsettings.json配置文件里});

5.工具-》nuget包管理-》控制台:1.执行数据库迁移:add-migration initDb 2.保存到数据库:update-database 手打6.在【Controllers】文件夹下创建控制器:CategoryController.cs ,用的是RESTfull开发风格:路由+http请求=方法体定义的api

using Microsoft.AspNetCore.Http;using Microsoft.AspNetCore.Mvc;using Microsoft.EntityFrameworkCore;using ShoopingWeb.Data;using ShoopingWeb.Models;namespace ShoopingWeb.Controllers{    [Route("api/[controller]")]//路由:api/控制器名,这里是Category别写错哟    [ApiController]//控制器是webapi    public class CategoryController : ControllerBase    {        private readonly ShopDbContext db;        public CategoryController(ShopDbContext db)//鼠标右键快速生成字段并赋值        {            this.db = db;//绑定数据库ShopDbContext上下文类        }        [HttpGet]//在webapi中,是通过路由+http请求【特性】来找到方法的,和方法名无关,无调用只有注释的作用。        public async Task> GetList()//有async定义的异步编程,不过有没有返回值都必须Task        {            return await db.Categories.ToListAsync();//有async异步定义的方法,就必须有await来执行任务。        }        [HttpGet("{id}")]//路由模式:api/controller/{id}        public async Task> Getid(int id)        {            var category = await db.Categories.FindAsync(id);//通过id查询            if (category == null)            {                return NotFound();//返回404的状态码,多种返回类型用:ActionResult            }            return Ok(category);//返回数据        }        [HttpPost]//增        public async Task> Add(Category model)        {            await db.Categories.AddAsync(model);//添加数据            await db.SaveChangesAsync();            return Ok(model.Id);        }        [HttpDelete("{id}")]//删        public async Task Delete(int id)        {            var category = await db.Categories.FindAsync(id);            if (category == null) { return NotFound(); }//返回404,都是返回状态码,用接口即可:IActionResult            db.Categories.Remove(category);//删除数据不需要异步            await db.SaveChangesAsync();//保存需要异步            return NoContent();//返回204,成功删除        }        [HttpPut]//改        public async Task Update(Category model)        {            var category = await db.Categories.FindAsync(model.Id);            if (category == null) { return NotFound(); }//返回404            category.Name = model.Name;            await db.SaveChangesAsync();//保存修改的数据            return NoContent();//返回204,成功修改        }    }}

测试:直接运行后台代码,可以看出后台其实返回的就是josn字符串和状态码而已

二、前后端CORS跨域配置

在Ajax请求时遵循的是同源策略:协议相同,域名相同,端口相同。而在webapi中前后端分离的,端口肯定不一样。所以不能在使用Ajax来发送请求。CORS(Cross-orgin-resource-sharing)跨域资源共享:打破同源策略的限制。Ajax为了安全考虑做的限制,打破限制的方案有很多,cors最常见。后台:服务端的配置【Program.cs】,开放运行策略

builder.Services.AddCors(options => //添加跨域服务{    options.AddPolicy("cors", p =>//添加策略,可以添加多种    { //如果是允许指定的域、方法、消息头需要使用WithOrigins、WithMethods、WithHeaders方法。        p.AllowAnyOrigin()//允许可以,参数可以给ip,不给表示允许所有        .AllowAnyMethod() //允许所有方法        .AllowAnyHeader();//请求头    });});
app.UseCors("cors");//启用策略中间件管道,必须放跳转:app.UseHttpsRedirection();的后面

前台:客户端vue3的框架配置文件【vue.config.js】,每次修改此文件需要重启项目,Ctrl+c项目关闭,重启命令:npm run serve

const { defineConfig } = require("@vue/cli-service")module.exports = defineConfig({//会覆盖webpack默认配置  transpileDependencies: true,  devServer:{//开发环境的服务器配置    open:true,//是否自动打开浏览器    host:"localhost",    port:8080,//修改默认端口    proxy:{//通过代理的方式访问,会重写路由      "/api":{        target:"https://localhost:7135/api/",//服务器请求地址,在后台Properties--》launchSettings.json中        secure:false,//HTTPS需要配置这个参数        changeOrigin:true,//请求头host属性,默认false发本机ip。true会把host设置为target的值。        pathRewrite:{"^/api":""}//路径重写,(正则表达式)识别api路径替换为空字符串。      }    }  }})

三、获取后台数据【axios请求库】

安装命令:npm install axios ,请求库还有很多,axios只是vue3的一种vue3前端src目录下创建【api】文件夹放配置文件:api_config.js

import axios from "axios" //请求库axios.defaults.baseURL="http://localhost:8080/api" //基础路径,做请求前缀。axios.defaults.headers["X-Requested-With"]="XMLHttpRequest" //请求类型:异步请求axios.defaults.headers.post["Content-Type"]="application/json" //post以json格式提交到后台export default axios;

获取后台所有数据:在【views】试图中【CategoryView.vue】组件下请求数据即可

  <script setup>  import {reactive,onMounted} from "vue" //vue里面要定义变量,需要导入reactive这个方法  import axios from "@/api/api_config";//请求库,@符号表示src文件夹    const tableData = reactive({list:[]})//reactive也可以定义一个对象list  onMounted(()=>{ //类似于后台构造方法,初始化时调用    getList()   })  const getList=()=>{//获取数据信息    return axios.get("/Category").then((res)=>{//get得的后台控制器的数据,返回结果用then方法获取。      tableData.list=res.data      console.log(res.data)//打印到控制台    })  }</script>

增删改:在【components】创建弹窗组件:AddCategory.vue 做添加和修改

  <script  setup>  import {inject, reactive,toRefs,watch} from "vue" //reactive可以定义变量也可以定义对象。    import {ElMessage} from "element-plus" //弹窗    import axios from "@/api/api_config";//请求库  const state =reactive({    dialogVisible:false,//表示不显示对话框,ui库包对话框当做属性来判断了    ruleForm:{id:"",name:""}//对话框的数据,也是修改和添加用  });//如果没有toRef转换,那么必须通过state.dialogVisible这样一层一层的取值  const {dialogVisible,ruleForm} =toRefs(state)//将reactive转为ref对象,也不需要点value取值  const dialogCategory=()=>{//定义一个打开对话框的方法    state.dialogVisible = true;//调用方法就显示对话框  };  //主动暴露子组件方法,这是编译器的宏命令,不需要引入,其他组件就可以使用  defineExpose({dialogCategory})//需要配置文件.eslintrc.js将宏命令打开:"vue/setup-compiler-macros":true在env选项中添加。  const title = defineProps({//自动暴露这个变量    dialogTitle:{type:String},//标题    tableRow:{type:Object}//id    })  watch(//监听器,是vue的一个选项,监听数据的变化而变化    ()=>title.tableRow,//需要监听的数据,    ()=>{state.ruleForm=title.tableRow},//如果有变化就改变数据。    {//配置        deep:true,//是否深度检测,数据又多层,可以深度查找        immediate:true //立即执行    }  )  const getList=inject("getList")//依赖注入刷新页面,传过来的用provide,接收的用inject  const add =()=>{    if(title.dialogTitle==="添加数据"){        let param={name:ruleForm.value.name} //let定义的变量在作用于大括号中,出了大括号无用        axios.post("/Category",param).then(()=>{            ElMessage.success("添加成功")            getList()//刷新页面数据            state.dialogVisible = false//关闭窗口        })    }else{        let param={            id:title.tableRow.id, //id            name:ruleForm.value.name //姓名        }        axios.put("/Category",param).then(()=>{            ElMessage.success("修改成功")            getList()//刷新页面数据            state.dialogVisible = false//关闭窗口        })    }  }</script>  

数据页代码如下

  <script setup>  import {reactive,onMounted,ref, provide} from "vue" //vue里面要定义变量,需要导入reactive这个方法  import axios from "@/api/api_config";//请求库,@符号表示src文件夹  import AddCategoryVue from "@/components/AddCategory.vue"; //子组件,对话框的标签  import { isNull } from "@/utils/filter";//自定义的做数据筛选处理  import { ElMessage, ElMessageBox } from "element-plus"//删除的消息弹窗    const tableData = reactive({list:[]})//reactive也可以定义一个对象list    onMounted(()=>{ //类似于后台构造方法,初始化时调用,自动运行    getList()   })  const getList=()=>{//获取数据信息的方法    return axios.get("/Category").then((res)=>{//返回结果用then方法获取。      tableData.list=res.data      console.log(res.data)//打印到控制台,测试数据用    })  }  provide("getList",getList);//依赖注入:跨组件,把这个方法提供给子组件执行,传过去的用provide,接收的用inject他们两个是一对依赖注入  const AddCategory = ref(null)//定义在标签里的ref属性,当做一个实例,名字就代表了这个对话框组件,就可以用变量去调用他里面的方法了  const dialogTitle =ref("")//弹窗标题  const tableRow =ref({})//修改和删除的id,绑定到标签,传给子组件  const handleDialog=(row)=>{ //打开弹窗的事件    if(isNull(row)){      dialogTitle.value="添加数据"    }else{      dialogTitle.value="修改数据"      tableRow.value = row //把id传入子组件的弹窗    }    AddCategory.value.dialogCategory()//调用子组件的弹窗方法  }  const open =(id)=>{      ElMessageBox.confirm("你确定要删除吗?","温馨提示",{        confirmButtonText:"确定",        cancelButtonText:"取消",        type:"warning",      }).then(()=>{        axios.delete(`/Category/${id}`).then(()=>{//这里的符号是反引号波浪线下面          ElMessage({            type:"success",            message:"删除成功!",          });          getList() //加载数据的方法,刷新数据        })    }).catch(()=>{//捕捉到错误        ElMessage({          type:"info",          message:"取消删除!",        })      })  }  </script>  

这里自定义了一个数据过滤器:src项目创建【utils】文件夹:filter.js怎么配置一些数据过滤

export const isNull=(data)=>{ //定义个数据过滤器    if(!data)return true //普通值    if(JSON.stringify(data)==="{}")return true //对象    if(JSON.stringify(data)==="{}")return true //数组}

关键词: 配置文件 数据库连接 刷新页面