vue尚品汇商城项目-day04【28.详情页面Detail】

简介: vue尚品汇商城项目-day04【28.详情页面Detail】

1.jpeg

@[toc]

28.详情页面Detail

重难点说明:

1) 图片放大镜效果

2) 小图轮播

28.1点击跳转详情页面且滚轮处在顶部

编写组件4步骤:

  1. 静态页面
  2. ajax调接口
  3. vuex
  4. 动态渲染展示数据

实现步骤:

  1. 在pages文件夹下新建Detail文件夹
  2. 在src/router/index.js下新增“页面详情”路由跳转+滚动行为
  3. 在src/pages/Search/index.vue图片跳转的地方改成路由跳转

修改代码:

/router/index.js

//引入路由跳转配置文件
import routes from "./routes"

//配置路由
export default new VueRouter({
    //实际是routes:routes,但是因为同名,所以可以只保留key即可,于是就有如下的写法
    routes,
    //滚动行为
    scrollBehavior(to, from, savedPosition) {
        // 始终滚动到顶部
        return { y: 0 }
    },
})

src/pages/Search/index.vue

<!-- 在路由跳转的时候切记别忘记带id(params)参数 -->
<router-link :to="`/detail/${good.id}`"><img :src="good.defaultImg" /></router-link>

src/router/routes.js

//引入路由组件
import Register from '@/pages/Register'
import Login from '@/pages/Login'
import Home from '@/pages/Home'
import Search from '@/pages/Search'
import Detail from '@/pages/Detail'

export default [
    {
        name: 'detail',
        path: '/detail/:skuId?',
        component: Detail,
    },
    {
        path: '/home',
        component: Home,
        meta:{"isShow": true}
    },
    {
        name: 'search',
        //:keyword?    其中的?可以理解成正则中的问号,代表出现0次或1次,这样就能进行控制params参数传递与不传递
        path: '/search/:keyword?',
        component: Search,
        meta:{"isShow": true}
    },
    {
        path: '/register',
        component: Register,
        meta:{"isShow": false}
    },
    {
        path: '/login',
        component: Login,
        meta:{"isShow": false}
    },
    //重定向,在项目跑起来的时候,访问/,立马让他定向到首页
    {
        path: '*',
        redirect: "/home",
    }
]

注意点1:“页面详情”路由跳转是需要传递参数的,传递的是商品的id,所以才有了如下写法

{
            name: 'detail',
            path: '/detail/:skuId?',
            component: Detail,
}

注意点2:

问题:点击跳转详情的时候,发现滚轮未在顶部,如何处理?

答案:vue官网提供了针对滚轮行为的API,且滚轮行为和routes是同级别的。

image.png

注意点3:针对编写路由跳转是可以再优化的,优化的点在于当下全部路由写在了src/router/index.js中,可能显得臃肿写,所以优化方案就是在router/下新建一个routes.js文件夹,把路由跳转相关单独提出来放在一个文件中。(其实这一步优化可有可无,看自己定夺)

src/router/index.js原始的长这样

//引入vue-router路由插件
import VueRouter from "vue-router";
//引入Vue
import Vue from "vue";
Vue.use(VueRouter);

//引入路由组件
import Register from '@/pages/Register'
import Login from '@/pages/Login'
import Home from '@/pages/Home'
import Search from '@/pages/Search'
import Detail from '@/pages/Detail'


//先把VueRouter原型对象的push方法,拷贝一份
let originPush = VueRouter.prototype.push;
let originReplace = VueRouter.prototype.replace;
//重写push|replace方法,其中第1个参数告诉原来push方法,你往哪里跳转以及传递哪些参数,第2个参数代表成功回调,第3个参数代表失败回调
VueRouter.prototype.push = function (location, resolve, reject) {
    if (resolve || reject) {
        /**
         * call || apply 区别?
         * 相同点:都可以调用函数一次,都可以篡改函数的上下文一次
         * 不同点:call与apply传递参数中,call传递参数用逗号隔开,而apply传递数组
         */
        originPush.call(this, location, resolve, reject);
    } else {
        originPush.call(this, location, ()=>{}, ()=>{});
    }
}
VueRouter.prototype.replace = function (location, resolve, reject) {
    if (resolve || reject) {
        originReplace.call(this, location, resolve, reject);
    } else {
        originReplace.call(this, location, ()=>{}, ()=>{});
    }
}

