vue06-项目数据加载与插槽

87 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

学子商城项目:

1.发送axios请求

(1). 问题: vue脚手架默认不带axios

(2). 解决: 右键单击package.json,选择在集成终端中打开。然后在终端中输入:

​ npm i -save axios

(3). 问题: 所有的页面组件或其他子组件中都随时有可能使用axios发送请求获取数据。

(4). 解决: 因为所有组件(根组件、全局组件、子组件)都是new Vue()类型的子对象。所以,可以将配置好的axios对象保存到Vue类型的原型对象中。结果,所有组件中都可像使用自己的属性一样使用Vue原型对象中axios对象了

(5). 如何:

A.放在原型对象中

a. main.js中:

import axios from "axios"
axios.defaults.baseURL="公共基础地址"
Vue.prototype.axios=axios

b. 其它组件中: this.axios.get()或this.axios.post()

1.png

B.利用模块化开发的单例模式

a. main.js中:

import axios from "axios"
axios.defaults.baseURL="http://xzserver.applinzi.com";

b. 其它组件中:

import axios from "axios"
axios.get('/url').then(
	...
)

2.png

2.动态加载首页商品:

(1). 在Index.vue中<script>中组件对象内添加:

data(){
	return {
		p1:{}, //准备接第一个商品
		p2:{}, //准备接第二个商品
		p3:{}, //准备接第三个商品
		others:[] //准备接剩余的后三个商品
	}
}

(2). 在mounted()内的axios的.then()中,将响应结果数组中每个商品对象赋值给data中的对应变量;

  mounted(){
    axios.get("/index").then(result=>{
      console.log(result.data);
        this.p1=result.data[0];
  		this.p2=result.data[1];
  		this.p3=result.data[2];
  		this.others=result.data.slice(-3)//从倒数第三个,一直取到最后
    })
  }

简写:

  mounted(){
    axios.get("/index").then(result=>{
      console.log(result.data);
      [this.p1,this.p2,this.p3,...this.others]=result.data;
    })
  }

(3). 去<template>中绑定每商品:

3.png

(4). 问题: 明明正常显示,但是还是报错:

不能读取 undefined 的xxx属性

a. 原因: 首次加载时,p1对象中没有值,是undefined。undefined加谁都算错!

b. 解决: 2个办法:

(1). 为对象的属性提前加上属性值:

(2). 在页面中绑定语法或指令中使用三目屏蔽undefined的情况。

4.png

3.从首页跳转到详情页,并发送请求查询一个商品的信息信息:

(1). 改造首页中按钮的旧路径为新路径:

<router-link :to="`/details/${p2.href.split('=')[1]}`">查看详情</router-link>

(2). 配置路由字典,允许/details路径携带参数

{ 
   path:"/details/:lid",
   component: ()=>import(...),
   props:true
}

5.png

(3). 在详情页使用props接住上个页面传来的数据,并发送axios请求,获得数据

6.png

4.动态绑定详情页的内容:

(0). 先从结果对象中取出每个对象或数组,分别保存:

a. data(){ product:{}, specs:[], pics:[] }

b. 在axios的.then()中为data中每个变量赋值

this.product=result.data.product;
this.specs=result.data.specs;

(1). 绑定右上角商品基本信息:

(2). 绑定右侧规格列表: 57行

v-for 遍历 specs数组中每隔规格对象

a. a解开注释,换成router-link,href换成to,

b. 添加v-for,并:to="/details/${sp.lid}",内容绑定sp.spec

c. 为当前router-link绑定class active。哪个规格对象的lid商品编号和地址栏中的商品编号一致,才用后active class。

8.png

(3). 问题: 点不同的规格按钮,只有地址栏里的数字变,网页内容不重新加载!

(4). 原因: 因为每个规格按钮都是跳回/details页面,只不过携带的值不同而已。所以,vue就认为没必要重新加载详情页组件。如果vue觉得没必要重新加载组件,则不会触发mount(挂载)阶段,自然不会触发mounted中的axios。而我们的程序只在mounted里写了一个axios请求。如果mounted不执行,则axios请求也不会重新发送,当然得不到新商品信息。

(5). 解决: 紧紧监视地址栏中的商品编号(props:["lid"])

只要lid变量值一变,就立刻重新发送请求!

7.png

http-proxy跨域:

1.旧的跨域方式:无论CORS还是JSONP,都要求助于后端才能跨域。

2.解决: 只要使用vue脚手架开发时,都可以用http-proxy跨域

3.优点: 纯前端跨域方式。

4.什么是: 请其他程序代替ajax发送请求。

5.如何:

(1). 在脚手架根目录的vue.config.js文件中,再配置一个代理程序:

module.exports={
	//.....
  devServer: {
    proxy: {
      '/': {
        target: `http://服务器端接口地址统一前缀部分`,
        changeOrigin: true,
      }
    }
  }
}

9.png

(2). main.js中,不用配置axios.defautls.baseURL了

(3). 重启npm run serve

10.png

插槽(slot)

程序中: 多个提示框 –布局风格一致, –只不过内部的具体内容不同

11.png

问题:现实中,早教机会为每种不同的卡片分别做一 个读卡机吗

解决 :现实中,造一个带插槽的读卡器

12.png

程序中: 也可以造一个带样式和插槽的外壳

13.png

然后定义每个对话框时,都把这个外壳套上, 再在外壳内填入每个对话框不同的内容

什么是插槽:插槽是组件中一块可动态改变HTML片段内容 的区域

何时使用插槽

今后,只要发现多个组件, –拥有相同的结构框架, –只是内部HTML片段有不同时, –都应该使用插槽

如何使用插槽

先定义一个组件包含统一的外壳结构

14.png

15.png

16.png

具名插槽

如果一个带插槽的外壳组件,有多个部位将来 可能会改变,怎么办

可以为每个部位指定插槽

将来使用插槽时,可以将不同的HTML片段, 插入不同的插槽中,如果一个带插槽的外壳组件包含多个具名插槽, 则使用时,每个插槽对应的HTML片段,都要放在一个

<template v-slot:插槽名>

简写为

<template #插槽名>

17.png

「xzvue」www.aliyundrive.com/s/c6ypq4xxu… 本次的相关代码