表单指令 v-model 设置属性值
1.语法: v-model='控制value值的变量'
2. :value='变量'(属性指令),直接这样绑定数据不会实时更新数据(修改表单标签值,值不会实时映射给绑定变量)
3. v-model='变量'(表单指令),绑定的数据会实时更新(修改表单标签值,值会实时映射给绑定变量)
4. 单一复选框作为确认框时,v-model绑定的变量值为布尔类型,true代表选上该框,false则相反
5. 多个复选框时,v-model绑定的变量值是一个数据(可以看成列表),里面存放的数据是复选框中的value属性的对应值(放了谁,谁就会被选中)
6.单选框时, v-model绑定的变量值是单选框中value属性对应的值(里面放了谁,谁就会被选中)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>表单指令</title>
</head>
<body>
<div id="app">
<form action="">
<!--表单指令语法: v-model='变量'-->
<!--普通表单元素,用 v-model绑定的变量控制的是表单元素的value值-->
<input type="text" v-model="v1">
<input type="text" v-model="v2">
<textarea name="" id="" cols="30" rows="10" v-model="v1"></textarea>
<p>{{ v1 }}</p> <!--通过表单指令,可以实时更新标签值,输入框v1值变,我也变,实时更新-->
<hr>
<p>{{ v2 }}</p>
<hr>
<!--单一复选框-->
同意:
<input type="checkbox" name="agree" v-model="v3">
<hr>
<!--多个复选框-->
男:<input type="checkbox" name="hobbies" value="male" v-model="v4">
女:<input type="checkbox" name="hobbies" value="female" v-model="v4">
哇塞:<input type="checkbox" name="hobbies" value="others" v-model="v4">
<p>{{ v4 }}</p>
<hr>
<!--单选框-->
中午吃啥:<br>
肉:<input type="radio" name="food" value="rou" v-model="v5">
菜:<input type="radio" name="food" value="cai" v-model="v5">
</form>
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 1. 先产生Vue实例
new Vue({
el: '#app',
data:{
//普通表单元素
// v1: '我是变量一',
v1: '',
v2: '我是变量二',
//单一复选框
// v3: true // 给变量赋一个布尔值,true就会默认选上
v3: false, // false默认不选
//多个复选框
// v4: ['male', 'others'],
v4: ['male', 'female', 'others'], // 复选框的绑定变量的值是一个数组(列表),里面放的是复选框的value属性的值,放了谁,谁就会被选上
//单选框
// v5: 'cai',
v5: 'rou' // 单选框的绑定变量的值是单选框的value属性的值,放了谁,谁就会被选上
}
})
</script>
</html>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.p1 {
500px;
height: 21px;
background-color: orange;
}
</style>
</head>
<body>
<div id="app">
<form action="">
<!--1) 对表单标签value进行绑定操作变量,不能时时检测绑定的变量-->
<input class="inp1" type="text" :value="info">
<input class="inp2" type="text" :value="info">
<p class="p1">{{ info }}</p>
<hr>
<!--2) 表单标签的值由 v-model="变量" 来绑定控制,操作的还是value,但是拥有时时变量值的检测 -->
<input class="inp1" type="text" v-model="info">
<input class="inp2" type="text" v-model="info">
<p class="p1">{{ info }}</p>
<hr>
<!-- 2) v-model操作单独复选框 - 确认框 -->
是否同意:<input type="checkbox" name="agree" v-model="isAgree">
<!--是否同意:<input type="checkbox" name="agree" true-value="yes" false-value="no" v-model="isAgree">-->
<p>{{ isAgree }}</p>
<!-- 3) 单选框-->
性取向:
男 <input type="radio" name="sex" value="male" v-model="mysex">
女 <input type="radio" name="sex" value="female" v-model="mysex">
哇塞 <input type="radio" name="sex" value="others" v-model="mysex">
<p>{{ mysex }}</p>
<!-- 4) 复选框-->
兴趣爱好:
男 <input type="checkbox" name="hobbies" value="male" v-model="myhobbies">
女 <input type="checkbox" name="hobbies" value="female" v-model="myhobbies">
哇塞 <input type="checkbox" name="hobbies" value="others" v-model="myhobbies">
<p>{{ myhobbies }}</p>
<hr>
<input type="submit">
</form>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
info: '123',
isAgree: 0,
// isAgree: 'no',
mysex: 'others',
myhobbies: ['male', 'female']
}
})
</script>
</html>
斗篷指令 v-cloak
1.斗篷指令作用:防止页面闪烁
不处理情况下,由于我们的vue导入一般都是在页面的最后面(body后面),而每次打开该页面时,代码从上往下运行,会先渲染到{{ }},由于还没有被解析,页面会闪烁一下,当vue环境加载成功后,{{ }}才会被解析消失
处理后,vue环境没被加载好时,#app是被隐藏的,当vue环境加载成功后,会依次#app的v-cloak属性,就不会出现{{ }}渲染闪烁问题。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>斗篷指令</title>
<!--定义一个style标签,固定书写-->
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<!--引用定义的 v-cloak样式-->
<div id="app" v-cloak>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
<p>{{ msg }}</p>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
msg: '我是斗篷指令'
}
})
</script>
</html>
**条件指令 **
v-if / v-show
v-if="false",为假时,在页面上不渲染,可以隐藏标签中的信息
v-show="false",为假时,在页面中用display: none渲染(隐藏),虽然没显示,但是任在页面结构
两种都是可以控制标签的显隐,绑定的值是布尔类型的值,当布尔值是false时,就是隐藏标签,当隐藏标签的时候
v-if 是不渲染标签
v-show以display:none方式渲染
**v-if / v-else-if / v-else **
v-if='变量'
v-else-if='变量'
v-else
一组分支,上分支成立会屏蔽掉下方所有分支,v-else分支没有条件,当所有的上分支都不成立时才显示v-else分支
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>条件指令</title>
</head>
<body>
<div id="app">
<!--条件指令-->
<!--v-if="false",为假时,在页面上不渲染,可以隐藏标签中的信息-->
<!--v-show="false",为假时,在页面中用display: none渲染(隐藏),虽然没显示,但是任在页面结构中-->
<p v-if="true">if指令true</p>
<p v-if="false">if指令false</p>
<p v-show="true">shoe指令true</p>
<p v-show="false">show指令false</p>
<!--v-if是一个家族,有:
v-if
v-else-if
v-else
有以下特点:
1.上分支成立,下分支会被屏蔽
2.else分支只有在所有上分支都为假时才显示,且不需要条件-->
<p v-if="v1==='1'">if分支</p>
<p v-else-if="v1==='2'">else_if分支</p>
<p v-els>else分支</p>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
// v1: '1'
// v1: '2'
v1: '3'
}
})
</script>
</html>
条件指令小案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>条件指令案例</title>
<style>
.box{
400px;
height: 200px;
}
.r{
background-color: red;
}
.y{
background-color: yellow;
}
.g{
background-color: green;
}
/*显示高亮,给一个背景颜色,谁拿到这个属性,谁就是高亮*/
.action{
background-color: pink;
}
</style>
</head>
<body>
<div id="app">
<!--<p>-->
<!--通过判断 action属性有没有效来判断谁是高亮-->
<!--<button @click="changeC('red')" :class="{action: c === 'red'}">红</button>-->
<!--<button @click="changeC('yellow')" :class="{action: c === 'yellow'}">黄</button>-->
<!--<button @click="changeC('green')" :class="{action: c === 'green'}">绿</button>-->
<!--</p>-->
<p>
<button @click="changeC('red')">红</button>
<button @click="changeC('yellow')" >黄</button>
<button @click="changeC('green')" >绿</button>
</p>
<div class="wrap">
<div class="box r" v-if="c ==='red'"></div>
<div class="box y" v-else-if="c === 'yellow'"></div>
<div class="box g" v-else></div>
</div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
// sessionStorage的生命周期与页面标签绑定,当标签页被关闭,数据库被清空
// localStorage是前台永久数据库
// sessionStorage.name = '123';
// localStorage.name = 'xyz';
// localStorage.clear();
new Vue({
el: '#app',
data:{
// c: 'red'
// 页面重新刷新加载,可以从数据库中获取缓存,如果没有,再取默认值
c: localStorage.c ? localStorage.c : 'red',
},
methods:{
changeC(color){
this.c = color;
// 每一次改变c的值,将值同步到前台数据库
localStorage.c = color; // 存在永久数据库中
}
}
})
</script>
</html>
循环指令 v-for
1) 遍历字符串:可以只逐一遍历字符,也可以连同遍历索引
<p v-for="ch in str"></p> | <p v-for="(ch, index) in str"></p>
2) 遍历数组:可以只逐一遍历成员元素,也可以连同遍历索引
<p v-for="ele in arr"></p> | <p v-for="(ele, index) in arr"></p>
3) 遍历字典:可以只逐一遍历值(value),也可以连同遍历成员键(key),还可以遍历成员key索引
依次遍历value,key,key索引
<p v-for="v in dic"></p> | <p v-for="(v,k) in arr"></p> | <p v-for="(v,k,i) in arr"></p>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>循环指令</title>
</head>
<body>
<div id="app">
<!--循环指令
v-for=""
语法:v-for="成员 in 容器"-->
<!--字符串循环渲染: 可以只遍历值,也可以遍历值与索引-->
<p>
<span v-for="v in title">{{ v }}</span>
</p>
<p>
<!--<span v-for="v in title">|{{ v }}</span>-->
<span v-for="(v, i) in title"><span v-if="i !=0" > | </span>{{ v }}</span>
</p>
<!--数组循环渲染:可以只遍历值,也可以遍历值和索引-->
<div>
<!--<p v-for="v in arr">{{ v }}</p>-->
<!--第一个参数永远代表值-->
<!--<p v-for="(v, i) in arr">第{{ i }}元素:{{ v }}</p>-->
</div>
<!--对象循环渲染:可以只遍历值,也可以遍历值与键,还可以遍历值、键、索引-->
<div>
<!--遍历值value-->
<!--<p v-for="v in people">{{ v }}</p>-->
<!--遍历值与键, 第一个参数永远代表值-->
<!--<p v-for="(v, k) in people">{{ k }}:{{ v }}</p>-->
<!--遍历值、键、索引-->
<p v-for="(v, k, i) in people">{{ i }}-{{ k }}:{{ v }}</p>
</div>
<br>
<div>
<div v-for="(stu, i) in stus">
<hr v-if="i != 0">
<p v-for="(v, k) in stu">{{ i }}-{{ k }}:{{ v }}</p>
</div>
</div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
title: '循环指令',
arr: [1,2,3,4],
people: {
name: '兔子',
age: 18,
price: 6.66
},
stus: [
{
name: "Bob",
age: 18
},
{
name: "Tom",
age: 17
},
{
name: "Jerry",
age: 19
}
]
}
})
</script>
</html>
<div id="app">
<div>
<span v-for="ch in str">{{ ch }}</span> #循环字符串
</div>
<div>
<!--针对循环遍历的标签,通过会提供key属性来优化渲染速度,但key的值必须唯一(key可以不用提供) -->
<span v-for="(ch, i) in str" :key="ch + i">{{ i }}{{ ch }}</span>
</div>
<div>
<p v-for="(ele, i) in arr">{{ i }}{{ ele }}</p> #循环数组
</div>
<div>
<p v-for="ele in dic">{{ ele }}</p> #循环字典
</div>
<div>
<p v-for="(ele, k) in dic">{{ k }}:{{ ele }}</p>
</div>
<div>
<p v-for="(ele, k, i) in dic">{{ i }}{{ k }}:{{ ele }}</p> #依次取出字典的value,key,key索引
</div>
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
str: 'abc123呵呵',
arr: [3, 4, 1, 2, 5],
dic: {
name: 'Tank',
age: 80,
gender: '哇塞',
}
}
})
</script>
循环案列
留言板案例
1) 留言就是往留言数组中添加数据,删除留言就是从留言数组中移除数据
2) 前台数据库:localStorage 和 sessionStorage
localStorage永久保存数据 (这次案例以localStroage保存)
sessionStorage临时保存数据(当所属页面标签被关闭,数据被清空)
3) 前台localStorage 和 sessionStorage数据库存储的值是字符串类型,所以要存放arr、dic等复杂数据需要JSON参与
点击留言按钮就把输入框中的留言保存在下面,再点击留言就是删除
push是尾增,unshift是首增
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title></title>
<style>
li:hover {
color: red;
cursor: pointer;
}
</style>
</head>
<body>
<div id="app">
<p>
<input type="text" v-model="userMsg"> #获取输入框的值userMsg并且传递给data
<button type="button" @click="sendMsg">留言</button>
</p>
<ul>
<li v-for="(msg, index) in msgs" @click="deleteMsg(index)">
{{ msg }}
</li>
</ul>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
msgs: localStorage.msgs ? JSON.parse(localStorage.msgs) : [], // 从数据库中取出所有留言,没有就显示[]
userMsg: '', // 用户留言
},
methods: {
sendMsg() { // 留言事件
// 尾增
// this.msgs.push(this.userMsg);
// 首增
// this.msgs.unshift(this.userMsg);
let userMsg = this.userMsg;
if (userMsg) { //判断用户输入的留言是否存在
this.msgs.unshift(userMsg); // 渲染给页面
localStorage.msgs = JSON.stringify(this.msgs); // 同步到数据库
this.userMsg = ''; // 清空留言框
}
},
deleteMsg(index) { //删除操作
// 开始索引 操作长度 操作的结果们 (括号里面三个参数,最后一个参数操作的结果不写就是删除的意思)
this.msgs.splice(index, 1)
}
}
})
</script>
</html>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<input type="text" v-model="msg">
<button @click="send_comment">留言</button>
<ul>
<li v-for="(v, i) in comments" @click="deleteMsg(i)">{{ v }}</li>
</ul>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
msg: '',
comments: []
},
methods: {
send_comment() {
// 数组的增
// push pop unshift shift splice
// this.comments.unshift(this.msg);
// this.comments.splice(0,0,0);
if (this.msg) {
this.comments.push(this.msg); // 留言
this.msg = ''; // 留言后清空输入框
}
},
deleteMsg(index) {
this.comments.splice(index, 1);
}
}
})
</script>
<script>
// 数组操作万能方法,可以完成增删改
let arr = [1, 2, 3];
// 参数:开始索引,操作长度,操作的结果们
arr.splice(2, 0, 100);
arr.splice(1, 1);
console.log(arr);
</script>
</html>
分隔符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>分隔符</title>
</head>
<body>
<div id="app">
<!--先要求不要vue进行渲染,要采用分隔符-->
<p>{{ num }}</p>
<hr>
<!--如以下定义有分隔符就要采用分隔符形式书写才会被渲染-->
<p>{ num ]}</p>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
num: 100
},
// 用来修改插值表达式符号
delimiters: ['{',']}']
})
</script>
</html>
计算属性成员
1.computed是用来声明 方法属性 的
2. 声明的方法属性不能在 data 中重复定义
3. 方法属性必须在页面中渲染使用,才会对内部出现的所有变量进行监听
4.计算属性的值来源于监听方法的返回值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>计算成员属性</title>
</head>
<body>
<div id="app">
<input type="text" v-model="v1">
+
<input type="text" v-model="v2">
=
<button>{{ res }}</button>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
v1: '',
v2: '',
// res: '结果' computed中定义了data中就不需要定义
},
//1. computed中定义的是方法属性,data中定义的也是方法属性,所以不需要重复定义(省去data中)
//2. 方式属性的值来源于绑定的方法的返回值
//3.方法属性必须在页面中渲染后,绑定的方法才会被调用
//4.方法中出现的所有变量都会被监听,任何变量发生值更新都会调用一次绑定方法,重新更新一下方法属性的值
//5. 方法属性值不能手动设置,必须通过绑定的方法进行设置
computed:{
// 这里的 res 相当于一个函数方法
res() {
// this.v1、this.v2 拿到的值是字符串,转换成数字用+号:+this.v1、+this.v2
return this.v1 && this.v2 ? +this.v1 + +this.v2: '结果'
}
}
})
</script>
</html>
把两个输入框的值合并,用{{flName}}渲染出来
<div id="app">
姓:<input type="text" v-model="fName">
名:<input type="text" v-model="lName">
姓名:<b>{{ flName }}</b>
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
fName: '',
lName: '',
},
computed: {
flName(){
// this.fName和this.lName有值发送改变,该方法都会被调用
// 变量flName的值是由函数的返回值决定
return this.fName + this.lName;
}
}
})
</script>
监听实例 watch
1.watch为data中已存在的属性设置监听方法
2.监听的属性值发生改变,就会触发监听方法
3.监听方法的返回值没有意义
监听一个值,然后拆分两份
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>属性监听</title>
</head>
<body>
<div id="app">
<p>
姓名:<input type="text" v-model="full_name">
</p>
<p>
姓:<span>{{ first_name }}</span>
</p>
<p>
名:<span>{{ last_name }}</span>
</p>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
full_name: '',
first_name: '',
last_name: ''
},
watch:{
//1.watch中给已有的属性设置监听方法
//2.监听的属性值一旦发生更新,就会调用监听方法,在方法中完成相应逻辑
//3.监听方法不需要返回值(返回值只有主动结束方法的作用)
full_name(){
// fullName值改变,就会调用绑定的事件方法
if (this.full_name.length === 2){
k_v_arr = this.full_name.split('');
this.first_name = k_v_arr[0];
this.last_name = k_v_arr[1]
}
}
}
})
</script>
</html>
组件
// 1) 组件:一个包含html、css、js独立的集合体,这样的集合体可以完成页面解构的代码复用
// 2) 分组分为根组件、全局组件与局部组件
// 根组件:所有被new Vue()产生的组件,在项目开发阶段,一个项目只会出现一个根组件
// 全局组件:不用注册,就可以成为任何一个组件的子组件
// 局部组件:必须注册,才可以成为注册该局部组件的子组件
// 3) 每一个组件都有自身的html结构,css样式,js逻辑
// 每一个组件其实都有自己的template,就是用来标识自己html结构的
// template模板中有且只有一个根标签
// 根组件一般不提供template,就由挂载点的真实DOM提供html结构
// 4) 除根组件的其他组件,数据要有局部作用域,保证组件复用时,各组件间数据的独立性
// 5) 在多组件共处时,在哪个组件模板中出现的变量,有当前组件组件提供
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>组件</title>
</head>
<body>
<div id="app">
{{ msg }}
</div>
</body>
<script src="js/vue.js"></script>
<script>
/**
* 1.组件:由html、css、js三部分组成的独立单位,可以类似于变量,重复使用
* 2.组件其实就是vue实例(对象),一个组件就是一个vue实例(对象)
* 3.new Vue()产生的也是实例对象,所以也是组件,我们称之为 根组件
* 一个页面建议只出现一个根组件(项目开发模式下,一个项目建议只出现一个根组件)
* 4.组件的html页面结构由 template 实例成员提供
* template提供的html结构是用来构建虚拟DOM的
* 真实DOM最终会被虚拟DOM替换
* 根组件一般不提供 template , 由挂载点el来提供构建虚拟DOM的页面结构,根组件如果提供了template,还需要设置挂载点作为替换占位符
* template 模板有且只有一个根标签
*/
let c1 = '';
new Vue({
el: '#app',
data: {
msg: 100,
c1: 'red',
},
template: `
<div id='app'>
<p :style="{color: c1}">{{ msg }}</p>
<p @click="clickAction">{{ msg }}</p>
</div> `,
methods: {
clickAction(){
console.log(this.msg)
}
}
})
</script>
</html>
局部组件
// 1) 创建局部组件
// 2) 在父组件中注册该局部组件 根组件称为父组件
// 3) 在父组件的template模板中渲染该局部组件
<style>
.box {
box-shadow: 0 3px 5px 0 #666;
240px;
height: 300px;
text-align: center;
padding: 20px 0;
float: left;
margin: 5px;
}
.box img {
200px;
}
</style>
<div id="app">
<!--<mcc></mcc>-->
//3.在父组件模板中渲染局部组件
<local-tag></local-tag>
<local-tag></local-tag>
</div>
<script src="js/vue.js"></script>
<script>
//1.创建局部组件
let localTag = {
template: `
<div class="box">
<img src="img/666.jpg" alt="">
<h3>凤哥</h3>
<p>马叉虫❤马叉虫</p>
</div>
`
};
new Vue({
el: '#app',
components: { //2.在父组件中注册局部组件
// mcc: localTag,
// localTag,
'local-tag': localTag,
}
})
</script>
子组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>子组件</title>
</head>
<body>
<!--根组件的 template-->
<div id="app">
<my-tag></my-tag>
<my-tag></my-tag>
<my-tag></my-tag>
<tag></tag>
</div>
</body>
<script src="js/vue.js"></script>
<script>
//1.定义组件
//2.注册组件
//3.使用组件
//如何定义子组件:组件就是一个普通对象,内部采用vue语法结构,被vue注册解释后,就会成为vue组件
let myTag = {
template: `
<div>
<h3>子组件</h3>
<p>我是自定义子组件</p>
</div>
`,
};
//了解:全局组件,不要注册就可以直接使用
Vue.component('tag',{
template:`
<div>
<h3>全局组件</h3>
<p>我是自定义的全局组件</p>
</div>`,
});
new Vue({
el: '#app',
components:{
myTag,
}
})
</script>
</html>
全局组件
// 1) 创建全局组件
// 2) 在父组件的template模板中直接渲染该全局组件
<style>
.box {
box-shadow: 0 3px 5px 0 #666;
240px;
height: 300px;
text-align: center;
padding: 20px 0;
float: left;
margin: 5px;
}
.box img {
200px;
}
</style>
<div id="app">
//2.父组件模板渲染全局组件
<global-tag></global-tag>
<global-tag></global-tag>
<global-tag></global-tag>
</div>
<script src="js/vue.js"></script>
<script>
//1.注册全局组件
Vue.component('global-tag', {
template: `
<div class="box" @click="action">
<img src="img/666.jpg" alt="">
<h3>凤哥</h3>
<p>马叉虫❤{{ num }}</p>
</div>
`,
data () {
return {
num: 0
}
},
methods: {
action() {
this.num++;
}
}
});
new Vue({
el: '#app',
})
</script>