//配置路由
export default new VueRouter({
    routes:[
        {
            name: 'detail',
            path: '/detail/:skuId?',
            component: Detail,
        },
        {
            path: '/home',
            component: Home,
            meta:{"isShow": true}
        },
        {
            name: 'search',
            //:keyword?    其中的?可以理解成正则中的问号,代表出现0次或1次,这样就能进行控制params参数传递与不传递
            path: '/search/:keyword?',
            component: Search,
            meta:{"isShow": true}
        },
        {
            path: '/register',
            component: Register,
            meta:{"isShow": false}
        },
        {
            path: '/login',
            component: Login,
            meta:{"isShow": false}
        },
        //重定向,在项目跑起来的时候,访问/,立马让他定向到首页
        {
            path: '*',
            redirect: "/home",
        }
    ],
    //滚动行为
    scrollBehavior(to, from, savedPosition) {
        // 始终滚动到顶部
        return { y: 0 }
    },
})

优化后的方案,先新建src/router/routes.js文件

//引入路由组件
import Register from '@/pages/Register'
import Login from '@/pages/Login'
import Home from '@/pages/Home'
import Search from '@/pages/Search'
import Detail from '@/pages/Detail'

export default [
    {
        name: 'detail',
        path: '/detail/:skuId?',
        component: Detail,
    },
    {
        path: '/home',
        component: Home,
        meta:{"isShow": true}
    },
    {
        name: 'search',
        //:keyword?    其中的?可以理解成正则中的问号,代表出现0次或1次,这样就能进行控制params参数传递与不传递
        path: '/search/:keyword?',
        component: Search,
        meta:{"isShow": true}
    },
    {
        path: '/register',
        component: Register,
        meta:{"isShow": false}
    },
    {
        path: '/login',
        component: Login,
        meta:{"isShow": false}
    },
    //重定向,在项目跑起来的时候,访问/,立马让他定向到首页
    {
        path: '*',
        redirect: "/home",
    }
]

src/router/index.js

//引入vue-router路由插件
import VueRouter from "vue-router";
//引入Vue
import Vue from "vue";
Vue.use(VueRouter);
import routes from "./routes"

//先把VueRouter原型对象的push方法,拷贝一份
let originPush = VueRouter.prototype.push;
let originReplace = VueRouter.prototype.replace;
//重写push|replace方法,其中第1个参数告诉原来push方法,你往哪里跳转以及传递哪些参数,第2个参数代表成功回调,第3个参数代表失败回调
VueRouter.prototype.push = function (location, resolve, reject) {
    if (resolve || reject) {
        /**
         * call || apply 区别?
         * 相同点:都可以调用函数一次,都可以篡改函数的上下文一次
         * 不同点:call与apply传递参数中,call传递参数用逗号隔开,而apply传递数组
         */
        originPush.call(this, location, resolve, reject);
    } else {
        originPush.call(this, location, ()=>{}, ()=>{});
    }
}
VueRouter.prototype.replace = function (location, resolve, reject) {
    if (resolve || reject) {
        originReplace.call(this, location, resolve, reject);
    } else {
        originReplace.call(this, location, ()=>{}, ()=>{});
    }
}

//配置路由
export default new VueRouter({
    //实际是routes:routes,但是因为同名,所以可以只保留key即可,于是就有如下的写法
    routes,
    //滚动行为
    scrollBehavior(to, from, savedPosition) {
        // 始终滚动到顶部
        return { y: 0 }
    },
})

28.2产品详情数据ajax获取

使用步骤:

  1. 封装ajax调商品详情接口
  2. vuex封装
  3. 在详情挂载完毕后派发action

