目录
Vue.js是什么
框架和库的区别
Vue基本代码
v-cloak
与v-text?区别:
v-text与v-html
v-bind
v-on
v-model
v-for和key
v-for循环普通数组
v-for循环对象
v-for迭代数字
v-if与v-show
v-if
v-show
事件修饰符
在Vue中使用样式
使用class样式
使用内联样式
案例中的操作
删除
查找
数组中的新方法
字符串新方法
过滤器
全局过滤器
局部过滤器(私有过滤器)
ES6字符串新方法padStart
自定义按键修饰符
全部的按键别名
自定义全局按键修饰符(2.x)
自定义指令
钩子函数
钩子函数的参数
自定义私有指令
指令函数简写形式
Vue实例的生命周期
vue-resource实现请求
GET
POST
JSONP
JSONP原理
Vue动画
使用过渡类名实现动画
自定义v-前缀
使用第三方类实现动画
钩子函数实现半场动画
列表动画
Vue组件
组件化和模块化的不同
全局组件定义的三种方式
使用Vue.extend来创建全局的Vue组件
使用字面量对象创建组件
使用template创建组件
使用components定义私有组件
组件中的data和methods
组件切换
使用v-if和v-else
使用component
组件切换动画
组件传值
父组件向子组件传值
父组件向子组件传递方法
ref获取DOM元素和组件
?<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>?
Vue.js是什么
vue是一套用于构建用户界面的渐进式框架。
与其他框架不同的是,Vue被设计为可以自底向上逐层应用
Vue的核心库只关注视图层
框架和库的区别
框架:是一套完整的解决方案,对项目的侵入性较大,项目如果需要更换框架,需要重新架构整个项目
库(插件):提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其他库实现
Vue基本代码
var vm = new Vue({
el: '#app',
data:{
message:'hello world'
}
methonds:{
show:function() {
alert('Hello')
}
}
})
el:表示当前我们new的这个vue实例要控制页面上的哪个区域
data:存放的是el中要用到的数据
methods:定义了当前Vue实例所有可用的方法
vue省去了操作DOM元素的步骤
v-cloak
解决插值表达式闪烁问题(网络慢)
[v-cloak] {
display:none;
}
与v-text?区别:
网速慢来不及渲染Vue时,v-cloak有闪烁问题
v-text会覆盖元素中原本的内容,v-cloak可以在插值表达式前后放任意内容,不会整个覆盖
<p v-cloak>+++{{ msg }}---</p>
<h4 v-text="msg">====</h4>
v-text与v-html
v-html用于输出html标签
v-bind
是Vue中提供的用于绑定指令的属性
<input type="button" value="按钮" v-bind:title="mytitle">
v-bind指令可以简写为 :要绑定的属性
v-bind中可以写合法的JS表达式
v-on
是Vue中提供的用于绑定事件的属性
<input type="button" value="按钮" v-bind:title="mytitle"?v-on:click="show">
v-on可以缩写成@
v-model
只有这唯一的指令能实现双向事件绑定
v-bind只能实现单项绑定
<div id="app">
<input type="text" v-model:value="message">
<h4>{{ message }}</h4>
</div>
var vm = new Vue({
el: '#app',
data: {
message: '123456789',
},
})
注意:v-model只能运用在表单元素中
表单元素:input(radio、text、address、email)、select、checkbox、textarea
v-for和key
v-for循环普通数组
<p v-for="item in message">{{item}}</p>
v-for循环对象
在遍历对象身上的键值对的时候,除了有val,key之外,在第三个位置还有一个索引
<p v-for="(val,key)in user">{{val}} --- {{key}}</p>
v-for迭代数字
<p v-for="count in 10">第 {{count}} 次</p>? //第1次?第2次......
如果使用v-for迭代数字,是从1开始
在2.2.0+的版本里,当在组件中使用v-for时,key是必须的
每次for循环的时候,通过指定key来标识当前循环这一项的唯一身份,保证唯一性
注意:
v-for循环的时候,key属性只能使用nuber或string
key在使用的时候,必须使用v-bind属性绑定的形式指定key的值
在组件中,使用v-for循环的时候,或者再一些特殊情况中,如果v-for有问题,必须在使用v-for的同时,指定唯一的字符串/数字类型 :key?值
v-if与v-show
v-if
每次都会重新删除或创建元素
有较高的切换性能消耗
v-show
每次不会重新进行DOM的删除操作,只是切换display:none;
有较高的初始渲染消耗
注意:如果元素涉及到频繁的交换,不要用v-if;如果元素可能创建出来从未被显示过,用v-if
事件修饰符
.stop?阻止冒泡
.prevent?阻止默认事件
.capture?添加事件侦听器时使用事件捕获模式
.self?只当事件在该元素本身触发时触发回调
.once?事件只触发一次
.stop和.self都可以阻止冒泡,区别:.stop阻止所有的冒泡行为;.self只能阻止自身冒泡
在Vue中使用样式
使用class样式
1.使用数组形式
<h1 :class="['red','thin']">123</h1>
2.在数组中使用三元表达式
<body>
<div id="app">
<h4 :class="['red',flag?'active':'']">{{message}}</h4>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
message: '123456789',
flag:false,
},
})
</script>
可以用但是不好读
3.在数组中使用对象代替三元表达式,提高代码可读性
<h4 :class="['red',{'active':flag}]">{{message}}</h4>
4.直接使用对象
<body>
<div id="app">
<h4 :class="{red:true,thin:false,italic:true,active:false}">{{message}}</h4>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
message: '123456789',
flag:true,
},
})
</script>
为class使用v-bind绑定对象的时候,对象的属性是类名,对象的属性可带引号可不带引号,属性的值是一个标识符
使用内联样式
1.直接在元素上通过 :style 形式书写
<h4 :style="{color:'red'}">{{message}}</h4>
如果属性里面包含 - ,必须要加引号
<h4 :style="{'font-weight':'700'}">{{message}}</h4>
2.将样式对象定义到data中,并直接引用到style中
3.在style中通过数组,引用多个data上的样式对象
<body>
<div id="app">
<h4 :style="[styleObj1,styleObj2]">{{message}}</h4>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
message: '123456789',
styleObj1:{'font-weight':'700'},
styleObj2:{'color':'red'}
},
})
</script>
案例中的操作
删除
del(id) {
this.list.some((item,i) => {
if(item.id == id) {
this.list.splice(i,1)
return true;
}
})
},
或者
var index = this.list.findIndex(item => {
if(item.id == id)
return true;
})
this.list.splice(index,1)
findIndex可以快速找到索引
查找
search(keywords) {
var newList = []
this.list.forEach(item => {
if(item.name.indexOf(keywords) != -1)
newList.push(item)
})
}
return newList
数组中的新方法
forEach(没法终止) some(通过return?true?终止) filter(过滤) findIndex(找到对应列项的索引) 这些都属于数组的新方法,会对数组中的每一项进行遍历,执行相关操作
字符串新方法
String.prototype.includes('要包含的字符串'),包含返回true,不包含返回false
过滤器
Vue.js允许自定义过滤器,可被用作一些常见的文本格式化
过滤器可以用在两个地方:mustache插值({{}})和v-bind表达式
全局过滤器
所有的vm实例都能共享
过滤器应该被添加在JavaScript表达式的尾部,由“管道”符提示
Vue.filter('过滤器的名称',fuction(){ })
过滤器中的function,第一个参数已经被规定死了,永远都是过滤器管道符前面传递过来的数据
Vue.filter('messageFormat',function(message) {
return message.replace(/1/g,'666666')
})
<body>
<div id="app">
<p>{{message | messageFormat('123456') }}</p>
</div>
</body>
<script>
Vue.filter('messageFormat',function(message,arg) {
return message.replace(/单纯/g,arg)
})
var vm = new Vue({
el:'#app',
data:{
message:'单纯'
},
methods:{ }
})
</script>
局部过滤器(私有过滤器)
定义私有过滤器有两个条件 [过滤器名称和处理函数]
过滤器调用的时候采用就近原则,如果私有过滤器和全局过滤器名称一致了,这时候优先调用私有的
ES6字符串新方法padStart
String.prototype.padStart(maxLength,fillString=' ')或String.prototype.padEnd(maxLength,fillString=' ')
自定义按键修饰符
全部的按键别名
- enter
- tab
- delete
- esc
- space
- up
- down
- left
- right
自定义全局按键修饰符(2.x)
Vue.config.keyCodes.f2 = 113;? //定义113(F2键)的名字为113
自定义指令
Vue中所有的指令在调用的时候都以v-开头
Vue.directive('focus',{ }) //定义全局指令
参数1是指令的名称,在定义的时候指令名称前不用加v-,在调用的时候必须在指令名称前加v-前缀
参数2是一个对象,这个对象身上有一些指令相关的函数,这些函数可以在特定的阶段执行相关的操作
钩子函数
-
bind :只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 -
inserted :被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。 -
update :所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 -
componentUpdated :指令所在组件的 VNode?及其子 VNode?全部更新后调用。 -
unbind :只调用一次,指令与元素解绑时调用。
注意:在每一个函数中,第一个参数永远是el,表示被绑定了指令的那个元素,这个el参数是一个原生的JS对象
使用bind获得focus时:在元素刚绑定了指令的时候,还没有插入到DOM中去,这时候调用focus方法没有用,因为一个元素只有插入DOM之后才能获取焦点,所以要用inserted
<body>
<div id="app">
<input type="text" v-focus>123
</div>
</body>
<script>
Vue.directive('focus',{
inserted:function(el) {
el.focus()
}
})
var vm = new Vue({
el:'#app',
data:{
},
methods:{ }
})
</script>
自定义字体颜色
Vue.directive('color',{
bind:function(el) {
el.style.color = 'red'
}
})
设置样式的时候不用关心有没有插入到DOM中去,只要把样式交给了DOM元素,只要DOM元素被浏览器渲染解析,最终显示页面的时候一定会把颜色渲染上去。样式只要通过指令绑定给了元素,不管这个元素有没有插入到页面中去,这个元素肯定有了一个内联样式。
与样式相关的设置到bind里就可以,与JS行为相关的要设置到inserted里(防止JS行为不生效)
钩子函数的参数
el :指令所绑定的元素,可以用来直接操作 DOM。binding :一个对象,包含以下 property:
name :指令名,不包括?v- ?前缀。value :指令的绑定值,例如:v-my-directive="1 + 1" ?中,绑定值为?2 。oldValue :指令绑定的前一个值,仅在?update ?和?componentUpdated ?钩子中可用。无论值是否改变都可用。expression :字符串形式的指令表达式。例如?v-my-directive="1 + 1" ?中,表达式为?"1 + 1" 。arg :传给指令的参数,可选。例如?v-my-directive:foo ?中,参数为?"foo" 。modifiers :一个包含修饰符的对象。例如:v-my-directive.foo.bar ?中,修饰符对象为?{ foo: true, bar: true } 。
vnode :Vue 编译生成的虚拟节点。移步?VNode API?来了解更多详情。oldVnode :上一个虚拟节点,仅在?update ?和?componentUpdated ?钩子中可用。
除了?el ?之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的?dataset来进行。
自定义私有指令
var vm2 = new Vue({
el:'#app',
data: { },
directives:{
'fontweight':{
bind:function(el,binding){
el.style.fontWeight = binding.value
}
}
}
})
指令函数简写形式
directives:{
'fontsize':function(el,binding){
el.style.fontSize = parseInt(binding.value) + 'px'
}
}
这个fuction等同于把代码写到了bind和update中去
Vue实例的生命周期
生命周期:从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件统称为生命周期
生命周期钩子:生命周期事件(函数)的别名
生命周期的函数分类:
创建期间的生命周期函数
beforeCreate:在此生命周期函数执行的时候,data和methods中的数据都还没有初始化
created:data和methods已经初始化好,如果要调用methods中的方法,或者操作data中的数据,最早只能在此操作
beforeMount:表示模板已经在内存中编辑完成了,但是尚未把模板渲染到页面中去。 在此时,页面中的元素内容还没有被真正替换过来,只是之前写的一些模板字符串
mounted:是实例创建期间的最后一个周期函数,执行完此函数时就表示实例已经完全被创建好了,如果没有其他操作的话这个实例已经完好的在内存中了。如果要通过插件操作页面上的DOM节点,最早在此操作。
只要执行完了mounted,就表示整个Vue实例已经初始化完毕了,此时组件已经脱离了创建阶段,进入到了运行阶段
运行期间的生命周期函数
如果从来没有改变过data,那么这两个函数不会被执行;data改变多少次,这两个函数触发多少次
beforeUpdate:这时候表示我们的界面还没有被更新,数据被更新了。当执行此函数的时候,页面中显示的数据还是旧的,数据data是最新的
update:此函数执行的时候,页面和data数据已经保持同步了,都是最新的
销毁期间的生命周期函数
实例就已经从运行阶段进入到了销毁阶段
beforeDestroy:当执行此函数的时候,实例身上所有的date和所有的methods以及过滤器、指令…都处于可用状态,还没真正执行销毁的过程
destroy:当执行到destroy函数的时候,组件已经被完全销毁了,组件中所有的数据、方法、指令、过滤器中都已经被销毁了。
vue-resource实现请求
<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
vue-resource依赖于vue,要注意导入包的先后顺序
?
GET
// global Vue object
Vue.http.get('/someUrl', [config]).then(successCallback, errorCallback);
Vue.http.post('/someUrl', [body], [config]).then(successCallback, errorCallback);
// in a Vue instance
this.$http.get('/someUrl', [config]).then(successCallback, errorCallback);
this.$http.post('/someUrl', [body], [config]).then(successCallback, errorCallback);
当发起get请求之后,通过.then来设置成功的回调函数
POST
发起post请求,表单格式:application/x-wwww-form-urlencoded
手动发起的post请求,默认没有表单格式,有的服务器处理不了
通过post方法的第三个参数,设置提交的内容类型为普通表单数据格式
this.$http.post('http://vue.studyit/io/api/post' , {},{emulateJson:true}).then(result => {console.log(result.body)})
JSONP
this.$http.jsonp('http://vue.studyit.io/api/jsonp').then(result => {console.log(result.body)})
JSONP原理
由于浏览器的安全限制,不允许AJAX访问协议不同、域名不同、端口号不同的数据接口,浏览器认为这种访问不安全;
可以通过动态创建script标签的形式,把script标签的src属性指向数据接口的地址,因为script标签不存在跨域限制,这种数据获取方式称作JSONP
Vue动画
使用过渡类名实现动画
需求:点击按钮让h3显示,再点击让h3隐藏
1.使用transition标签把需要被动画控制的元素包裹起来(transition元素时vue官方提供的)?
2.自定义两组样式,来控制transition内部元素实现动画
<style>
.v-enter,
.v-leave-to {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: all 0.4s ease;
}
</style>
<body>
<div id="app">
<input type="button" value="toggle" @click="flag = !flag">
<transition>
<h3 v-if="flag">h3</h3>
</transition>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data:{
flag:false,
},
methods:{
}
})
</script>
自定义v-前缀
<style>
.my-enter,
.my-leave-to {
opacity:0;
transform:translateY(150px);
}
.my-enter-active,
.my-leave-active {
transition: all 0.4s ease;
}
</style>
<input type="button" value="toggle" @click="flag2 = !flag2">
<transition name="my">
<h4 v-if="flag2">h4</h4>
</transition>
使用第三方类实现动画
<link
? ? rel="stylesheet"
? ? href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
? />
<transition enter-active-class=" animate__bounce"
leave-active-class=" animate__bounce">
<h4 v-if="flag2" class="animate__animated">h4</h4>
</transition>
enter-active-class一定要加在transition里,加在h4里无效
还可以在transition里添加 :duration?控制入场、离场时间
钩子函数实现半场动画
动画钩子函数的第一个参数el,表示要执行动画的那个DOM元素,是个原生的JS对象
可以理解成el是通过document.getElementById('')?获取到的JS DOM对象
<body>
<div id="app">
<input type="button" name="" value="快到碗里来" @click="flag = !flag">
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter">
<div class="ball" v-show="flag"></div>
</transition>
</div>
</body>
<script>
var vue = new Vue({
el:'#app',
data: {
flag:false,
},
methods:{
beforeEnter(el) {
el.style.transform = "translate(0,0)"
},
enter(el,done) {
el.offsetWidth
el.style.transform = "translate(150px,450px)"
el.style.transition = "all 1s ease"
done() //立即消失
},
afterEnter(el) {
this.flag = !this.flag
}
}
})
</script>
el.offsetWidth?这句话没有是的作用但是如果不写出不来动画效果,可以认为el.offsetWidth会强制动画刷新,写el.offsetHeight等等也可以
done()?这里的done就是afterEnter这个函数,也就是说done是一个函数(afterEnter)的引用
当只用 JavaScript 过渡的时候,在?enter ?和?leave ?中必须使用?done ?进行回调。否则,它们将被同步调用,过渡会立即完成。
this.flag = !this.flag?这句话有两个功能:1.控制小球的显示与隐藏;2.直接跳过后半场动画,让flag标识符直接变为false
列表动画
在实现列表过渡的时候,如果需要过渡的元素是通过v-for循环渲染出来的,不能使用transition包裹,需要使用transition-group??
给transition-group添加appear属性,实现页面刚战术出来的时候入场动画
在f12中,会把transition-group渲染成span,此操作不符合W3C规范,所以我们可以设置tag属性,指定transition-group渲染成什么样的元素,如果不指定默认为span
?<transition-group appear tag="ul"> </transition-group>
上方li删除时下方li上移的动画(配合使用,记住他们):
.v-move {
? ? ? ? transition: all 0.6s ease;?}
.v-leave-active {
? ? ? ? position: absolute;}
Vue组件
组件的出现是为了拆分Vue实例的代码量,能让我们以不同的组件来划分不同的功能模块,将来我们需要什么样的功能就可以去调用对应的组件即可
组件化和模块化的不同
模块化:从代码逻辑角度划分,方便代码分层开发,保证每个功能模块职能单一
组件化:从UI界面角度划分,前端的组件化方便UI组件化的重用
全局组件定义的三种方式
使用Vue.extend来创建全局的Vue组件
1.通过template属性,指定了组件要展示的HTML结构
2.使用Vue.component('组件的名称','创建出来的组件模板对象')
3.如果要使用组件,直接把组件的名称以HTML标签的形式引入页面中即可
<body>
<div id="app">
<my-coml>
</my-coml>
</div>
</body>
<script>
var coml = Vue.extend({
template:'<h3>这是使用Vue.extend创建的组件</h3>'
//通过tempalte属性,指定了组件要展示的HTML结构
})
Vue.component('myComl',coml)
</script>
可以合并
Vue.component('myComl',Vue.extend({
template:'<h3>这是使用Vue.extend创建的组件</h3>'
}))
如果使用Vue.component定义全局组件的时候,组件名称使用了驼峰命名,则在引用组件的时候需要把大写的驼峰改成小写字母,两个单词之间使用-连接;若不使用驼峰则正常使用即可
使用字面量对象创建组件
Vue.component('myComl',{
template:'<div><h3>123</h3><span></span></div>'
})
无论是哪种方式创建出的组件,组件的template属性指向的模板内容必须有且只有唯一的一个根元素
使用template创建组件
<body>
<div id="app">
<my-coml>
</my-coml>
</div>
<template id="tmp1">
<div>
<h1>这是通过template元素在外部定义的组件结构</h1>
</div>
</template>
</body>
<script>
Vue.component('myComl',{
template:'#tmp1'
})
var vm = new Vue({
el:'#app',
data:{}
})
</script>
使用components定义私有组件
<body>
<div id="app">
<login></login>
</div>
</body>
<script>
Vue.component('myComl',{
template:'#tmp1'
})
var vm = new Vue({
el:'#app',
data:{},
components: {
login:{
template:'<h1>私有组件</h1>'
}
}
})
</script>
组件中的data和methods
组件可以有自己的data
组件中的data必须为一个function且要返回object
组件中的data数据使用方式和实例中data使用方式完全一样({{msg}})
<body>
<div id="app">
<my-coml></my-coml>
</div>
</body>
<script>
Vue.component('myComl',{
template:'<h1>这是全局组件{{msg}}</h1>',
data: function() {
return {
msg:'--组件中data定义的数据'
}
}
})
var vm = new Vue({
el:'#app',
data:{},
})
</script>
methods正常使用即可
methods:{
increment() {
this.count++
}
}
组件切换
使用v-if和v-else
缺陷:只能实现两个组件切换
<body>
<div id="app">
<a href="" @click.prevent="flag = true">登录</a>
<a href="" @click.prevent="flag = false">注册</a>
<login v-if="flag"></login>
<register v-else="flag"></register>
</div>
</body>
<script>
Vue.component('login',{
template:'<h3>登录组件</h3>'
})
Vue.component('register',{
template:'<h3>注册组件</h3>'
})
var vm = new Vue({
el:'#app',
data:{
flag:true
},
})
</script>
使用component
Vue提供了component来展示对应名称的组件
component是一个占位符,:is?属性可以用来指定要展示的组件的名称
<body>
<div id="app">
<a href="" @click.prevent="comName='login'">login</a>
<a href="" @click.prevent="comName='register'">register</a>
<component :is="comName"></component>
</div>
</body>
<script>
Vue.component('login',{
template:'<h3>登录组件</h3>'
})
Vue.component('register',{
template:'<h3>注册组件</h3>'
})
var vm = new Vue({
el:'#app',
data:{
comName:'login'
},
})
</script>
组件切换动画
用transition包裹component
通过mode属性,设置组件切换时的方式
mode=“out-in”?实现完全出去再进来的效果
<transition mode="out-in">
<component :is="comName"></component>
</transition>
组件传值
父组件向子组件传值
在Vue中默认子组件无法直接获取父组件中的数据
父组件如果想要给子组件传递数据,则需要使用属性绑定(v-bind)的形式
<body>
<div id="app">
<com1 :msg="parentMsg"></com1>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data:{
parentMsg:'parent'
},
components:{
'com1':{
template:`<div>
<h3>这是子组件的标题{{msg}}</h3>
</div>`,
props:['msg']
}
}
})
</script>
在Vue中,只有props是数组,其他的s后缀的属性都是对象
注意:组件中所有props中的数据,都是通过父组件传递给子组件的;子组件的data数据不是父组件传递过来的,而是子组件私有的。比如子组件通过AJAX请求回来的数据都可以放到data上。 data上的数据可读可写;props中的数据只可读。
父组件向子组件传递方法
父组件向子组件传递方法,使用的是事件绑定机制:v-on,当自定义了一个事件属性之后,那么子组件就能够通过某些方法来调用传递进去的这个方法
<body>
<div id="app">
<com2 @func="show"></com2><!--父组件的方法-->
</div>
<template id="tmp">
<div>
<h1>This is the son</h1>
<input type="button" value="触发父组件" @click="myClick"><!--子组件的方法-->
</div>
</template>
</body>
<script>
var com2 = {
template:'#tmp',
methods: {
myClick() {
this.$emit('func')
}
}}
var vm = new Vue({
el:'#app',
data:{
},
methods: {
show() {
console.log('调用了父组件身上的methods');
}},
components: {
com2
}
})
</script>
$emit('')?用此触发传递过来的方法,从第二个参数开始,都可以传参
ref获取DOM元素和组件
使用$refs
<body>
<div id="app">
<input type="button" value="获取元素" @click="getElement">
<h3 ref="myH3">123</h3>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data: {
},
methods: {
getElement() {
console.log(this.$refs.myH3.innerText);
}
}
})
</script>
ref引用组件的意义
|