您现在的位置是:首页 >技术交流 >Vue(ajax、插槽)网站首页技术交流

Vue(ajax、插槽)

DF-vegan 2024-06-17 11:19:22
简介Vue(ajax、插槽)

一、ajax请求

1. 实现ajax请求方式:

  • xhr:原生

  • jquery封装xhr

  • axios:属于promise

  • fetch

2. axios实现步骤:

1.首先安装axios

//安装
npm i axios

 2. 在本地准备两个服务端

//student
const express = require('express')
const app = express()

app.use((request,response,next)=>{
	console.log('有人请求服务器1了');
	console.log('请求来自于',request.get('Host'));
	 console.log('请求的地址',request.url);
	next()
})

app.get('/students',(request,response)=>{
	const students = [
		{id:'001',name:'tom',age:18},
		{id:'002',name:'jerry',age:19},
		{id:'003',name:'tony',age:120},
	]
	response.send(students)
})

app.listen(5000,(err)=>{
	if(!err) console.log('服务器1启动成功了,请求学生信息地址为:http://localhost:5000/students');
})
//cars
const express = require('express')
const app = express()

app.use((request,response,next)=>{
	console.log('有人请求服务器2了');
	next()
})

app.get('/cars',(request,response)=>{
	const cars = [
		{id:'001',name:'奔驰',price:199},
		{id:'002',name:'马自达',price:109},
		{id:'003',name:'捷达',price:120},
	]
	response.send(cars)
})

app.listen(5001,(err)=>{
	if(!err) console.log('服务器2启动成功了,请求汽车信息地址为:http://localhost:5001/cars');
})

3. 在组件中引入并使用axios发送ajax-get请求

import axios from "axios"
//模板按钮 
<button @click="getStudent">获取学生信息</button>