修改代码:

src/api/index.js

//获取产品详情信息的接口  URL: /api/item/{ skuId }  请求方式:get
export const getGoodsInfo = (skuId)=>requests({url:`/item/${skuId}`, method:"get"});

src/store/index.js

import detail from "@/store/detail"

//模块:把小仓库进行合并变为大仓库
    modules:{       
        detail
    }

src/store/detail/index.js

import {getGoodsInfo} from "@/api";
//Detail模块的小仓库
//actions代表一系列动作,可以书写自己的业务逻辑,也可以处理异步
const actions = {
    //获取产品信息的action
    async getGoodsInfo(context, skuId) {
        let response = await getGoodsInfo(skuId);
        if (response.code == 200) {
            context.commit("GET_GOODS_INFO", response.data)
        }
    }
}
//mutations代表维护,操作维护的是state中的数据,且state中数据只能在mutations中处理
const mutations = {
    GET_GOODS_INFO(state, goodsInfo) {
        state.goodsInfo = goodsInfo
    },
}
//state代表仓库中的数据
const state = {
    //仓库初始状态
    goodsInfo:{}
}
//计算属性
//项目当中getters主要的作用是:简化仓库中的数据(简化数据而生)
//可以把我们将来在组件当中需要用的数据简化一下【将来组件在获取数据的时候就方便了】
const getters = {}

//创建并暴露store
export default {
    actions,
    mutations,
    state,
    getters
}

src/pages/Detail/index.vue

mounted() {
      //派发action获取产品详情的信息
      this.$store.dispatch("getGoodsInfo", this.$route.params.skuId)
    }

注意点1:

问题:什么时候派发action?

答案:当用户点击图片详情,当search组件跳转到detail组件中,并且detail组件挂载完毕时进行派发。

注意点2:ajax封装的get请求和post请示是有区别的,要留意

这是GET不传参的:
export const mockGetFloorList = ()=> mockRequests.get("/floor")
-------------------------------------------------------------------------------
这是GET传参的:
export const getGoodsInfo = (skuId)=>requests({url:`/item/${skuId}`, method:"get"});
-------------------------------------------------------------------------------
这是POST传参的:
export const getSearchList = (params)=>requests({url:"/list", method:"post", data:params});

注意点3:新建商品详情src/store/detail/index.js对应的vuex文件时,要提前在src/store/index.js中注册。

注意点4:调用商品详情接口是要传skuId参数的,这个可以在路由参数params中获取,就是你在定义路由规则的时候定义的那个参数。

28.3产品详情展示动态数据

代码修改地方:

src/store/detail/index.js

const getters = {
    categoryView(state) {
        return state.goodsInfo.categoryView || {};
    },
    skuInfo(state) {
        return state.goodsInfo.skuInfo || {};
    },
    spuSaleAttrList(state) {
        return state.goodsInfo.spuSaleAttrList || [];
    }
}

src/pages/Detail/index.vue

<!-- 导航路径区域 -->
<div class="conPoin">
        <span v-show="categoryView.category1Name">{
  {categoryView.category1Name}}</span>
        <span v-show="categoryView.category2Name">{
  {categoryView.category2Name}}</span>
        <span v-show="categoryView.category3Name">{
  {categoryView.category3Name}}</span>
</div>

<!--放大镜效果-->
<Zoom :skuImageList="skuImageList"/>
<!-- 小图列表 -->
<ImageList :skuImageList="skuImageList"/>

<h3 class="InfoName">{
  {skuInfo.skuName}}</h3>
<p class="news">{
  {skuInfo.skuDesc}}</p>      
<em>{
  {skuInfo.price}}</em>

<dl v-for="(spuSaleAttr, index) in spuSaleAttrList" :key="spuSaleAttr.id">
    <dt class="title">{
  {spuSaleAttr.saleAttrName}}</dt>
    <dd changepirce="0" :class="{active: spuSaleAttrValue.isChecked == '1'}" v-for="(spuSaleAttrValue, index) in spuSaleAttr.spuSaleAttrValueList" :key="spuSaleAttrValue.id">{
  {spuSaleAttrValue.saleAttrValueName}}</dd>
