Vue之后端交互、计算、监听、组件间通信
一、与后端交互的多种方式
前后端要打通----> 从前端发送ajax---> 核心:使用js发送http请求,接收返回
- 原生js,可以开启ajax,但是原生js开启,比较麻烦,需要做浏览器兼容,有坑(基本不写)
-jquery,写了个兼容所有浏览器的 $.ajax(),不仅仅有ajax,还封装了很多dom操作。vue中使用它,不合适
-const xhr = new XMLHttpRequest()
Fetch和XMLHttpRequest (XHR) 都是用于在浏览器中进行网络请求的技术,它们的作用是从服务器获取数据或将数据发送到服务器
-axios:第三方的 ajax包(常用)
-fetch: 原生js发送ajax请求,有的浏览器也不兼容
1、js版本的 $.ajax()
handleLoad() { // 请求发送成功,后端执行了,但是被浏览器拦截了,因为有跨域问题 // 当前地址,如果向非浏览器地址栏中得地址发送请求,就会出现跨域 // 1 ajax请求方式 1 jquery的ajax var _this = this $.ajax({ url: 'http://127.0.0.1:5000', type: 'get', success: function (data) { console.log(typeof data) var res = JSON.parse(data) _this.name = res.name _this.age = res.age } }) }
补充: 使用箭头函数(箭头函数没有自己的this,不需要定义_this)
<script> let vm = new Vue({ el: '#box', data: { name: '', age: 0 }, methods: { handleClick() { $.ajax({ url: 'http://127.0.0.1:5000/', // 发送请求的url,本地的5000端口,是flask的默认端口 method: 'get', success: (data)=> { if (data.code == 100) { this.name=data.name this.age=data.age } // console.log(data) } }) } } }) </script>
2、axios(第三方的 ajax包)
起步 | Axios 中文文档 | Axios 中文网 (axios-http.cn)
<head> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> handleLoad() { var _this = this axios.get('http://127.0.0.1:5000').then(function (res) { console.log(res.data) _this.name = res.data.name _this.age = res.data.age }) }
补充:axios携带参数
axios.get(地址,{})
axios.post(地址,{},{headers:{token:asdasdf}})
// 引入 Axios 库 import axios from "axios"; // 定义 API 地址 const apiUrl = "https://api.example.com/endpoint"; // 替换为实际的 API 地址 // 准备要发送的数据 const requestData = { key1: "value1", // 请求体中的参数1 key2: "value2", // 请求体中的参数2 }; // 准备要添加的自定义头部 const customHeaders = { token: "asdasdf", // 替换为实际的 token 值 }; // 使用 Axios 发送 POST 请求 axios.post(apiUrl, requestData, { headers: customHeaders, // 添加自定义头部 }) .then(response => { // 请求成功时的处理 console.log("响应数据:", response.data); }) .catch(error => { // 请求失败时的处理 console.error("请求失败:", error); });
3、fetch
# fetch固定格式 fetch('http://example.com/movies.json') .then(function(response) { return response.json(); }) .then(function(myJson) { console.log(myJson); }); <script> let vm = new Vue({ el: '#box', data: { name:'', age: '', }, methods: { handleClick() { fetch('http://127.0.0.1:5000/').then(response => { return response.json() }).then(json => { console.log('从后端获取的json数据', json) // success 获取的数据 this.name = json.name this.age = json.age }).catch(ex => { console.log('出现了异常', ex) // 抛出异常 }) } } }) </script>
4、小电影案例
html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <button @click="handleLoad">点我,加载小电影</button> <hr> <ul> <li v-for="item in dataList"> <h3>电影名字:{{item.name}}</h3> <h3>导演:{{item.director}}</h3> <p>电影介绍:{{item.synopsis}}</p> <p><img :src="item.poster" alt="" height="300px"></p> </li> </ul> </div> </body> <script> var vm = new Vue({ el: '#app', data: { dataList: [] }, methods: { handleLoad() { axios.get('http://127.0.0.1:5000/films').then(res => { console.log(res.data) this.dataList = res.data.data.films }) } } }) </script> </html>
flask 后端:
import json from flask import Flask, jsonify app = Flask(__name__) @app.route('/films') def films(): with open('./filme.json', 'rt', encoding='utf-8') as f: res = json.load(f) res = jsonify(res) res.headers = {'Access-Control-Allow-Origin': '*'} return res if __name__ == '__main__': app.run()
原生django:
import json from django.http import HttpResponse, JsonResponse def films(request, *args, **kwargs): with open('filme.json', 'rt', encoding='utf-8') as f: result = json.load(f) res = {'code': 100, 'msg': '查询成功', 'result': result} aa = JsonResponse(res) aa['Access-Control-Allow-Origin'] = '*' return aa
电影json地址:
https://m.maizuo.com/v5/#/films/nowPlaying
效果:
二、计算属性
计算属性是基于它们的依赖变量进行缓存的
计算属性只有在它的相关依赖变量发生改变时才会重新求值,否则不会变(函数只要页面变化,就会重新运算)
计算属性就像Python中的property,可以把方法/函数伪装成属性
计算属性,必须有返回值
1、基本使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <h1>实现输入input中后名字首字母大写</h1> <input type="text" v-model="username"> ---> {{ getUpperCase()}} <br> <input type="text" v-model="age">---->{{ age }} <h2>通过计算属性实现--->当属性用</h2> <input type="text" v-model="username1">--->{{ getName }} </div> </body> <script> var vm = new Vue({ el: '#app', data: { username: '', age: '', username1: '' }, methods: { getUpperCase() { console.log('函数执行我执行了') return this.username.substring(0, 1).toUpperCase() + this.username.substring(1) } }, computed: { getName() { console.log('计算属性执行了') return this.username1.substring(0, 1).toUpperCase() + this.username1.substring(1) } } }) </script> </html>
补充:计算属性的关键字
在methods中写 computed,下的方法包装成属性。
return this.username1.substring(0, 1).toUpperCase() + this.username1.substring(1) ### username1.substring(0,1)截取第一个字母,.username1.substring(1) :从第二个字母截取到尾部
computed: { getName() { console.log('计算属性执行了') return this.username1.substring(0, 1).toUpperCase() + this.username1.substring(1) } }
2、
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <input type="text" v-model="search"> <hr> <ul> <li v-for="item in newdataList">{{ item }}</li> </ul> </div> </body> <script> let vm = new Vue({ el: '#app', data: { search: '', dataList: ['a', 'at', 'atom', 'attoo', 'be', 'beyond', 'cs', 'csrf'], }, computed: { newdataList() { return this.dataList.filter(item => item.indexOf(this.search) >= 0) } } }) </script> </html>
三、监听(侦听)属性
1、关键字 watch
属性如果发生变化,就会执行某个函数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <div class="container-fluid"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <div class="text-center"> <span class="btn btn-danger" @click="course_type='0'"> Python课程</span> <span class="btn btn-danger" @click="course_type='1'"> Go课程</span> <span class="btn btn-danger" @click="course_type='2'"> Linux课程</span> </div> <div> 点击了 {{course_type}} 课程类型 <br> {{course}} 课程 </div> </div> </div> </div> </div> </body> <script> var vm = new Vue({ el: '#app', data: { course: 'python', course_type: '', }, watch: { course_type() { console.log('我变了', this.course_type) if (this.course_type == 0) { this.course = 'python' } else if (this.course_type == 1) { this.course = 'Go' } else { this.course = 'Linux' } } } }) </script> </html>
四、ref属性
ref
属性允许你在 Vue 组件中获取对 DOM 元素或组件实例的引用,从而方便地访问和操作它们。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <h1>ref属性放在普通标签上</h1> <input type="text" v-model="username" ref="myinput"> <br> <img src="http://pic.imeitou.com/uploads/allimg/230331/7-230331110I0.jpg" alt="" height="300px" ref="myimg"> <h1>ref放在组件上</h1> <hr> <lqz ref="mylqz"></lqz> <hr> <button @click="handleClick">点我执行函数</button> <br> {{username}} </div> </body> <script> var vm = new Vue({ el: '#app', data: { username: '' }, methods: { handleClick() { console.log(this.$refs) // 通过key,取到标签,拿到原生dom,通过dom操作,控制标签 this.$refs.myinput.value = 'lqz' this.$refs.myimg.src='10026.jpg' // 放在组件上---》现在在父组件中,能拿到子组件对象,对象中的属性和方法直接用即可 console.log(this.$refs.mylqz) // this.$refs.mylqz.title = 'sb' // this.username=this.$refs.mylqz.title //this.$refs.mylqz.handleBack() } }, components: { lqz: { template: ` <div> <button @click="handleBack">后退</button> {{ title }} <button>前进</button> </div>`, data() { return { title: "首页" } }, methods: { handleBack() { alert('后退了') } } } } }) </script> </html>
五、Vue生命周期
1、 vue实例有生命周期,每个组件也有这8个生命周期。
# new Vue()---->创建出来---》页面关闭---》被销毁掉----》整个整个过程经历了一个周期----》vue帮咱们提供了一些钩子函数[写了就会执行,不写就不执行],到某个阶段,就会触发某个函数的执行 # 8 个生命周期钩子函数 beforeCreate 创建Vue实例之前调用 created 创建Vue实例成功后调用 beforeMount 渲染DOM之前调用 mounted 渲染DOM之后调用 beforeUpdate 重新渲染之前调用(数据更新等操作时,控制DOM重新渲染) updated 重新渲染完成之后调用 beforeDestroy 销毁之前调用 destroyed 销毁之后调用 # 8个声明周期钩子,什么情况会用到 -created:用的最多,变量初始化完成了(data中得数据),在这里,我们发送ajax请求 -beforeDestroy:组件销毁之前会执行 -组件创建,就执行一个定时任务[每隔1s,打印一个helloworld] -组件销毁,定时任务要销毁,如果定时任务不销毁,会一直执行
2、组件也有生命周期
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>生命周期</title> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script> </head> <body> <div id="box"> <child v-if="isShow"></child> <br> <button @click="terminate">删除显示子组件</button> </div> </body> <script> Vue.component('child', { template: ` <div> {{ name }} <button @click="name='lqs'">更新数据1</button> <button @click="name='asdf'">更新数据2</button> </div>`, data() { return { name: 'Darker1', t: null } }, beforeCreate() { console.group('当前状态:beforeCreate') console.log('当前el状态:', this.$el) console.log('当前data状态:', this.$data) console.log('当前name状态:', this.name) }, created() { console.group('当前状态:created') console.log('当前el状态:', this.$el) console.log('当前data状态:', this.$data) console.log('当前name状态:', this.name) // 启动一个定时器 this.t = setInterval(() => { console.log('asdfasdfasdf') }, 3000) }, beforeMount() { console.group('当前状态:beforeMount') console.log('当前el状态:', this.$el) console.log('当前data状态:', this.$data) console.log('当前name状态:', this.name) }, mounted() { console.group('当前状态:mounted') console.log('当前el状态:', this.$el) console.log('当前data状态:', this.$data) console.log('当前name状态:', this.name) }, beforeUpdate() { console.group('当前状态:beforeUpdate') console.log('当前el状态:', this.$el) console.log('当前data状态:', this.$data) console.log('当前name状态:', this.name) }, updated() { console.group('当前状态:updated') console.log('当前el状态:', this.$el) console.log('当前data状态:', this.$data) console.log('当前name状态:', this.name) }, beforeDestroy() { console.group('当前状态:beforeDestroy') console.log('当前el状态:', this.$el) console.log('当前data状态:', this.$data) console.log('当前name状态:', this.name) clearInterval(this.t) this.t = null }, destroyed() { console.group('当前状态:destroyed') console.log('当前el状态:', this.$el) console.log('当前data状态:', this.$data) console.log('当前name状态:', this.name) }, }) let vm = new Vue({ el: '#box', data: { isShow: true }, methods: { terminate() { this.isShow = !this.isShow }, }, // beforeCreate() { // console.log("vue实例,开始创建了") // console.log(this.isShow) // }, // created() { // console.log("vue实例,创建成功了") // console.log(this.$data) // 数据有了 // console.log(this.$el) // 没有 模板 // }, // beforeMount() { // console.log("vue实例,准备挂载el") // console.log(this.$data) // 数据有了 // console.log(this.$el) //模板有了,但是 插值都没渲染上 // }, // mounted() { // console.log("vue实例,挂载el了") // console.log(this.$data) // 数据有了 // console.log(this.$el) //模板有了,但是 插值都没渲染上 // }, }) // setTimeout(() => { // alert('lqz is handsome') // }, 3000) // // setInterval(()=>{ // console.log('lqz is handsome') // },5000) </script> </html>
六、组件介绍和使用
1、组件就是:扩展 HTML 元素,封装可重用的代码,目的是复用
例如:有一个轮播图,可以在很多页面中使用,一个轮播有js,css,html 组件把js,css,html放到一起,有逻辑,有样式,有html #组件的分类: 全局组件:可以放在根中,可以在所有组件中使用 局部组件:只能在当前组件中使用
2、定义全局组件
Vue.component('child', template: ``), 中child是自定义的组件名字,<child></child> 表示使用child组件,template模版中存放html页面
<script> //1 定义一个全局组件,vue2中,组件必须在一个标签中 Vue.component('child', { template: ` <div> <button @click="back">后退</button> {{ title }} <button>前进</button> </div> `, data() { return { title: '我是首页' } }, methods: { back() { console.log('退了') } } }) var vm = new Vue({ el: '#app', }) </script>
3、定义局部组件
这里lqz是一个自定义的局部组件的名字,<lqz></lqz>是应用局部组件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <h1>组件的使用</h1> <lqz></lqz> </div> </body> <script> var lqz={ template: ` <div> <h1>我是局部组件</h1> <img :src="url" alt="" height="400px"> </div>`, data() { return { url: 'http://www.qingjv.com/static/upload/image/20221021/1666333229189563.jpg' } }, methods: {} } // 根组件 var vm = new Vue({ el: '#app', data: {}, // 局部组件是定义在某个组件内,可以定义多个,只能在它父组件中使用,不能到别的地方使用 components: { lqz, } }) </script> </html>
小结:
# 1 全局组件是使用Vue.component定义的,可以在全局任意组件中使用 # 2 局部组件是定义在某个组件内的:components,只能用在当前组件中 # 3 组件可以嵌套定义和使用 # 扩展:elementui,提供给咱们很多全局组件
七、组件间通信
1、父传子: 自定义属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <h1>组件的使用</h1> <hr> <lqz :url="url" :myshow="true"></lqz> <hr> </div> </body> <script> // 2 var lqz = { template: ` <div> <h1>我是局部组件</h1> <img :src="url" alt="" height="400px"> <button @click="handleCheck">点我看myshow类型</button> </div>`, data() { return {} }, methods: { handleCheck() { console.log(this.myshow) console.log(typeof this.myshow) } }, props: ['url', 'myshow'] } // 根组件 var vm = new Vue({ el: '#app', data: { url: 'http://pic.imeitou.com/uploads/allimg/230331/7-230331110I0.jpg', }, // 局部组件是定义在某个组件内,可以定义多个,只能在它父组件中使用,不能到别的地方使用 components: { lqz, } }) </script> </html>
props的作用:
-
数据传递:
props
允许父组件将数据传递给子组件。父组件可以通过绑定属性的方式将数据传递给子组件。 -
参数配置: 除了数据,
props
也可以用于配置子组件的行为。父组件可以通过props
向子组件传递配置参数,以影响子组件的行为。 -
动态数据:
props
可以接收动态数据,这意味着父组件可以根据需要动态地更新传递给子组件的数据。 -
数据验证: Vue.js 允许你在子组件中对
props
进行验证,以确保传递的数据满足特定的要求。这有助于提高应用程序的可靠性。
2、子传父: 自定义事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <h1>组件的使用</h1> 接受到的子组件输入的内容是:{{username}} <hr> <lqz @myevent="handelEvent"></lqz> <hr> </div> </body> <script> // 2 var lqz = { template: ` <div> <h1>我是局部组件</h1> <img :src="url" alt="" height="400px"> <br> <input type="text" v-model="username"> <button @click="handleSend">传递到父组件</button> </div>`, data() { return { url: 'https://pic2.zhimg.com/v2-ab3bd9cb8ba184b2f12bbfe969036955_r.jpg', username: '' } }, methods: { handleSend() { // 传递给父组件 this.$emit('myevent', this.username) } } } // 根组件 var vm = new Vue({ el: '#app', data: { username: '' }, methods: { handelEvent(username) { console.log('父组件自定义事件的event执行了') console.log(username) this.username = username } }, // 局部组件是定义在某个组件内,可以定义多个,只能在它父组件中使用,不能到别的地方使用 components: { lqz, } }) </script> </html>
补充:
1 子传父的流程
2 $emit
的基本用法和作用:
-
触发自定义事件: 使用
$emit
方法,你可以在 Vue 组件内部触发自定义事件,这个事件可以有任何自定义名称,通常用驼峰命名规则。 -
传递数据: 除了触发事件,你还可以通过
$emit
向事件的监听器传递数据,这些数据可以是任何 JavaScript 数据类型。 -
监听事件: 父组件或其他组件可以使用
v-on
指令(或简写为@
)来监听并响应子组件触发的自定义事件。
这里属于出发自定义的事件,触发事件的同时把username传进去
八、作业记录
1、写一个books接口,带按价格排序,前端页面创建完成,向后端发送请求,获取图书属性,表格显示在前端
后端代码:
from .models import Book from rest_framework.viewsets import ModelViewSet from .serializer import BookSerializer from rest_framework.filters import OrderingFilter class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer filter_backends = [OrderingFilter] ordering_fields = ['id', 'price'] def list(self, request, *args, **kwargs): res = super().list(request, *args, **kwargs) res.headers['Access-Control-Allow-Origin'] = '*' return res ### super().list 中有 return Response(serializer.data) ### 序列化文件 from rest_framework.serializers import ModelSerializer from .models import Book class BookSerializer(ModelSerializer): class Meta: model = Book fields = "__all__"
前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <style> .text-center { text-align: center; } </style> </head> <body> <div id="app"> <div class="container-fluid"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <div class="text-center"> <button class="btn btn-primary" @click="handleClick">点我按照价格排序</button> </div> <table class="table table-bordered"> <thead> <tr> <th class="text-center">id号</th> <th class="text-center">图书名字</th> <th class="text-center">图书价格</th> </tr> </thead> <tbody> <tr v-for="item in books_list"> <th scope="row" class="text-center">{{ item.id }}</th> <td class="text-center">{{ item.title }}</td> <td class="text-center">{{ item.price }}</td> </tr> </tbody> </table> </div> </div> </div> </div> </body> <script> let vm = new Vue({ el: '#app', data: { books_list: [], ordering: 'price', url: 'http://127.0.0.1:8000/books/' }, created() { axios.get(this.url).then(res => { console.log(res.data) this.books_list = res.data }) }, methods: { handleClick() { if (this.ordering.indexOf('-') >= 0) { this.ordering = 'price' } else { this.ordering = '-price' } } }, watch: { ordering() { axios.get(this.url+'?ordering='+this.ordering).then( res => { this.books_list = res.data }) } } }) </script> </html>
备注:
1 created()生命周期:创建Vue实例成功后调用。这里vue实例创建后把后端返回的数据赋值给 books_list 列表
2 handleClick 点击事件用来动态给ordering属性赋值
3 watch 监听函数监听ordering的变化,从而修改请求地址的表达
2、定义组件,组件创建成功,向后端发送请求,后端返回一张图片地址,显示在组件上
后端:
from rest_framework.views import APIView from rest_framework.response import Response class ImageView(APIView): def get(self, request, *args, **kwargs): return Response({'code': 100, 'msg': '成功', 'url': 'http://127.0.0.1:8000/media/11.jpg/'}, headers={'Access-Control-Allow-Origin': '*'})
路由:
from django.urls import path from app01.views import ImageView from django.views.static import serve from django.conf import settings urlpatterns = [ path('admin/', admin.site.urls), path('img/', ImageView.as_view()), path('media/<path:path>', serve,{'document_root': settings.MEDIA_ROOT}), ] ## setting中配置 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
补充:
1 serve 视图函数用于定位和提供媒体文件的地方。
2 media/<path:path> 这是django3中的5中转换器之一path,转换器允许你在 Django URL 配置中更灵活地捕获不同类型的数据,并将它们传递给视图函数以进行处理。你可以根据你的项目需求选择适当的转换器。
前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <h1>组件</h1> 路径:{{a}} <hr> <lqz @myevent="handelEvent"> </lqz> <hr> </div> </body> <script> var vm = new Vue({ el: '#app', data: { a: '' }, components: { lqz: { template: ` <div> <h1>这是请求的一张图片</h1> <img :src="url" alt="" height="300px"> <br> <button @click="handleSend">传递到父组件</button> </div> `, data() { return { url: '' } }, created() { axios.get('http://127.0.0.1:8000/img/').then(res => { console.log(res) this.url = res.data.url }) }, methods: { handleSend() { this.$emit('myevent', this.url) } } } }, methods: { handelEvent(url) { this.a = url } } }) </script> </html>
效果: