1.创建vue实例,需要引入vue.js
<script>
new vue({
el:'.root', //el用于指定当前vue实例为哪个容器服务,值通常为css选择器字符串
data:{ //data中用于存储数据,数据供el所指定的容器去使用
name:''
}
})
</script>
<div id="app">
<h1>hello,world,{{name}}</h1>
</div>
<div class="root">
<h1>hello,world,{{name}}</h1>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
var app = new Vue({
el: '#app', //容器中是id属性,在这用 #
data: {
name: 'Hello Vue!'
}
})
new Vue({
el: '.root', //容器中是class属性,在这用 .
data: {
name: 'Hello Vue!'
}
})
</script>
2.插值语法和指令语法
<!--
插值语法:用于标签体 例:<h3>你好,{{name}}</h3>
指令语法:用于解析标签(标签属性、内容,绑定事件...) 例:<a v-bind:href="url" x="hello">
v-bind <--> : v-bind将标签属性变成js表达式
-->
<div id="root">
<h1>插值语法</h1>
<h3>你好,{{name}}</h3>
<hr/>
<h1>指令语法</h1>
<a v-bind:href="url" x="hello">点我{{school.name}}跳转</a> <!-- v-bind简写为 : -->
<a :href="url" v-bind:x="hello">点我{{school.name}}跳转</a>
</div>
<!--
如果属性冲突
<script>
new vue({
el:'#root',
data:{
name:'bo',
hello:'你好,
school:{
name:'heshida'
url:'http://baidu.com',
}
}
})
</script>
-->
<script>
new vue({
el:'#root',
data:{
name:'bo',
url:'http://baidu.com',
hello:'你好'
}
})
</script>
3. 2种数据绑定方式
(单向绑定)v-bind:数据只能从data流向页面
(双向绑定)v-model:数据不仅能从data流向页面,也能从页面流向data
备注:双向绑定一般都应用在表单元素上(如:input、select)
v-model:value 可以简写为v-model,因为v-model默认收集的就是value值
4. el的两种写法
const v = new Vue({
el:'#', //如果这里不使用el,使用下面的内容
data:{
name:''
}
})v.$mount('#'); //mount:挂载
5. data的两种写法
5.1对象式
data:{
name:''
}
5.2函数式(有组件时,用函数式)
data:function(){ <=> data(){
return { return {
name:'' name:''
} } } }
6. 定时器
setTimeout(()=>{
v.$mount('#');
},时间参数);
7. Object.defineProperty(对象名,属性名,操作)方法
<script type="text/javascript">
let number = 19
let person = {
name:'张三',
sex:'男',
/ /age:'18'
}
Object.defineProperty(person,'age',{
//value:18,
//enumberable:true, //控制属性是否可以枚举,默认值为false
//writable:true, //控制属性是否可以被修改,默认值为false
//configurable:true //控制属性是否可以被删除,默认值为false
//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get(){
console.log('有人来读取age值了')
return number
},
//当有人修改person.age属性时,set函数(setter)就会被调用,且会收到修改的值
set(value){
console.log('有人,修改了age的值',value),
number = value
}
})
//console.log(person)
</script>
8. 绑定事件
1.v-on: 或者 @
2.事件回调函数需要配置methods对象中,最终会在vm上
3.menthods中的函数不要用箭头函数,否则this不是vm了
4.methods中配置的函数,都是被vue所管理的函数,this指向的是vm 或 组件实例对象
5.@click="demo" 和 @click="demo($event)"效果一致,但是后者可以传参
<body>
<div id="root">
<p>hello,{{name}}</p>
<button @click='showData1'>点我展示1</button>
<button @click='showData2($event,66)'>点我展示2</button>
</div>
</body>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name:'bowen',
},
methods:{
showData1(event){
alert("hello1");
},
showData2(event,number){
alert("hello2"+this.number);
}
}
})
</script>
9. vue中的事件修饰符
1. prevent:阻止默认事件(常用)
2. stop: 阻止事件冒泡(常用)
3. once: 事件只触发一次(常用)
4. capture: 使用事件的捕获模式
5. self: 只有event.target是当前操作的元素时才触发操作
6. passive: 事件的默认行为立即执行,无需等待事件回调执行完毕.
<body>
<div id="root">
<p>hello,{{name}}</p>
<a href="http://www.baidu.com" @click.prevent='showData1'>点我展示1</a>
<button @click.once='showData2($event,66)'>点我展示2</button>
</div>
</body>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name:'bowen',
},
methods:{
showData1(event){
alert("hello1");
},
showData2(event,number){
alert("hello2"+this.number);
}
}
})
</script>
10. Vue中常用的按键别名:
1.
回车 => enter
删除 => delete
退出 => esc
空格 => space
换行 => tab(特殊,必须配合)
上 => up
下 => down
左 => left
右 => right
2.
Vue为提供别名的按键,可以使用按键原始的key值去绑定
3. 系统修饰键(用法特殊):ctrl、alt、shift、meta
1)配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才触发
2)配合keydown使用:正常触发事件
4. 也可以使用keyCode去指定具体的按键(不推荐)
5. Vue.config.keyCodes.自定义键名 = 键码. 可以去定制按键别名
<body>
<div id="root">
<p>hello,{{name}}</p>
<input type="text"@keyup.enter="info"> <!-- 键盘事件 用 @keyup -->
</div>
</body>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name:'bowen'
},
methods:{
info(event){
//if(e.keyCode !== 13) return
console.log(e.target.value) //keyCode是按键的码,key是键名
//alert('hello')
}
}
})
</script>
11. computed(计算属性)
<body>
<div id="root">
<input type="text":value="firstName">姓<br><br/>
<input type="text":value="lastName">名<br><br/>
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三'
}
/*计算属性 (完整版)
computed:{
fullName:{
get(){
return this.firstName+'-'+this.lastName
},
set(value){
console.log("value",value)
const arr = value.split('-')
firstName = arr[0]
lastName = arr[1]
}
}
}
*/
computed:{
fullName:function(){
return this.firstName+'-'+this.lastName
}
}
})
12. 监听事件
watch:{
info:{ //监听对象(vm的属性 或 计算属性)
immediate : true , //初始化时让hanled调用一下
handler(newValue,oldValue){
console.log('info被修改了',newValue,oldValue)
}
}
}
<script type="text/javascript">
const vm = new Vue({
el:'#root',
data:{
isHot:'true'
},
computed:{
info(){
return this.isHot ? '炎热': '寒冷'
}
},
methods:{
changeWeather(){
console.log('changeWeather被调用了')
this.isHot = !this.isHot
}
},
/*第一种方法
watch:{
info:{
immediate : true ,
handler(newValue,oldValue){
console.log('info被修改了',newValue,oldValue)
}
}
}
*/
})
//第二种方法
vm.$watch('info',{
immediate : true ,
handler(newValue,oldValue){
console.log('info被修改了',newValue,oldValue)
}
})
</script>
13. 深度监视
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
<hr/>
<h2>a的值是:{{numbers.a}}</h2>
<button @click="numbers.a++">a++</button>
<h2>b的值是:{{numbers.b}}</h2>
<button @click="numbers.b++">b++</button>
<hr>
<h2>d的值是:{{numbers.d}}</h2>
<button @click="numbers.d++">d++</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el:'#root',
data:{
isHot:'true',
numbers:{
a:'1',
b:'1',
c:{
d:'1'
}
}
},
computed:{
info(){
return this.isHot ? '炎热': '寒冷'
}
},
methods:{
changeWeather(){
console.log('changeWeather被调用了')
this.isHot = !this.isHot
}
},
watch:{
info:{
immediate : true ,
handler(newValue,oldValue){
console.log('info被修改了',newValue,oldValue)
}
},
numbers:{
deep:true, //配置deep:true 可以监测对象(例:numbers)内部值的改变
handler(){
console.log('numbers改变了')
}
}
}
})
</script>
14. computed与watch的区别
1)computed能完成的功能,watch都能完成
2)watch能完成的功能,computed不一定能完成
3)被vue管理的函数,最好写成普通函数,this的指向才是vm或组件实例对象
4)不被vue管理的函数(定时器回调函数、ajax的回调函数、Promise的回调函数),最好写成箭头函数,这样 的this的访问才是vm或组件实例对象
setTimeout(()=>{
执行语句
},1000)
15. 条件渲染
1. v-if
写法:
1).v-if="表达式"
2).v-else-if="表达式"
3).v-else="表达式"
适用于:切换频率较低的场合
特点:不展示的Dom元素直接被删除
注意:v-if、v-else-if、v-else一起使用,但要求结构不能被"打断"
2. v-show
写法:
.v-show="表达式"
适用于:切换频率较高的场合
特点:不展示的Dom元素未被删除,仅仅是使用样式隐藏掉
3. 备注:
使用v-if时,元素可能无法获取到,但使用v-show时,一定可以获取到
<h2 v-if="false">今天天气很炎热</h2>
<h2 v-show="false">今天天气很炎热</h2>
16. 列表渲染
v-for
1.用于:展示列表数据
2.语法:v-for="(item,index) in xxx" :key="yyy" //这里的yyy值的是index
3.可遍历数组、对象、字符串(用得少)、指定次数(用得少)
<body>
<div id="root">
<h2>人员列表(遍历数组)</h2>
<ul>
<li v-for="p in persons" :key="p.id">
{{p.name}}-{{p.age}}
</li>
</ul>
<h2>汽车信息(遍历对象)</h2>
<ul>
<li v-for='(value,key) in car':key="key">
{{key}}:{{value}}
</li>
</ul>
<h2>遍历字符串(用得少)</h2>
<ul>
<li v-for="(value,index) in str":key="index">
{{index}}--{{value}}
</li>
</ul>
<h2>遍历指定次数(用得少)</h2>
<ul>
<li v-for="(number,index) in 5":key="index">
{{index}}--{{number}}
</li>
</ul>
</div>
<script type="text/javascript">
const vm = new Vue({
el:'#root',
data:{
persons:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:20},
{id:'003',name:'王五',age:19}
],
car:{
name:'奥迪',
price:'70w',
color:'block'
},
str:'hello'
}
})
</script>
</body>
17. Vue.set(target,key,val) 或者 vm.$set(target,key,val)
1.不允许在Vue实例对象身上加属性,只能在Vue实例对象中的对象加属性
const vm = new Vue({
el:'#root',
data:{
//Vue.set(this._data,'phone','xiaomi') 错误❌
persons:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:20},
{id:'003',name:'王五',age:19}
],
car:{
name:'奥迪',
price:'70w',
color:'block'
//type:'' 正确
},
str:'hello'
}
})
18. 修改Vue中的数组
常用的方法:
1.会改变原数组
push(在数组最后添加一个元素)
pop(把数组最后一个元素删掉)
shift(删除数组中第一个元素)
unshift(在数组最前面添加一个元素)
splice(在数组的指定位置插入、删除、替换一个元素)
sort(对数组进行排序)
reverse(反转数组)
2.不会改变原数组
filter(过滤某些元素)
19. Vue监视数据的原理
1.vue会监视data中所有层次的数据
2.如何检测对象中的数据
通过setter实现监视、且要new Vue时就传入要检测的数据
1)对象中后追加的属性、vue一般不做响应式处理
2)如需给后加的属性做响应式。请使用如下API:
Vue.set(target,propertyName/index,value)或
vm.$setv(target,propertyName/index,value)
3.如何检测数组中的数据?
通过包裹数组更新元素的方法实现。本质就是做了两件事:
1)调用原生对应的方法对数组进行更新
2)重新解析模版,进而更新页面
4.在Vue中修改数组中某个元素一定要用如下方法:
1)使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()、
2)Vue.set()或vm.$set()
特别注意:Vue.set()或vm.$set()不能给vm或vm的根数据对象添加元素
20. <label for="demo">账号:</label> //点击input框可以聚焦、点击label的‘账号’也可以聚焦
<input type="text" id="demo">
21. JSON.stringify() //把原来的对象的类型转换成字符串类型
22. 收集表单数据
若:<input type="text"/>,则v-model收集的是value值,用户输入的是value值
若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值
若:<input type="checkbox"/>
1.没有配置input的value属性,那么收集到的就是checked(勾选 or 未勾选,是布尔值)
2.配置input的value属性:
1)v-model的初始值是非数组,那么收集到的就是checked(勾选 or 未勾选,是布尔值)
2)v-model的初始值是数组,那么收集到的就是value组成的数组
备注:v-model的三个修饰符
lazy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim:输入首位空格过滤
<body>
<div id="root">
<form @submit.prevent="demo">
<label for="demo">账号:</label>
<input type="text" id="demo"v-model.trim="userInfo.account"><br><br/>
<label for="demo1">密码:</label>
<input type="password" id="demo1"v-model="userInfo.password"><br><br/>
年龄:
<input type="number" name="age" v-model.number="userInfo.age"><br><br/>
性别:
男<input type="radio" v-model="userInfo.sex" value="male">
女<input type="radio" v-model="userInfo.sex" value="female"><br><br/>
爱好:
<input type="checkbox" v-model="userInfo.hobby" value="study">学习
<input type="checkbox" v-model="userInfo.hobby" value="play">打游戏
<input type="checkbox" v-model="userInfo.hobby" value="eat">吃饭
<br><br/>
地址:
<select v-model="userInfo.city">
<option value="">请选择地区</option>
<option value="xinxiang">新乡</option>
<option value="nanyang">南阳</option>
<option value="jiaozuo">焦作</option>
</select>
<br><br/>
其他信息:<input type="textarea"v-model="userInfo.other"><br><br/>
<input type="checkbox">阅读并接受<a href="#">《用户协议》</a><br><br/>
<button>提交</button>
</form>
</div>
<script>
new Vue({
el:'#root',
data:{
userInfo:{
account:'',
password:'',
age:'',
sex:'',
hobby:[],
city:'',
other:''
}
},
methods:{
demo(){
console.log(JSON.stringify(this.userInfo))
}
}
})
</script>
</body>
23. 过滤器
定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)
语法:
1)注册过滤器:Vue.filter(name,callback) 或 new Vue{filter:{}}
2)使用过滤器:{{xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"
备注:
1.过滤器也可以接收额外参数、多个过滤器也可以串联
2.并没有改变原本的数据,是产生新的对应的数据
<body>
<div id="root">
<h2>时间:{{time}}</h2>
<h2>格式化时间:{{time | fmtTime}}</h2>
<input :x="msg | mySplcie">
</div>
<script>
Vue.filter('mySplcie',function(value){
return value.splice(0,4)
})
new Vue({
el:'#root',
data:{
time:1653912528248,
msg:'hello,World'
},
filters:{
fmtTime(value){
console.log('hello')
return dayjs(value).format("YYYY-MM-DD HH:mm:ss")
},
mySplice(value){
return value.splice(0,4)
}
}
})
</script>
</body>
24. 学过的指令:
1. v-bind : 单向绑定解析表达式,可以简写为 :xxx
2. v-model : 双向数据绑定
3. v-for : 可遍历数组、对象、字符串
4. v-on : 绑定事件监听,可以简写为 @
5. v-if : 条件渲染(动态控制节点是否存在)
6. v-else : 条件渲染(动态控制节点是否存在)
7. v-show : 条件渲染(动态控制节点是否展示)
8. v-test指令:
1)作用:向其所在的节点中渲染文本内容
2)与插值语法的区别:v-test会替换掉节点中的内容,{{xx}}不会
9. v-html指令:
1)作用:向指定节点中渲染包含html结构的内容
2)与插值语法的区别:
(1). v-html会替换掉节点中所有的内容.{{xx}}则不会
(2). v-html可以识别html结构
3)严重注意:v-html有安全性问题!
(1). 在网站中动态渲染html是非常危险的,容易导致xss攻击
(2). 一定要在可信的内容上使用v-html,永不要用在用户提交的内容上
<div id="root">
<h3>你好,{{name}}</h3>
<div v-text="name"></div>
<div v-text="str"></div>
<div v-text="str2"></div>
<h2 v-if="true">今天天气很炎热</h2>
</div>
<script>
new Vue({
el:'#root',
data:{
name:'硅谷',
str:'<h3>你好<h3>',
str2:'<a href=javascript:location.href="http://baidu.com?+document.cookie>我找到你需要的资源,请点我跳转</a>' //跳转后搜索框中显示 https://www.baidu.com/?a=2
}
})
</script>
10. v-clock指令:
1)本质是一个特殊的属性,Vue实例创建完毕并接管容器后,会删掉v-clock属性
2)使用css配置v-clock可以解决网速慢时页面展示出{{xxx}}的问题
11. v-once指令:
1)v-once所在节点在初次动态渲染后,就视为静态内容了
2)以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能
<div id="root">
<h2 v-once>初始值n={{n}}</h2>
<h2>初始值n={{n}}</h2>
<button @click="n++">n++</button>
</div>
<script>
new Vue({
el:'#root',
data:{
n:'1'
}
})
</script>
12. v-pre指令:
1)跳过其所在节点的编译过程
2)可利用它跳过:没有使用指令语法、没有插值语法的节点,会加快编译
25. 自定义指令 (v-自定义名)
<!-- 将n的值扩大10倍-->
<div id="root">
<h2 v-once>初始值n={{n}}</h2>
<h2>n={{n}}</h2>
<h2>放大10倍后n=<span v-big="n"></span></h2>
<button @click="n++">n++</button>
</div>
<script>
new Vue({
el:'#root',
data:{
n:'1'
},
directives:{
big(element,binding){ //函数式
console.log(element,binding)
element.innerText = binding.value *10
}
}
})
</script>
<!-- 定义一个v-fbind指令,和v-bind指令功能类似,但可以让其绑定的input元素默认获取焦点-->
<div id="root">
<h2 v-once>初始值n={{n}}</h2>
<h2>n={{n}}</h2>
<h2>放大10倍后n=<span v-big="n"></span></h2>
<button @click="n++">n++</button><br><br/>
<input type="text" v-fbind:value="n">
</div>
<script>
new Vue({
el:'#root',
data:{
n:'1'
},
directives:{
big(element,binding){ //函数式
element.innerText = binding.value *10
},
fbind:{ //对象式
//指令与元素绑定时
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element,binding){
element.focus() //获取焦点
},
//指令所在的模板被重新解析时
update(element,binding){
element.value = binding.value
}
}
}
})
</script>
自定义指令总结:
一、定义语法:
1)局部指令:
new Vue({
directives:{指令名:配置对象}
})
或
new Vue({
directives(){}
})
2)全局指令:
Vue.directive(指令名,配置对象)
或
Vue.directive(指令名,回调函数)
二、配置对象的3个回调函数
1) bind: 指令与元素成功绑定时调用
2) inserted: 指令所在元素被插入页面时调用
3) update: 指令所在模板结构被重新解析时调用
三、备注
1)指令定义时不需要加v-,但使用时需要加v-
2)指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名
26.生命周期函数
生命周期:
1.又名:生命周期回调函数、生命周期函数、生命周期钩子
2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数(例:mounted()函数)
3.生命周期函数的名字不能更改,但函数的具体内容是程序员根据需求编写的
4.生命周期中的this指向是 vm 或 组件实例对象
5.常用生命周期钩子
1)mounted:发送ajax请求、启动定时器、绑定自定义事件、订阅信息等(初始化操作)
2)beforeDestroy:清除定时器、解绑自定义事件、取消订阅信息等(收尾工作)
6.关于销毁Vue实例
1)销毁后借助Vue开发工具看不到任何信息
2)销毁后自定义事件会失效、但原生DOM事件依然有效
3)一般不会再beforDestroy操作数据,因为即便操作数据,也不会再触发更新流程了
<div id="root">
<h2 :style="{opacity}">欢迎来到Vue</h2>
</div>
<script>
new Vue({
el:'#root',
data:{
opacity:1
},
//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
mounted(){
console.log('mounted')
setInterval(()=>{
this.opacity-=0.01
if(this.opacity <= 0) this.opacity = 1
},16)
}
})
</script>
27.组件
Vue中使用组件的三大步骤:
1.定义组件(创建组件)
2.注册组件
3.使用组件(写组件标签)
一、如何定义一个组件?
使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别:
1)el不要写,为什么?--最终所有组件都要经过一个Vue的管理,由vm中的el决定要服务于哪个容器
2)data必须写成函数,为什么?--避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构
二、如何注册组件?
1.局部注册:靠new vue的时候传入components选项
2.全局注册:靠Vue.component('组件名',组件)
三、编写组件标签:
例:<school></school>
<div id="root">
<!--第三步:使用组件-->
<school></school>
<student></student>
<hello></hello>
<!--
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
-->
</div>
<script>
//第一步:定义组件
const school = Vue.extend({
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
`,
data(){
return{
schoolName:'河师大',
address:'新乡'
}
}
})
const student = Vue.extend({
template:`
<div>
<h2>学生名字:{{studentName}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data(){
return{
studentName:'张三',
age:20
}
}
})
const hello = Vue.extend({
template:`
<div>
<h1>你好啊!{{name}}</h1>
</div>
`,
data(){
return{
name:'tom'
}
}
})
//注册全局组件
Vue.component('hello',hello)
new Vue({
el:'#root',
//第二步:注册组件
components:{
school:school,
student:student
}
/*
data:{
schoolName:'河师大',
address:'新乡'
}
*/
})
</script>
28.组件嵌套
<div id="root">
<App></App>
<!--第三步:使用组件-->
<!--
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
-->
</div>
<script>
const student = Vue.extend({
template:`
<div>
<h2>学生名字:{{studentName}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data(){
return{
studentName:'张三',
age:20
}
}
})
//第一步:定义组件
const school = Vue.extend({
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<student></student>
</div>
`,
data(){
return{
schoolName:'河师大',
address:'新乡'
}
},
components:{
student
}
})
const hello = Vue.extend({
template:`
<div>
<h1>你好啊!{{name}}</h1>
</div>
`,
data(){
return{
name:'tom'
}
}
})
const App =Vue.extend({
template:`
<div>
<hello></hello>
<school></school>
</div>
`,
components:{
school:school,
hello:hello
}
})
//注册全局组件
Vue.component('hello',hello)
new Vue({
el:'#root',
//第二步:注册组件
components:{
App:App
}
/*
data:{
schoolName:'河师大',
address:'新乡'
}
*/
})
</script>
29.组件中的this指向是 VueComponent
const school = Vue.extend({
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我显示学校名称</button>
<student></student>
</div>
`,
data(){
return{
schoolName:'河师大',
address:'新乡'
}
},
components:{
student
},
methods:{
showName(){
alert(this.schoolName)
}
}
})