</dl>

computed: {
      ...mapGetters(["categoryView", "skuInfo", "spuSaleAttrList"]),
      //给子组件的数据
      skuImageList() {
        //如果服务器数据没有回来,skuInfo这个对象是空数组
        return this.skuInfo.skuImageList || []
      }
    }

src/pages/Detail/ImageList/ImageList.vue

<div class="swiper-slide" v-for="(skuImage, index) in skuImageList" :key="index">
        <img :src="skuImage.imgUrl">
</div>

 props: ["skuImageList"]

src/pages/Detail/Zoom/Zoom.vue

<img :src="coverSkuImageListObj.imgUrl" />
<img :src="coverSkuImageListObj.imgUrl" />

props: ["skuImageList"],
    computed: {
      coverSkuImageListObj() {
        //如果服务器数据没有回来,skuImageList子项应该是空对象
        return this.skuImageList[0] || {}
      }
    }

注意点1:

问题:功能都好使,为啥会有警告?

image.png

image.png

image.png

答案:因为goodInfo未调用接口是是个空对象,而空对象调用categoryView就是underfine,而underfine再调用category1Name就会报错,所以正确应该返回空对象,正确代码如下:

skuInfo(state) {
        return state.goodsInfo.skuInfo || {};
    }

注意点2:

问题:在修改放大镜功能的时候,警告报错但不影响功能,为什么?

image.png

image.png

答案:Zoom组件在初始化加载的时候仓库中是没有数据的,还为没有调服务器接口呢所以压根没数据,所以模板代码中空对象调用属性的时候就会报错。正确写法如下:

<!--放大镜效果-->
<Zoom :skuImageList="skuImageList"/>

computed: {
    //给子组件的数据
      skuImageList() {
        //如果服务器数据没有回来,skuInfo这个对象是空数组
        return this.skuInfo.skuImageList || []
      }
}

注意点3:

问题:报错如图

image.png

image.png

答案:skuImageList空数组所以skuImageList[0]就是undefine,而undefine不可能调用属性imgUrl,所以报错。正确写法如下:

<img :src="coverSkuImageListObj.imgUrl" />

computed: {
      coverSkuImageListObj() {
        //如果服务器数据没有回来,skuImageList子项应该是空对象
        return this.skuImageList[0] || {}
      }
    }

28.4实现商品详情属性的勾选切换,效果如图

image.png

修改代码:

src/pages/Detail/index.vue

<dd changepirce="0" :class="{active: spuSaleAttrValue.isChecked == '1'}" v-for="(spuSaleAttrValue, index) in spuSaleAttr.spuSaleAttrValueList" :key="spuSaleAttrValue.id" @click="changeActive(spuSaleAttrValue, spuSaleAttr.spuSaleAttrValueList)">{
  {spuSaleAttrValue.saleAttrValueName}}</dd>

methods: {
      //产品的售卖属性值切换高亮
      changeActive(spuSaleAttrValue, spuSaleAttrValueList) {
        //遍历全部售卖属性值isChecked为零没有高亮了
        spuSaleAttrValueList.forEach(item =>{item.isChecked = '0'})
        //点击的那个售卖属性值变为1
        spuSaleAttrValue.isChecked = '1';
      }
}

注意点1:

问题:为啥点击方法要传递2个参数spuSaleAttrValue, spuSaleAttrValueList?

答案:spuSaleAttrValue其实就是数组spuSaleAttrValueList的子项,点击选中时是要把数组spuSaleAttrValueList中的选中项对象中的isChecked属性值设置为1才行。

注意点2:

问题:如何切换选中高亮呢?

答案:点击方法刚进来把所有选项都设置为不勾选,当选中谁就在对应子项的isChecked属性值为1就行。

28.5实现放大镜下方轮播图切换及点击展示不同图片功能

想实现的效果如下图:

image.png

