一、初识Vue
初识vue:
(1)想让vue工作,就必须创建一个vue实例,且要传入一个配置对象
(2)root容器里的代码依然符合html规范,只不过混入了一些特殊的vue语法
(3)root容器里的代码被称为【vue模板】
(4)vue实例和容器是一一对应的
(5)真实开发中只有一个vue实例,并且会配合着组件一起使用
(6){{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性
(7)一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新
注意区分js表达式和js代码(语句)
(1)表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方
(2)语句:不会产生值if for
<!--准备好一个容器-->
<body>
<div id="root">
<h1>hello,{{name}}</h1>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示
//创建vue实例
new Vue({
el:'#root',//el用于指定当前vue实例为哪个容器服务,值通常为css选择器字符串
data:{//data中用于存储数据,数据供el所指定的容器去使用,值暂时先写成一个对象
name:'张三'
}
})
</script>
二、模板语法
vue模板语法有两大类:
1、插值语法:
(1)功能:用于解析标签体内容。
(2){{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性
2、指令语法:
(1)功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…)
(2)举例:v-bind:href=“xxx” 或 简写为 :href=“xxx” .xxx同样要写js表达式,
且可以直接读取到data中的所有属性
(3)备注:vue中有很多的指令,且形式都是: v-??? ,此处我们只是拿v-bind举个例子
<body>
<div id="root">
<h1>插值语法</h1>
<h3>你好,{{name}}</h3>
<hr />
<h1>指令语法</h1>
<a :href="school.url">点我去{{school.name2}}学习</a>
</div>
</body>
<script>
Vue.config.productionTip = false //阻止vue在启动时生成产生提示
new Vue({
el:"#root",
data:{
name:'jack',
school:{
name2:'张三',
url:'http://www.baidu.com'
}
}
})
</script>
三、数据绑定
vue中有2中数据绑定的方式:
1、单向绑定(v-bind):数据只能从data流向页面
2、双向绑定(v-model):数据不仅能从data流向页面。还可以从页面流向data
备注:
(1)双向绑定一般都应该在表单类元素上(如:input、select)
(2)v-model:value 可以简写为v-model 因为v-model默认收集的就是value值
<body>
<!--准备好一个容器-->
<div id="root">
<!--普通写法-->
<!--单项数据绑定:<input type="text" v-bind:value="name" /><br />
双项数据绑定:<input type="text" v-model:value="name" />-->
<!--简写-->
单项数据绑定:<input type="text" :value="name" /><br />
双项数据绑定:<input type="text" v-model="name" />
<!--一下代码是错误的,因为v-model只能应用在表单类元素(输入类元素)上。要有value属性-->
<!--<h2 v-model:x="name">你好啊</h2>-->
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止vue 在启动时生成提示
new Vue({
el:'#root',
data:{
name:'张三'
}
})
</script>
四、el与data的两种写法
1、el有两种写法:
(1).new Vue时候配置el属性
(2)先创建vue实例,随后在通过vm.$mount(’#root’)指定el的值
2、data有两种写法
(1).对象式
(2).函数式
如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错
3、一个重要原则:
由vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是vue实例了
<!--定义一个容器-->
<body>
<div id="root">
<h1>你好,{{name}}</h1>
</div>
</body>
<script>
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示
//el的两种写法
/*const v = new Vue({
//el:'#root', //第一种写法
data:{
name:'张三'
}
})
console.log(v);
v.$mount('#root')*/ //第二种写法
//data的两种写法
new Vue({
el:'#root',
/*data:{
name:'张三' //第一种写法
}*/
data(){
return{
name:'张三'
}
}
})
</script>
五、MVVM模型
MVVM模型
M 模型(Model) data中的代码
V 视图(View) 模板代码
VM 视图模型(ViewModel) Vue实例MVVM模型的核心是提供对View 和 ViewModel 的双向数据绑定。在MVVM的架构下,View层和Model层并没有直接联系,而是通过ViewModel层进行交互。ViewModel层通过双向数据绑定将View层和Model层连接了起来,使得View层和Model层的同步工作完全是自动的。
观察发现:
(1)data中的所有属性,最后都出现在了VM身上
(2)VM身上的所有属性 及 vue原型上的所有属性 在vue模板中都可以直接使用
<!--定义一个容器-->
<body>
<div id="root">
<h1>学校名称:{{name}}</h1>
<h1>学校地址:{{address}}</h1>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时产生生产提示
const vm = new Vue({
el:'#root',
data:{
name:'张三',
address:'中国'
}
})
console.log(vm)
</script>
六、数据代理
1、回顾Object.definedProperty
<script type="text/javascript">
let number = 18
let person = {
name:'张三',
sex:'女'
}
Object.defineProperty(person,'age',{
//value:18,
//enumerable:true, //控制属性是否可以枚举,默认值是false
//writable:true, //控制属性是否可以被修改,默认值是false
//configurable:true //控制属性是否可以被删除,默认值是false
//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值都是age的值
get:function(){
return number
}
//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
set(value){
number = value
}
})
/*console.log(Object.keys(person))*/
console.log(person);
</script>
2、何为数据代理
<!--数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)-->
<script>
let obj = {x:100}
let obj2 = {y:200}
Object.defineProperty(obj2,'x',{
get(){
return obj.x
}
set(value){
obj.x = value
}
})
</script>
3、vue中的数据代理
1、vue中的数据代理:通过VM对象来代理data对象中属性的操作(读/写)
2、vue中数据代理的好处:更加方便的操作data中的数据
3、基本原理:
(1)通过Object.definedProperty() 把data对象中所有属性都添加到VM上
(2)为每一个添加到VM上的属性,都指定一个getter/setter
(3)在getter/setter内部去操作(读/写)data中对应的属性
<!--创建一个容器-->
<div id="root">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
</body>
<script>
Vue.config.productionTip = false //阻止 vue 启动时产生提示
/*let data = { //验证 vm._data = options.data = data
name:'张三',
address:'北京'
}*/
const vm = new Vue({
el:'#root',
data:{
name:'张三',
address:'北京'
}
})
</script>
七、事件处理
1、事件的基本使用
事件的基本使用:
(1)使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名
(2)事件的回调需要配置在methods对象中,最终会在VM上
(3)methods中配置的函数,不要用箭头函数!否则this就不是VM了
(4)methods中配置的函数,都是被vue所管理的函数,this的指向是VM 或组件实例对象
(5)@click=“demo” 和 @click=“demo($event)” 效果一致,但后者可以传参
<!--定义一个容器-->
<body>
<div id="root">
<h2>欢迎来到{{name}}学习</h2>
<!--<button v-on:click="showInfo">点我提示信息</button>-->
<button @click="showInfo1">点我提示信息1</button>
<button @click="showInfo2(66,$event)">点我提示信息2</button>
</div>
</body>
<script>
Vue.config.productionTip = false //阻止 vue 启动时产生的提示信息
const vm = new Vue({
el:'#root',
data:{
name:'张三'
},
methods:{
showInfo1(event){
alert("同学你好1")
//console.log(this) //此处的this是vm
},
showInfo2(number,event){
console.log(number)
}
}
})
</script>
2、事件修饰符
vue中的事件修饰符:
(1)prevent:阻止默认事件(常用)
(2)stop:阻止事件冒泡(常用)
(3)once:事件只触发一次(常用)
(4)capture:使用事件的捕获模式
(5)self:只有event.target是当前操作的元素时才触发事件
(6)passive:事件的默认行为立即执行,无需等待事件回调执行完毕
<style type="text/css">
.demo1 {
height: 50px;
background-color: skyblue;
}
* {
margin-top: 10px;
}
.box1 {
padding: 10px;
background-color: skyblue;
}
.box2 {
background-color: orange;
}
.list {
width: 200px;
height: 200px;
background-color: pink;
overflow: auto;
}
li {
height: 100px;
}
</style>
<body>
<!--创建一个容器-->
<div id="root">
<h2>欢迎来到{{name}}来学习</h2>
<!--阻止默认事件-->
<a href="http://www.baidu.com" @click.prevent="showInfo">点我提示信息</a>
<!--阻止事件冒泡-->
<div class="demo1" @click="showInfo">
<button @click.stop="showInfo">点我提示信息</button>
</div>
<!--修饰符可以连续写-->
<!--先阻止默认事件,再阻止冒泡。可以反过来,效果一样-->
<a href="http://www.baidu.com" @click.stop.prevent="showInfo">点我提示信息</a>
<!--事件只触发一次-->
<button @click.once="showInfo">点我提示信息</button>
<!--使用事件的捕获模式-->
<div class="box1" @click.capture="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
</div>
</div>
<!--self:只有event.target是当前操作的元素时才触发事件-->
<div class="demo1" @click.self="showInfo">
<button @click="showInfo">点我提示信息</button>
</div>
<!--passive:事件的默认行为立即执行,无需等待事件回调执行完毕-->
<ul class="list" @wheel.passive="demo">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
</body>
<script>
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'尚硅谷'
},
methods:{
showInfo(e){
alert("点我确定")
/*console.log(e.target)*/
},
showMsg(msg){
console.log(msg)
},
demo(){
for(let i=0;i<100000;i++){
console.log('#')
}
console.log("累坏了")
}
}
})
</script>
3、键盘事件
(1)vue中常用的按键别名:
回车 enter
删除 delete
退出 esc
空格 space
换行 tab (特殊,必须配合keydown)
上 up
下 down
左 left
右 right
(2)vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
(3)系统修饰键(用法特殊):ctrl alt shift meta
----配合keyup使用:按下修饰键的同时,在按下其他键,随后释放其他键,事件才被触发
----配合keydown使用:正常触发事件(4)也可以使用keyCode去指定具体的按键(不推荐) keydown.13
(5)Vue.config.keyCode 自定义键名 = 键码 可以去定制按键别名
<body>
<!--创建一个容器-->
<div id="root">
<h2>欢迎来到{{name}}来学习</h2>
<input type="text" placeholder="按下回车提示输入" @keyup="showInfo">
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
Vue.config.keyCodes.huiche = 13 //定义了一个别名按键
new Vue({
el:'#root',
data:{
name:'尚硅谷'
},
methods:{
showInfo(e){
console.log(e.key,e.keyCode)
/*console.log(e.target.value)*/
}
}
})
</script>
八、计算属性
1、姓名案例_插值语法实现
<body>
<!--创建一个容器-->
<div id="root">
姓:<input type="text" v-model='firstName'/><br /><br />
名:<input type="text" v-model='lastName'/><br /><br />
全名:<span>{{firstName.slice(0,3)}}-{{lastName}}</span>
</div>
</body>
<script>
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三'
}
})
</script>
2、姓名案例_methods实现
<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>
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三'
},
methods:{
fullName(){
return this.firstName+"-"+this.lastName
}
}
})
</script>
3、姓名案例_计算属性实现
计算属性:
(1)定义:要用的属性不存在,要通过已有的属性计算得来
(2)原理:底层借助了Object.definepeoperty方法提供的getter和setter
get函数什么时候执行?
(1)初次读取的时候会执行一次
(2)当依赖的数据发生改变时会被再次调用
优势:与methods实现相比,内部会有缓存机制(复用),效率更高,调试方便
备注:
(1)计算属性最终会出现在vm上,直接读取使用即可
(2)如果计算属性要被修改,那必须写set函数去影响修改,且set中要引起计算时依赖的数据发生改变
<!--创建一个容器-->
<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>
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三'
},
computed:{
fullName:{
//get作用:当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
//get什么时候调用?
//1、初次读取fullName时
//2、所依赖的数据发生变化时
get(){
return this.firstName+"-"+this.lastName
},
//set什么时候调用?当fullName被修改时
set(value){
console.log('set',value)
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
}
})
</script>
4、姓名案例_计算属性简写
<!--创建一个容器-->
<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>
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三'
},
computed:{
//完整写法
/*fullName:{
get(){
return this.firstName+"-"+this.lastName
},
//set什么时候调用?当fullName被修改时
set(value){
console.log('set',value)
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}*/
//简写:只读取不修改
fullName(){//相当于getter函数
eturn this.firstName+"-"+this.lastName
}
}
})
</script>
九、监视属性(侦听属性)
1、天气案例
<body>
<!--准备好一个容器-->
<div id="root">
<h1>今天天气很{{info}}</h1>
<button @click="isHot = !isHot">切换天气</button><!--可以写一些简单的语句-->
</div>
</body>
<script>
Vue.config.productionTip = false //阻止 vue 启动时生成提示信息
new Vue({
el:'#root',
data:{
isHot:true
},
computed:{
info(){
return this.isHot ? '炎热' : '清爽'
}
},
methods:{
/*changeWeather(){
this.isHot = !this.isHot
}*/
}
})
</script>
2、天气案例_监视属性
监视属性watch:
(1)当被监听的属性变化时,回调函数自动调用(handler),进行相关操作
(2)监视的属性必须存在,才能进行监视
(3)监视的两种写法:
-------new Vue时传入watch配置
-------通过vm.$watch监视
<!--准备好一个容器-->
<div id="root">
<h1>今天天气很{{info}}</h1>
<button @click="changeWeather">切换天气</button>
</div>
</body>
<script>
Vue.config.productionTip = false //阻止 vue 启动时生成提示信息
const vm = new Vue({
el:'#root',
data:{
isHot:true
},
computed:{
info(){
return this.isHot ? '炎热' : '清爽'
}
},
methods:{
changeWeather(){
this.isHot = !this.isHot
}
},
/*watch:{
idHot:{
immediate:false, //初始化时让handler调用一下
//handler什么时候调用?当isHot发生改变时
handler(newValue,oldValue){
console.log(newValue,oldValue)
}
}
}*/
})
vm.$watch('isHot',{
immediate:false, //初始化时让handler调用一下
//handler什么时候调用?当isHot发生改变时
handler(newValue,oldValue){
console.log(newValue,oldValue)
}
})
</script>
3、天气案例_深度监视
深度监视:
(1)vue中的watch默认不监测对象内部值的改变(一层)
(2)配置deep:true可以监测对象内部值的改变(多层)
备注:
(1)vue自身可以监测对象内部值的改变,但vue提供的watch默认不可以
(2)使用vue时根据数据的具体结构,决定是否采用深度监视
<!--准备好一个容器-->
<div id="root">
<h1>今天天气很{{info}}</h1>
<button @click="changeWeather">切换天气</button>
<hr />
<h3>a的值是:{{numbers.a}}</h3>
<button @click="numbers.a++">点我让a+1</button>
<h3>b的值是:{{numbers.b}}</h3>
<button @click="numbers.b++">点我让b+1</button>
</div>
</body>
<script>
Vue.config.productionTip = false //阻止 vue 启动时生成提示信息
const vm = new Vue({
el:'#root',
data:{
isHot:true,
numbers:{
a:1,
b:2
}
},
computed:{
info(){
return this.isHot ? '炎热' : '清爽'
}
},
methods:{
changeWeather(){
this.isHot = !this.isHot
}
},
watch:{
isHot:{
/*immediate:false, //初始化时让handler调用一下*/
//handler什么时候调用?当isHot发生改变时
handler(newValue,oldValue){
console.log(newValue,oldValue)
}
},
/*//监视多级结构中某个属性的变化
'numbers.a':{
handler(){
console.log('a被改变了')
}
}*/
//监视多级结构中所有属性的变化
numbers:{
deep:true,
handler(){
console.log('number改变了')
}
}
}
})
</script>
4、天气案例_监视属性_简写
<body>
<!--准备好一个容器-->
<div id="root">
<h1>今天天气很{{info}}</h1>
<button @click="changeWeather">切换天气</button>
</div>
</body>
<script>
Vue.config.productionTip = false //阻止 vue 启动时生成提示信息
const vm = new Vue({
el:'#root',
data:{
isHot:true,
numbers:{
a:1,
b:2
}
},
computed:{
info(){
return this.isHot ? '炎热' : '清爽'
}
},
methods:{
changeWeather(){
this.isHot = !this.isHot
}
},
watch:{
/*//正常写法
isHot:{
//immediate:false, //初始化时让handler调用一下
//deep:true //深度调用
handler(newValue,oldValue){
console.log(newValue,oldValue)
}
}*/
//简写
/*isHot(newValue,oldValue){
console.log(newValue,oldValue)
}*/
}
})
vm.$watch('isHot',function(newValue,oldValue){
console.log(newValue,oldValue)
})
</script>
5、姓名案例_watch实现
computed和watch之间的区别:
(1)computed能完成的功能,watch都可以完成
(2)watch能完成的功能,computed不一定能完成。例如:watch可以进行异步操作
两个重要的小原则:
(1)所有被vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象
(2)所有不被vue所管理的函数(定时器的回调函数、Ajax的回调函数等、promise的回调函数),最好写成箭头函数
这样this的指向才是vm或组件实例对象
<!--创建一个容器-->
<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>
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三',
fullName:'张-三'
},
watch:{
firstName(newValue){
setTimeout(()=>{//延迟一秒
this.fullName = newValue+'-'+this.lastName
},1000);
},
lastName(newValue){
this.fullName = this.firstName+'-'+newValue
}
}
})
</script>
十、绑定样式
1、class样式
写法:class=“xxx” xxx可以是字符串、对象、数组
(1)字符串写法适用于:类名不确定、要动态获取
(2)对象写法适用于:要绑定多个样式,个数不确定,名字也不确定
(3)数组写法适用于:要绑定多个样式,个数确定,名字也确定。但不确定用不用
2、style样式
:style="{fontSize:xxx}" 其中xxx是动态值
:style="[a,b]"其中a、b是样式对象
<style>
.basic{
width: 300px;
height: 100px;
border: 1px solid gray;
}
.happy{
width: 300px;
height: 100px;
background-color: orange;
}
.sad{
width: 300px;
height: 100px;
background-color: gray;
}
.normal{
}
.atguigu1{
width: 300px;
height: 100px;
background-color: wheat;
}
.atguigu2{
width: 300px;
height: 100px;
background-color: aqua;
}
.atguigu3{
width: 300px;
height: 100px;
background-color: palegreen;
}
</style>
<!--创建一个容器-->
<div id="root">
<!--绑定class样式——字符串写法:适用于:样式的类名不确定,需要动态指定-->
<div class="basic" :class="mood" @click="changeMood">{{name}}</div>
<!--绑定class样式——数组写法:适用于:要绑定的样式个数不确定,名字也不确定-->
<div class="basic" :class="classArr">{{name}}</div>
<!--绑定class样式——对象写法:适用于:要绑定的样式个数确定,名字也确定,但要动态决定用不用-->
<div class="basic" :class="classObj">{{name}}</div>
<!--绑定style样式——对象写法-->
<div class="basic" :style="styleObj">{{name}}</div>
<!--绑定style样式——数组写法-->
<div class="basic" :class="styleArr">{{name}}</div>
</div>
</body>
<script>
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'张三',
mood:'normal',
classArr:['atguigu1','atguigu2','atguigu3'],
classObj:{
atguigu1:false,
atguigu2:false,
},
styleObj:{
fontSize:'40px'
},
styleObj2:{
backgroundColor:'orange'
},
styleArr:[
{
fontSize:'40px'
},
{
backgroundColor:'orange'
}
]
},
methods:{
changeMood(){
//this.mood = 'happy' 切换心情
const arr = ['happy','sad','normal']
const index = Math.floor(Math.random()*3)
this.mood = arr[index]
}
},
})
</script>
十一、条件渲染
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一定可以获取到
<div id="root">
<!--使用v-show做条件渲染-->
<!--<h2 v-show="false">欢迎来到{{name}}</h2>-->
<!--<h2 v-show="1===1">欢迎来到{{name}}</h2>-->
<!--使用v-if做条件渲染-->
<!--<h2 v-if="1===1">欢迎来到{{name}}</h2>-->
<h2>当前的n值是{{n}}</h2>
<button @click = "n++">点我+1</button>
<!--v-else和v-else-if-->
<!--<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>-->
<!--v-if 与 template 的配合使用-->
<template v-if="n===1">
<h2>你好</h2>
<h2>张三</h2>
<h2>北京</h2>
</template>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'北京',
n:0
}
})
</script>
十二、列表渲染
1、基本列表
v-for指令:
(1)用于展示列表数据
(2)语法:v-for="(item,index) in xxx" :key=“yyy”
(3)可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
<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,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>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
persons:[
{id:'001',name:"张三",age:14},
{id:'002',name:"李四",age:16},
{id:'003',name:"王五",age:11}
],
car:{
name:'奥迪',
price:'30w',
age:4
},
str:'hello'
}
})
</script>
2、key的原理
3、列表过滤
this.filPersons = this.persons.filter((p)=>{
return p.name.indexOf(val) !== -1
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 in filPersons" :key="p.id">
{{p.name}}-{{p.age}}-{{p.sex}}
</li>
</ul>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
keyWord:'',
sortType:0, //0原顺序,1降序,2升序
persons:[
{id:'001',name:"马冬梅",age:14,sex:'女'},
{id:'002',name:"周冬雨",age:16,sex:'女'},
{id:'003',name:"周杰伦",age:11,sex:'男'},
{id:'004',name:"温兆伦",age:15,sex:'男'}
]
},
computed:{
filPersons(){
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>