//vue中设置请求方法
    methods: {
    getStudent(){
      axios.get('http://localhost:5000/students').then(
        // 成功形参
        response => {
          console.log('请求成功的',response.data);
        },
        // 失败形参
        error=>{
          console.log('请求失败',err.message);
        }
      )
    }

4. 解释跨域

以上ajax请跨域,因为本地的端口号是8080

请求过程中:两个计算机的协议类型、主机、端口号三个都必须一致,任一不同都会导致跨域请求

5. 解决跨域

  • cors:解决跨域,在写服务器的时候添加特殊响应头(不可以随便设置,否则都可以获取到数据)

    // 自定义响应头
  response.setHeader("Access-Control-Allow-Headers", "*");
  • JSONP:借助script标签src属性引入外部资源不受同源策略(只有get请求可以用)

jsonp原理详解——终于搞清楚jsonp是啥了_哪 吒的博客-CSDN博客一、JSONP的由来1、Ajax直接请求普通文件存在跨域无权限访问的问题,不管是静态页面、动态页面、web服务,只要是跨域请求,一律不准。2、不过我们发现,web页面调用js文件则不受跨域的影响(不仅如此,我们还发现凡是拥有“src”这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>)。3、于是可以判断,当前阶段如果想通过纯web端跨域访问数据就只有一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用https://blog.csdn.net/guorui_java/article/details/107345499?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168429206416782427418587%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168429206416782427418587&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-107345499-null-null.142%5Ev87%5Ekoosearch_v1,239%5Ev2%5Einsert_chatgpt&utm_term=jsonp&spm=1018.2226.3001.4187

  • 代理服务器:客户端向代理服务器发送请求,代理服务器向指定跨域服务器发送请求

6. 代理服务器使用

此处了解脚手架中的开启代理服务器

  • 在脚手架的config文件中进行配置开启解决跨域代理服务器
  • 配置前端获取端口(改为代理服务器)
  • 开启server1服务器
  • 然后进行访问

配置参考 | Vue CLI?️ Vue.js 开发的标准工具https://cli.vuejs.org/zh/config/#devserver-proxy

开启代理服务器1:在vue.config.js文件中进行配置(查看上方链接文档)

目标地址指向访问的服务器

devServer: {
    proxy: 'http://localhost:5000'
  }

然后组件中直接定义方法:使用axios进行获取数据(注意要引入,端口变成8080)

 getStudents(){
      axios.get('http://localhost:8080/xlf/students').then(
        // 成功形参
        response => {
          console.log('请求成功的',response.data);
        },
        // 失败形参
        error=>{
          console.log('请求失败',error.message);
        }
      )
    },

代理服务器问题:

  • 不能配置多个代理

  • 不是将所有请求转发给传送数据服务器(当自身服务器存在就直接获自身服务器上的数据而不获取代理服务器)

  • public文件就是8080服务器根目录

  • 例如直接在根目录创建一个txt文件,里面添加数据,文件命名为students

 

开启代理服务器1:在vue.config.js文件中进行配置(查看上方链接文档)

  • 此处注意文档中不存在的配置:pathRewrite(代理服务器前缀修改)

  • 直接本地进行ajax请求代理服务器会存在报错,因为代理服务器访问服务器会存在前缀

 

 // 配置代理方式2:指定多个代理
  devServer: {
    proxy: {
      // 请求前缀:当本地8080给代理发送请求,如果请求前缀符合指定代理
      '/xlf': {
        // 代理目标地址
        target: 'http://localhost:5000',
        //配置将代理服务器前缀转为空
        pathRewrite: {'^/xlf': ''},
        ws: true,
        //false:就是获取端口
        // true:就是被请求的端口
        // changeOrigin: true//控制请求头中的host值,默认为真
      },
      '/demo': {
        // 代理目标地址
        target: 'http://localhost:5001',
        //配置将代理服务器前缀转为空
        pathRewrite: {'^/demo': ''},
        ws: true,
        //false:就是获取端口
        // true:就是被请求的端口
        // changeOrigin: true//控制请求头中的host值
      },
    }
  }
getStudents(){
      axios.get('http://localhost:8080/xlf/students').then(
        // 成功形参
        response => {
          console.log('请求成功的',response.data);
        },
        // 失败形参
        error=>{
          console.log('请求失败',error.message);
        }
      )
    }
  • changeOrigin的作用:控制请求头中的host值

    • 如果设置为false:直接表示来自于8080端口
    • 如果设置为true:给服务器撒谎来自于相同服务器

 

  •  弥补了代理服务器1=>可以给多个服务器进行代理(使用时候注意前缀)

 '/demo': {
        // 代理目标地址
        target: 'http://localhost:5001',
        //配置将代理服务器前缀转为空
        pathRewrite: {'^/demo': ''},
        ws: true,
        //false:就是获取端口
        // true:就是被请求的端口
        // changeOrigin: true//控制请求头中的host值
      },
 getCars(){
      axios.get('http://localhost:8080/demo/cars').then(
        // 成功形参
        response => {
          console.log('请求成功的',response.data);
        },
        // 失败形参
        error=>{
          console.log('请求失败',error.message);
        }
      )
    }

二、插槽

目的:让父组件可以向子组件指定位置插入HTML结构,是一种组件间通信方式

适用于:父组件  ===>  子组件

常用父给子传递数据:

  • 父组件中实例化子组件时候传递数据
  • 子组件props进行接收
  • 然后进行使用 

如果需要显示不同内容就需要在子组件添加显示判断指令(结构较麻烦)

1. 默认插槽

  • 子组件获取结构处(挖坑)定义标签slot

  • 父组件中实例化时候使用双标签,在其中布置html结构,也可以直接遍历其中数据等操作

 
<!--子组件:定义一个插槽(等着组件的使用者进行填充) -->
 <slot>我是一些默认值,当使用者没有传递据结构,会出现</slot>
//父组件 可以传递数据也可以直接布置结构
<Category title='游戏'>
      <ul>
        <li v-for="(g,index) in games" :key='index'>{{g}}</li>
      </ul>
   </Category>

2. 具名插槽

  • 直接给子组件(挖坑)定义标签slot时候添加标签属性name命名

     

  • 父组件中实例化时候使用双标签,在其中布置html结构,标签中使用标签属性定义插槽位置

    • slot=坑名:可以直接使用

    • v-slot=坑名:需要template标签包裹结构

<slot name="center">我是一些默认值,当使用者没有传递据结构,会出现1</slot>
<slot name="footer">我是一些默认值,当使用者没有传递据结构,会出现2</slot>
<Category title='电影' >
    <video slot="center" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
    <template v-slot:footer>
       <div class="foot">
          <a href="">经典</a>
          <a href="">热门</a>
          <a href="">推荐</a>
      </div>
      <h4>欢迎前来观影</h4>
    </template>
   </Category>

3. 作用域插槽

当前数据存放在子组件中

  • 首先子组件(挖坑)slot:利用数据绑定将当前组件中的数据进行绑定

  • 然后父组件中使用template包裹结构:使用标签属性scope获取传入数据名字

  • 麻烦:遍历scope命名数据时候需要逐层获取到传递的数据

<slot :games='games'></slot>
<!-- 注意此时的 数据在当前子组件 -->
<Category title='游戏'>
      <template scope="games">
        <ul>
          <li v-for="(g,index) in games.games" :key='index'>{{g}}</li>
        </ul> 
      </template>
    </Category>

解决以上麻烦:

直接使用scope进行优化替换标签属性值:scope-> slot-scope

<Category title='游戏'>
      <template slot-scope={games}>       
        <h4 style="color:red" v-for="(g,index) in games" :key='index'>{{g}}</h4>
      </template>
    </Category>
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。