修改代码:

src/pages/Detail/Zoom/Zoom.vue

data() {
      return {
        currentIndex: 0
      }
    },
    computed: {
      coverSkuImageListObj() {
        //如果服务器数据没有回来,skuImageList子项应该是空对象
        return this.skuImageList[this.currentIndex] || {}
      }
    },
    mounted() {
      //全局事件总线:获取兄弟组件传递过来的索引值
      this.$bus.$on('transferCurrentIndex', (currentIndex)=>{
        //修改当前响应式数据
        this.currentIndex = currentIndex;
      })
    }

src/pages/Detail/ImageList/ImageList.vue

<img :src="skuImage.imgUrl" :class="{active: currentIndex == index}" @click="changeCurrentIndex(index)">

data() {
      return {
        currentIndex: 0
      }
    },
    methods: {
      changeCurrentIndex(index) {
        //修改响应式数据
        this.currentIndex = index;
        //通知兄弟组件:当前的索引值为几
        this.$bus.$emit('transferCurrentIndex', index)
      }
    },
    watch: {
      //监听数据:可以保证数据一定ok,但是不能保证v-for遍历结构是否完事。
      skuImageList: {
        handler(newValue, oldValue) {
          this.$nextTick(() => {
            new Swiper('.swiper-container', {
              //显示几个图片设置
              slidesPerView: 3,
              //每一次切换图片个数
              slidesPerGroup: 1,
              // 如果需要前进后退按钮
              navigation: {
                nextEl: '.swiper-button-next',
                prevEl: '.swiper-button-prev',
              },
            })
          });
        }
      }
    }

<style lang="less" scoped>
    //该处这是掉了,不通过CSS方式鼠标划入添加选中高亮色,想通过JS方式实现
        //&:hover {
        //  border: 2px solid #f60;
        //  padding: 1px;
        //}
</style>

注意点1:放大镜下方的还是轮播图,轮播图的注意事项请看知识点“21.使用swiper轮播图插件”

注意点2:

问题:swipper如何控制,一排显示几个以及滚动跳过几个?

答案:请找官网
image.png

注意点3:

问题:给轮播图选中高亮显示如何做?

答案:方法有2种

第一种CSS方式鼠标划入添加选中高亮色
&:hover {
          border: 2px solid #f60;
          padding: 1px;
        }
----------------------------------------------------------------   
第二种通过JS方式实现,添加点击事件
<img :src="skuImage.imgUrl" :class="{active: currentIndex == index}" @click="changeCurrentIndex(index)">

data() {
      return {
        currentIndex: 0
      }
},

changeCurrentIndex(index) {
        //修改响应式数据
        this.currentIndex = index;
        //通知兄弟组件:当前的索引值为几
        this.$bus.$emit('transferCurrentIndex', index)
      }

28.6放大镜功能

最终效果如下:

image.png

修改代码:

src/pages/Detail/Zoom/Zoom.vue

<div class="event" @mousemove="handler"></div>
<div class="big">
<img :src="coverSkuImageListObj.imgUrl" ref="big"/>
</div>
<!-- 遮罩层:就是浅绿色的正方形 -->
<div class="mask" ref="mask"></div>

methods: {
    handler(event) {
        let mask = this.$refs.mask;
        let big = this.$refs.big;
        let left = event.offsetX - mask.offsetWidth/2;
        let top = event.offsetY - mask.offsetHeight/2;
        //约束范围
        if(left <= 0) left = 0;
        if(left >= mask.offsetWidth) left = mask.offsetWidth;
        if(top <= 0)top = 0;
        if(top >= mask.offsetHeight) top = mask.offsetHeight;
        //修改元素的left|top属性值
        mask.style.left = left + 'px';
        mask.style.top = top + 'px';
        big.style.left = - 2 * left + 'px';
        big.style.top = -2 * top + 'px';
      },
}

注意点1:放大镜功能实际和4个参数有关,分别是:【 event.offsetX、event.offsetY、mask.offsetWidth、mask.offsetHeight】。

