vue购物车案例,v-model进阶,与后端交互,vue生命周期,vue组件
内容回顾
v-for 可以循环的类型:数字,字符串,数组,对象
js的循环方式:
基于索引的方式(i=0;i<10;i++)
in 循环出来的是索引
of 基于迭代的,循环出来就是值
$.each(数组,item=>{})
数组 forEach循环((item)=>{})
key值的解释 :key=‘唯一值’
数组的检测与更新
Vue.set(数组/对象,要添加的名字/索引,要添加的值)
input:事件
change 发生改变触发
blur 失去焦点
focus 获得焦点
click 点击事件
input 输入事件
v-model input标签上,数据双向绑定
过滤案例
数组的filtter((item)=>{return true})
字符串的indexOf 判断字符串是否在字符串中如果在大于等于0如果不在等于-1
箭头函数
var f =item=>itme++
事件修饰符
once 事件只触发一次
stop 事件不冒泡
self 只处理自己的事件
prevent 阻止a标签的跳转
按键修饰符
@keyup=‘函数’
@keyup.enter=‘函数’
@keyup.13=‘函数’
表单控制
radio:字符串类型 多个radiov-model绑定,选中某个会把value赋值给这个变量
checkbox
单选:布尔类型
多选:数组
内容详细
购物车案例
基本购物车
js的变量只要发生变化,html页面中使用该变量的地方,就会发生变化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
<link rel="stylesheet" href="bootstrap-3.4.1-dist/css/bootstrap.min.css">
</head>
<body>
<div class="app">
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1 class="text-center h1">购物车</h1>
<table class="table table-hover table-striped">
<thead>
<tr>
<td>编号</td>
<td>商品名</td>
<td>价格</td>
<td>数量</td>
<td>选择</td>
</tr>
</thead>
<tbody>
<tr v-for="item in goodsList">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>{{item.count}}</td>
<td><input type="checkbox" v-model="checkbox" :value="item" :key="item.id"></td>
</tr>
</tbody>
</table>
总价格:{{handlerTotal()}}
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
checkbox: [],
goodsList: [
{id: 1, name: '张三', price: 88, count: '102'},
{id: 2, name: '王五', price: 1, count: '16'},
{id: 3, name: '金苹果', price: 28, count: '62'},
{id: 4, name: '香蕉', price: 46, count: '22'},
{id: 5, name: '李四', price: 100, count: '182'},
]
},
methods: {
handlerTotal() {
total = 0
for (item of this.checkbox) {
total += item.price * item.count
}
return total
},
}
})
</script>
</html>
购物车带全选全不选
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
<link rel="stylesheet" href="bootstrap-3.4.1-dist/css/bootstrap.min.css">
</head>
<body>
<div class="app">
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1 class="text-center h1">购物车</h1>
<table class="table table-hover table-striped">
<thead>
<tr>
<td>编号</td>
<td>商品名</td>
<td>价格</td>
<td>数量</td>
<td>全选/全不全 <input type="checkbox" @change="handlerAll" v-model="allSelect"></td>
</tr>
</thead>
<tbody>
<tr v-for="item in goodsList">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>{{item.count}}</td>
<td><input type="checkbox" @change="handlerOne" v-model="checkbox" :value="item" :key="item.id">
</td>
</tr>
</tbody>
</table>
总价格:{{handlerTotal()}}
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
checkbox: [],
allSelect: false,
goodsList: [
{id: 1, name: '张三', price: 88, count: '102'},
{id: 2, name: '王五', price: 1, count: '16'},
{id: 3, name: '金苹果', price: 28, count: '62'},
{id: 4, name: '香蕉', price: 46, count: '22'},
{id: 5, name: '李四', price: 100, count: '182'},
]
},
methods: {
handlerTotal() {
total = 0
for (item of this.checkbox) {
total += item.price * item.count
}
return total
},
handlerAll() {
// if (this.allSelect) {
// this.checkbox = this.goodsList
// } else {
// this.checkbox = []
// }
//三目运算
this.allSelect ? this.checkbox = this.goodsList : this.checkbox = []
},
handlerOne() {
// if (this.checkbox.length != this.goodsList.length) {
// this.allSelect = false
// } else {
// this.allSelect = true
// }
//三目运算
this.checkbox.length != this.goodsList.length ? this.allSelect = false : this.allSelect = true
},
}
})
</script>
</html>
购物车带加减
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
<link rel="stylesheet" href="bootstrap-3.4.1-dist/css/bootstrap.min.css">
</head>
<body>
<div class="app">
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1 class="text-center h1">购物车</h1>
<table class="table table-hover table-striped">
<thead>
<tr>
<td>编号</td>
<td>商品名</td>
<td>价格</td>
<td>数量</td>
<td>库存</td>
<td>全选/全不全 <input type="checkbox" @change="handlerAll" v-model="allSelect"></td>
</tr>
</thead>
<tbody>
<tr v-for="item in goodsList">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>
{{item.price}}
</td>
<td>
<button class="btn btn-warning" @click="handlerSub(item)">-</button>
{{item.count}}
<button class="btn btn-success" @click="handlerAdd(item)">+</button>
</td>
<td>{{item.ck}}</td>
<td><input type="checkbox" @change="handlerOne" v-model="checkbox" :value="item" :key="item.id">
</td>
</tr>
</tbody>
</table>
总价格:{{handlerTotal()}}
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
checkbox: [],
allSelect: false,
goodsList: [
{id: 1, name: '张三', price: 88, count: '95', ck: 10},
{id: 2, name: '王五', price: 1, count: '16', ck: 3},
{id: 3, name: '金苹果', price: 28, count: '62', ck: 8},
{id: 4, name: '香蕉', price: 46, count: '22', ck: 20},
{id: 5, name: '李四', price: 100, count: '182', ck: 2},
]
},
methods: {
handlerTotal() {
total = 0
for (item of this.checkbox) {
total += item.price * item.count
}
return total
},
handlerAll() {
// if (this.allSelect) {
// this.checkbox = this.goodsList
// } else {
// this.checkbox = []
// }
//三目运算
this.allSelect ? this.checkbox = this.goodsList : this.checkbox = []
},
handlerOne() {
// if (this.checkbox.length != this.goodsList.length) {
// this.allSelect = false
// } else {
// this.allSelect = true
// }
//三目运算
this.checkbox.length != this.goodsList.length ? this.allSelect = false : this.allSelect = true
},
handlerSub(item) {
if (item.count > 1) {
item.count--
item.ck++
}
},
handlerAdd(item) {
if (item.ck > 0) {
item.count++
item.ck--
}
},
}
})
</script>
</html>
购物车带删除
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
<link rel="stylesheet" href="bootstrap-3.4.1-dist/css/bootstrap.min.css">
</head>
<body>
<div class="app">
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1 class="text-center h1">购物车</h1>
<table class="table table-hover table-striped">
<thead>
<tr>
<td>编号</td>
<td>商品名</td>
<td>价格</td>
<td>数量</td>
<td>库存</td>
<td>全选/全不全 <input type="checkbox" @change="handlerAll" v-model="allSelect"></td>
<td>删除商品</td>
</tr>
</thead>
<tbody>
<tr v-for="item in goodsList">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>
{{item.price}}
</td>
<td>
<button class="btn btn-warning" @click="handlerSub(item)">-</button>
{{item.count}}
<button class="btn btn-success" @click="handlerAdd(item)">+</button>
</td>
<td>{{item.ck}}</td>
<td><input type="checkbox" @change="handlerOne" v-model="checkbox" :value="item" :key="item.id">
</td>
<td>
<button class="btn btn-danger" @click="handlerDelete(item)">删除商品</button>
</td>
</tr>
</tbody>
</table>
总价格:{{handlerTotal()}}
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
checkbox: [],
allSelect: false,
goodsList: [
{id: 1, name: '张三', price: 88, count: '95', ck: 10},
{id: 2, name: '王五', price: 1, count: '16', ck: 3},
{id: 3, name: '金苹果', price: 28, count: '62', ck: 8},
{id: 4, name: '香蕉', price: 46, count: '2', ck: 20},
{id: 5, name: '李四', price: 100, count: '182', ck: 2},
]
},
methods: {
handlerTotal() {
total = 0
for (item of this.checkbox) {
total += item.price * item.count
}
return total
},
handlerAll() {
// if (this.allSelect) {
// this.checkbox = this.goodsList
// } else {
// this.checkbox = []
// }
//三目运算
this.allSelect ? this.checkbox = this.goodsList : this.checkbox = []
},
handlerOne() {
// if (this.checkbox.length != this.goodsList.length) {
// this.allSelect = false
// } else {
// this.allSelect = true
// }
//三目运算
this.checkbox.length != this.goodsList.length ? this.allSelect = false : this.allSelect = true
},
handlerSub(item) {
if (item.count > 1) {
item.count--
item.ck++
} else {
alert('最少一个商品不能在减啦!!!')
}
},
handlerAdd(item) {
if (item.ck > 0) {
item.count++
item.ck--
} else {
alert('商品已经被你买光了,不能在加了!!!')
}
},
handlerDelete(item) {
this.goodsList = this.goodsList.filter(value => value != item)
this.checkbox = this.checkbox.filter(value => value != item)
},
}
})
</script>
</html>
v-model进阶
lazy:等待input框的数据绑定失去焦点之后再变化:类似于change事件
number:数字开头,只保留数字,后面的字母不保留;字母开头,都保留
trim:取出首尾空格,再用户输入账号密码的时候可以用到
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div class="app">
<h2>v-model默认</h2>
<input type="text" v-model="vardefault">--------->{{vardefault}}
<hr>
<h2>v-model lazy</h2>
<input type="text" v-model.lazy="varlazy">--------->{{varlazy}}
<hr>
<h2>v-model number</h2>
<input type="text" v-model.number="varnumber">--------->{{varnumber}}
<hr>
<h2>v-model trim</h2>
<input type="text" v-model.trim="vartrim">--------->{{vartrim}}
<hr>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
vardefault: '',
varlazy: '',
varnumber: '',
vartrim: '',
},
methods: {}
})
</script>
</html>
与后端交互
跨域问题
浏览器的原因,只要不向不是地址栏中的【域:地址和端口】发生请求,拿的数据,浏览器就给拦截了
处理跨域问题
后端代码处理–》只需要再响应头中加入允许即可
jq的ajax
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
<link rel="stylesheet" href="./bootstrap-3.4.1-dist/css/bootstrap.min.css">
</head>
<body>
<div class="app">
<button class="btn btn-success" @click="handlerClick">发生请求</button>
<div v-if="userinfo.username">
<p>姓名:{{userinfo.username}}</p>
<p>年龄:{{userinfo.age}}</p>
<p>性别:{{userinfo.gender}}</p>
<p>爱好:
<ul>
<li v-for="item in userinfo.hobby">
{{item.name}}
</li>
</ul>
</p>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
userinfo: {},
},
methods: {
handlerClick() {
$.ajax({
url: 'http://127.0.0.1:8000/get_userinfo/',
type: 'get',
success: (item) => {
//使用箭头函数解决this问题
this.userinfo = item.data
}
})
},
}
})
</script>
</html>
from django.shortcuts import render
from django.http import JsonResponse
# Create your views here.
from django.views import View
from .models import UserInfo
from django.core.serializers import serialize
def get_userinfo(request):
if request.method == 'GET':
id = request.GET.get('id')
if id:
res = UserInfo.objects.filter(id=id).first()
else:
res = UserInfo.objects.filter(id=1).first()
res = {
'username': res.username,
'password': res.password,
'age': res.age,
'gender': res.get_gender_display(),
'hobby': [{'name': i.name} for i in res.hobby.all()]
}
res = {
'code': 100,
'msg': '成功',
'data': res
}
res = JsonResponse(res, safe=False)
res['Access-Control-Allow-Origin'] = '*'
return res
flask
from flask import Flask, jsonify, make_response
app = Flask(__name__)
@app.route('/')
def index():
print('执行了')
res = make_response(jsonify({'name': '彭于晏', 'age': 19, 'gender': 'male'}))
res.headers['Access-Control-Allow-Origin'] = '*' # 把这个key和value加入到响应头,就没有跨域问题了
return res
if __name__ == '__main__':
app.run()
fetch发生ajax请求
fetch提供了一个javaScript接口,用于访问和操作http管道的一些具体部分,例如请求和响应
新的发生ajax接口
用起来比较方便
支持promise写法【最新的异步写法】
解决了元素XMLHttpRequest兼容性的问题
不是所有浏览器都支持
主流现在是用axios【第三方】发生请求
XMLHttpRequest:原生js提供的
比较老,不同浏览器需要做一些兼容性的处理,写起来比较麻烦
jquery基于他做了封装
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
<link rel="stylesheet" href="./bootstrap-3.4.1-dist/css/bootstrap.min.css">
</head>
<body>
<div class="app">
<button class="btn btn-success" @click="handlerClick">发生请求</button>
<div v-if="userinfo.username">
<p>姓名:{{userinfo.username}}</p>
<p>年龄:{{userinfo.age}}</p>
<p>性别:{{userinfo.gender}}</p>
<p>爱好:
<ul>
<li v-for="item in userinfo.hobby">
{{item.name}}
</li>
</ul>
</p>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
userinfo: {},
},
methods: {
handlerClick() {
fetch('http://127.0.0.1:8000/get_userinfo/').then((item)=>{return item.json()}).then((item)=>{
this.userinfo=item.data
})
// $.ajax({
// url: 'http://127.0.0.1:8000/get_userinfo/',
// type: 'get',
// success: (item) => {
// //使用箭头函数解决this问题
// this.userinfo = item.data
// }
// })
},
}
})
</script>
</html>
axios发送ajxa请求
以后都用它,再vue上,第三方模块
axios是一个基于promise的HTTP库,还是基于XMLHttpRequest封装的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
<link rel="stylesheet" href="./bootstrap-3.4.1-dist/css/bootstrap.min.css">
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.2/axios.js"></script>
</head>
<body>
<div class="app">
<button class="btn btn-success" @click="handlerClick">发生请求</button>
<div v-if="userinfo.username">
<p>姓名:{{userinfo.username}}</p>
<p>年龄:{{userinfo.age}}</p>
<p>性别:{{userinfo.gender}}</p>
<p>爱好:
<ul>
<li v-for="item in userinfo.hobby">
{{item.name}}
</li>
</ul>
</p>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
userinfo: {},
},
methods: {
handlerClick() {
axios.get('http://127.0.0.1:8000/get_userinfo/').then(item=>{
this.userinfo = item.data.data
console.log('axions方式')
})
// fetch('http://127.0.0.1:8000/get_userinfo/').then((item) => {
// return item.json()
// }).then((item) => {
// this.userinfo = item.data
// })
// $.ajax({
// url: 'http://127.0.0.1:8000/get_userinfo/',
// type: 'get',
// success: (item) => {
// //使用箭头函数解决this问题
// this.userinfo = item.data
// }
// })
},
}
})
</script>
</html>
小电影
https://m.maizuo.com/v5/?co=mzmovie#/films/nowPlaying
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
<link rel="stylesheet" href="./bootstrap-3.4.1-dist/css/bootstrap.min.css">
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.2/axios.js"></script>
</head>
<body>
<div class="app">
<h1>小电影</h1>
<button class="btn btn-success" @click="handlerClick">发送请求</button>
<div v-if="datas.length>0">
<div v-for="data in datas">
<p>电影名:{{data.name}}</p>
<img :src="data.poster" width="200px" height="300px" alt="">
<p>分类:{{data.director}}</p>
<p>电影简介:{{data.synopsis}}</p>
<p>导演:
<ul>
<li v-for="item in data.actors">
{{item.name}}
</li>
</ul>
</p>
<hr>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
datas: {},
},
methods: {
handlerClick() {
axios.get('http://127.0.0.1:8000/file/').then(item => {
console.log(item.data.data.films)
this.datas = item.data.data.films
console.log('axions方式', this.datas)
})
// fetch('http://127.0.0.1:8000/get_userinfo/').then((item) => {
// return item.json()
// }).then((item) => {
// this.userinfo = item.data
// })
// $.ajax({
// url: 'http://127.0.0.1:8000/get_userinfo/',
// type: 'get',
// success: (item) => {
// //使用箭头函数解决this问题
// this.userinfo = item.data
// }
// })
},
}
})
</script>
</html>
from django.shortcuts import render
# Create your views here.
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
import json
from rest_framework.decorators import action
from django.conf import settings
import os
class File(ViewSet):
# @action(methods=['GET'], detail=False)
def list(self, request):
with open(os.path.join(settings.BASE_DIR, 'app01', 'file.json'), 'r', encoding='utf-8') as f:
res = json.load(f)
return Response(res, headers={'Access-Control-Allow-Origin': '*'})
flask
from flask import Flask, jsonify, make_response
import json
app = Flask(__name__)
@app.route('/')
def index():
print('执行了')
# res = make_response(jsonify({'name': '彭于晏', 'age': 19, 'gender': 'male'}))
res = make_response(jsonify({'code': 100, 'msg': '成功', 'data': {'name': '彭于晏', 'age': 19, 'gender': 'male'}}))
res.headers['Access-Control-Allow-Origin'] = '*' # 把这个key和value加入到响应头,就没有跨域问题了
return res
@app.route('/film')
def film():
with open('./film.json', 'r', encoding='utf-8') as f:
res_dict = json.load(f)
res = make_response(jsonify(res_dict))
res.headers['Access-Control-Allow-Origin'] = '*' # 把这个key和value加入到响应头,就没有跨域问题了
return res
if __name__ == '__main__':
app.run()
vue生命周期
从vue实例创建开始,到实例被销毁,总共经历了8个生命周期钩子【只要写了就会执行】函数
钩子:反序列化验证–》钩子函数
学名【专门的名字】–》面向切面编程(aop)
oop:面向对象编程
8个生命周期钩子函数
beforeCreate 创建vue实例之前调用
created 创建Vue实例成功之后调用(可以再此处发送异步请求后端数据)
beforeMount 渲染DOM之前调用
mounted 渲染DOM之后调用
beforeUpdate 重新渲染之前调用(数据更新等操作是,控制DOM重新渲染)
updated 重新渲染完成之后调用
beforeDestroy 销毁之前调用
destroyed 销毁之后调用
理解图
重点
用的最多的,created发送ajax请求,–》有的人放在mounted中加载
beforeDestroy
组件一创建,created中启动一个定时器
组件被销毁,beforeDestroy销毁定时器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div class="app">
<div class="app">
<button @click="handlerClick">点我显示或关闭</button>
<childs v-if="show"></childs>
</div>
</div>
</body>
<script>
Vue.component('childs', {
template: `
<div>{{name}}
<p @click="handler">点我改变name</p>
</div>
`,
data() {
return {name: '123'}
},
methods: {
handler() {
this.name = 111
}
},
//创建Vue对象之前执行的
//实例化Vue对象的首先执行的相当于申请了一块内存地址
beforeCreate() {
console.group('准备创建实例了')
console.log(this.$el, this.$data, this.name)
},
//创建Vue对象完毕执行的
//这个相当于把要托管的标签名与内部的一些数据进行绑定
created() {
console.group('实例创建过了')
console.log(this.$el, this.$data, this.name)
},
//这个是相当于进行页面渲染之前执行
beforeMount() {
console.group('准备渲染页面了')
console.log(this.$el, this.$data, this.name)
},
//这个是页面渲染完毕后执行,这个el就托管了模板字符串的标签了
mounted() {
console.group('页面渲染过了')
console.log(this.$el, this.$data, this.name)
},
//这个是在检测的数据变化要进行数据更新之前要做的操作
beforeUpdate() {
console.group('准备更新数据了')
console.log(this.$el, this.$data, this.name)
},
//这个是数据变化之后的要做的
updated() {
console.group('数据更新过了')
console.log(this.$el, this.$data, this.name)
},
//这个是这个Vue对象要被销毁之前做操作
beforeDestroy() {
console.group('准备删除实例了')
console.log(this.$el, this.$data, this.name)
},
//这个是Vue对象被销毁之后做的操作
destroyed() {
console.group('实例删除过了')
console.log(this.$el, this.$data, this.name)
},
})
var vm = new Vue({
el: '.app',
data: {
show: true
},
methods: {
handlerClick() {
this.show = !this.show
},
},
})
</script>
</html>
实现实时聊天效果(在线聊天室)
-轮询:定时器+ajax http:http版本区别
-长轮询:定时器+ajax http
-websocket协议:服务端主动推送消息
https://zhuanlan.zhihu.com/p/371500343
vue组件
组件化开发的好处,重用代码
组件分类:
全局组件:在任意组件中都可以使用
局部组件:只能再当前组件中使用
定义全局组件
小坑
全局组件如果用到多个变量就需要包起来如果不包起来就会报错
报错
template: `
<div>hahahha{{ name }}
<p @click="handler">123</p>
</div>
{{ name }}
`,
这样就不报错了
template: `
<div>hahahha{{ name }}
<p @click="handler">123</p>
{{ name }}
</div>
`,
局部组件
局部定义的变量只能在模板字符串内使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<child></child>
</div>
</body>
<script>
Vue.component('child', {
template: `
<div>
{{ name }}
<br>
<child1>
</child1>
{{name}}
</div>
`,
data() {
return {
name: '张三',
}
},
components: {
child1: {
template: `
<div>
{{ age }}
</div>
`,
data() {
return {
age: 13
}
},
}
}
})
var vm = new Vue({
el: '#app',
data: {},
methods: {}
})
</script>
</html>