注意点2:

问题:为啥left和top是要除以2?

let left = event.offsetX - mask.offsetWidth/2;
let top = event.offsetY - mask.offsetHeight/2;

答案:长度如图。

image.png

注意点3:注意约束范围,否则的话绿色正常性会出界。

//约束范围
if(left <= 0) left = 0;
if(left >= mask.offsetWidth) left = mask.offsetWidth;
if(top <= 0)top = 0;
if(top >= mask.offsetHeight) top = mask.offsetHeight;

注意点4:右面的放大的图片也要修改left、top坐标,且通过读取CSS样式发现big的宽高是mask的两倍,所以才有了如下的代码:

//修改元素的left|top属性值
mask.style.left = left + 'px';
mask.style.top = top + 'px';
big.style.left = - 2 * left + 'px';
big.style.top = -2 * top + 'px';

28.7购买产品个数的操作

image.png

考虑点:

  • 考虑点1:点击“-”最小只能为1,不能为0或者负数
  • 考虑点2:既然数量用户可以输入,那么就得加校验规则,正确就直接显示,不正确就显示1。比如用户输入数字和英文组合、负数、0、正小数、中英文、特殊符号等等。

修改代码:

src/pages/Detail/index.vue

<div class="controls">
    <input autocomplete="off" class="itxt" v-model="skuNum" @change="changeSkuNum">
    <a href="javascript:" class="plus" @click="skuNum++">+</a>
    <a href="javascript:" class="mins" @click="skuNum > 1 ? skuNum-- : (skuNum = 1)">-</a>
</div>

data() {
      return {
        skuNum: 1
      }
},
//表单元素修改产品个数
changeSkuNum(event) {
        //用户输入进来的文本 * 1
        let value = event.target.value * 1;
        if (isNaN(value) || value < 1) {
          this.skuNum = 1;
        } else {
          //正常大于1【大于1整数不能出现小数】
          this.skuNum = parseInt(value);
        }
      }

注意点0:

问题:如何获取用户输入的值呢?

答案:通过event.target.value获取值。

注意点1:确保点击减号“-”最小值为1

<a href="javascript:" class="mins" @click="skuNum > 1 ? skuNum-- : (skuNum = 1)">-</a>

注意点2:

问题:如何校验用户输入数量呢?

答案:添加@change方法。

注意点3:

问题:如何判断输入值是否合规呢?

答案:

//用户输入进来的文本 * 1
let value = event.target.value * 1;
if (isNaN(value) || value < 1) {
    this.skuNum = 1;
} else {
    //正常大于1【大于1整数不能出现小数】
    this.skuNum = parseInt(value);
}

注意点4:一个小技巧:任何带非数字的字符串*1,值都为NaN。

注意点5:一个小技巧:parseInt()可以让小数向下取整。

本人其他相关文章链接

1.vue尚品汇商城项目-day04【24.点击搜索按钮跳转后的页面商品列表、平台售卖属性动态展示(开发Search组件)】
2.vue尚品汇商城项目-day04【25.面包屑处理关键字】
3.vue尚品汇商城项目-day04【26.排序操作(难点)】
4.vue尚品汇商城项目-day04【27.分页器静态组件(难点)】
5.vue尚品汇商城项目-day04【28.详情页面Detail】
6.vue尚品汇商城项目-day04【29.加入购物车操作(难点)】

目录
相关文章
|
21天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
17天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2563 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
15天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
13天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
17天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1556 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
19天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
826 14
|
14天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
621 7
|
7天前
|
Docker 容器
Docker操作 (五)
Docker操作 (五)
170 69
|
7天前
|
Docker 容器
Docker操作 (三)
Docker操作 (三)
167 69
|
19天前
|
人工智能 自动驾驶 机器人
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
过去22个月,AI发展速度超过任何历史时期,但我们依然还处于AGI变革的早期。生成式AI最大的想象力,绝不是在手机屏幕上做一两个新的超级app,而是接管数字世界,改变物理世界。
629 52
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界