前言:
上一章已经学会如何创建vue实例了,这一章是vue的基础知识点,包括模板语言,以及常见的一些命令。最底部有运行好的全部代码链接。
常见报错:
hbuiderX不报错的话去浏览器运行。一些warn可以不用管。
没有任何渲染:
检查是否写了容器app
检查实例是否绑定了这个app。vm.mount(’#app’)
检查你的html代码是否写到了app容器外面
检查{{ }} 里面是否有格式错误。
假如你的浏览器仍然是{{ pop }},没有渲染上可能原因:
双括号里面没有空出来空格{{pop}} ,有时不空出来也没事。
data那里该有的逗号没写,
vue实例data下面多半个“{”或者少半个“{”。
部分没有执行:渲染不上或者事件没有执行函数。
一定要注意你应用的变量是否和data里写的是一个,经常相近的单词会写错。
比如data里是arr,应用的时候很容易自己写成this.arrlist等。或者CV大法的代码(bushi)记得改 变量。
函数里要注意的:
data(){
return data
}, //这个别丢
methods:{//冒号别忘了写
func0(){//()别忘了写
},
func:(){//这里多加了一个冒号,应去掉。
//和es5写法不要混了。
},
func1:function(){
//正确的es5写法
}
,//两个函数相邻这个逗号
func2(){
}//最后数数,别多一个少一个
}
不显示图片
到浏览器运行显示图片。
v-for遍历的时候,显示值不正确。
在遍历的时候,有两种的得到值的办法,一种是{{ value }},另一种是在属性中写,title=“value”.
但这样写是不对的,经常会忘记给属性绑定上,才会得到变量的值value。正确写法 :title=“value”
<div v-for="value in namearr">
<input type="checkbox" :id="value" :value="value" v-model="checkedNames" />
<label :for="value">{{ value }}</label><br />
</div>
要想让namearr的数据全显示出来,而不是显示value的话,标签里写{{ }},属性要加上冒号才能表示value.
模板语言:
差值表达式/mastach语法:把变量绑定在标签内部{{ msg }}
文本差值中还可以写表达式用于判断:
{{ opop?“yes”:“no” }}
opop的值是true,则渲染yes,否则渲染no。opop:1,渲染yes.
{{num+1}}
data={ ok:”1”,num:10}
常用指令:
指令带有前缀 v-
,以表示它们是 Vue 提供的特殊 attribute。
数据双向绑定v-model
表单输入绑定,不只应用于表单。 v-model="value1"它取代的是 :value=“value” ,有了v-model就不用绑定value了。
<div id="app">
<h4>vue的双向绑定的功能</h4>
<input type="text" v-model="value1"/>
<h3>{{ value1 }}</h3>
</div>
const data = {
value1:"balabalabal",
}
那么这个时候就会觉得input的value好像没作用了,或者感觉这俩作用一样,这是一个误区。
实际上v-model绑定的是value值,它实现的是视图和data的双向绑定,任何一个变,另一个都会实时改变。
视图层和数据层可以互相改变。
:value
:value只是绑定了初始的时候data里的值,给渲染到浏览器。
<input type="text" :value="value1" />
{{ value1 }}
data={
value1:123456
}
当我们改变输入框的值时,我们去掉3个改成123,渲染的value1不会发生变化。不能由视图层改数据层。
它只能由数据层渲染到视图,也就是说data里面改变了,视图层才会变化,反着不行。
data={
value1:123
}
假如只绑定了:value,如何实现数据的双向绑定呢?
:value实现数据双向绑定
input事件可以实现。
简写:
<input type="text" @input="value1=$event.target.value" :value="value1" />
{{ value1 }}
data={
value1:123
}
简写看不懂的看这个理解一下:
//html
<button @click='handleclick'>点击</button>
<button @click='handleclick1($event)'>点击1</button>
//js
methods:{
handleclick(e){
//e不用传参,e.target得到的就是点击对象
console.log("我是点击的对象"+e.target)
//我是点击的对象[object HTMLButtonElement]
},
handleclick1:(e){
//传参$event后e就是$event,实际结果都是得到鼠标点击的button对象
console.log("我是点击的对象"+e.target)
//我是点击的对象[object HTMLButtonElement]
},
}
通过这个例子可以明白在函数里e.target就是得到事件对象的。
:value不能从由视图层改变到数据层改变。也就说,实现这一步就可以双向绑定了,那需要做的就是得到视图层的数据,把它赋给数据层。
数据层数据=视图层数据
我们需要一个事件,可以是点击事件,也可以是input事件,让他去调用函数,在函数里得到视图层的数据,e.target如上述是事件对象,那么在input里这个事件对象就是input标签,e.target.value就是视图层的数据
在函数中的得到数据层数据是this.data。
那为什么是this的data呢,这个记住就可以,vue在实例化的时候改变了this的指向,使this能够访问到data的数据。与this的其他指向无关。
还是why?
所以在函数中赋值即可:
this.msg = e.target.value;
input中的事件会在value改变的时候调用这个函数,用改变的value给msg赋值,使之能够实时渲染,这样就可以实现双向绑定。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.global.js"></script>
</head>
<body>
<div id="app">
<div>
<input type="text" @input="handleInput" :value="msg" />
<div>{{ msg }}</div>
</div>
</div>
</body>
<script type="text/javascript">
data = {
msg:'123',
}
const vm = Vue.createApp({
data() {
return data
},
methods:{
handleInput(e){
this.msg = e.target.value;
},
}
})
vm.mount('#app')
</script>
</html>
改变框的值,msg渲染也可以改变。
那已经有v-model了,:value实现双向绑定有什么作用呢?
:value实现双向绑定的作用
当v-model不生效的时候替代v-model。
v-model双向绑定的依据是通过data里面的渲染到v-model上,必须直接改变data里的值才会和input框同步渲染。
<input type="number" value="One" v-model="aaa" />
data={
aaa:1
}
有一种情况是当input的value值不通过data里的aaa改变,而是像下边一样通过一个事件函数自行改变,在视图层就自行变化了,没有通过aaa传值。此时v-model的值也能显示,但与input的value值不匹配。可能会出现多一位的情况.
当事件在视图层改变了value值的时候,v-model很可能失效。
<input type="number" oninput="if (value < 0) value = 0; if(value>1000) value=1000;"/>
这时我们就需要:value来控制。通过上面:value的双向绑定详解也能知道,:value是将数据层的值赋给
:value代替v-model的用法:
看这个例子:oninput改变了视图层的value值。v-model得出来的值与框里不一致。限定最大值1000后还比它多一位。
这是用v-model时,v-model绑定的商品数量
<tr v-for="item,index in goodslist" :key='index'>
<td><input type="number" min="0" max="1000"
oninput="if (value < 0) value = 0; if(value>=1000) value=1000;"
v-model='item.count'
>
</td>
<td>单个价格:{{ item.price*item.count }} 单个数量--- {{ item.count}}</td>
<td><button :disabled="item.count<=0" >删除</button></td>
</tr>
这是用:value。v-model绑定的谁,用:value就绑定谁,同时给input绑定上,函数名也是这个。
特别要注意的是@input=“value1=$event.target.value” :value="value1"一定要写在事件(oninput)的后面,否则会和v-model效果一样。
<tr v-for="item,index in goodslist" :key='index'>
<td><input type="number" min="0" max="1000"
oninput="if (value < 0) value = 0; if(value>=1000) value=1000;"
onkeypress="return event.charCode >=48 && event.charCode <=57 "
@input="item.count=$event.target.value)"
:value="item.count" >
</td>
<td>{{ item.price*item.count }} 数量--- {{ item.count }}</td>
<td><button :disabled="item.count<=0" >删除</button></td>
</tr>
v-model绑定单选框
由于是单选,所以不用像复选框一样在选中的值上绑定一个数组,可以绑定一个字符串即可,然后选中哪个,字符串表示的就是哪个单选的value值。
<body>
<div id="app">
<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>
<br />
<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
<br />
<span>单选值: {{ picked }}</span>
</div>
</body>
<script type="text/javascript">
data = {
picked: ''
}
const vm = Vue.createApp({
data() {
return data
},
})
vm.mount('#app')
</script>
v-model绑定复选框
checkbox会将鼠标选中项的value值自动添加到v-model绑定的数组中.
v-model绑定的是checkedNames: []这个空数组,那么当我们点击input复选框时,打勾的(选中的)会进入这个数组中,并且我们可以用{{checkedNames }}让它显示出来。
<input type="checkbox" id="jack" />
<label for="jack">Jack</label>
input给一个id,label一个for写id名,是为了点击label时,input框高亮,是为了让他们俩联系起来。与本题无关。
官网给出的例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.global.js"></script>
</head>
<body>
<div id="app">
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames" />
<label for="jack">Jack</label><br />
<input type="checkbox" id="john" value="John" v-model="checkedNames" />
<label for="john">John</label><br />
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames" />
<label for="mike">Mike</label><br />
<br />
<span>选中的会放在v-model绑定的数组checkedNames这里: {{ checkedNames }}</span>
</div>
</body>
<script type="text/javascript">
data = {
checkedNames: []
}
const vm = Vue.createApp({
data() {
return data
},
})
vm.mount('#app')
</script>
</html>
我们可以用v-for表示复选框。
给一个namearr代表各个复选框的值,点击的会进入另一个数组checkedNames。
<body>
<div id="app">
<div v-for="value in namearr">
<input type="checkbox" :id="value" :value="value" v-model="checkedNames" />
<label :for="value">{{ value }}</label><br />
</div>
<span>checkedNames: {{ checkedNames }}</span>
</div>
</body>
<script type="text/javascript">
data = {
namearr:["jack","jone","mike"],
checkedNames: []
}
const vm = Vue.createApp({
data() {
return data
},
})
vm.mount('#app')
</script>
v-model绑定多选框
v-model多选框,写在selecet上,绑定的是选中的值,选中哪个绑定哪个,如果option中没有写value,那么它值的是option标签里的文字,如果写了value,它指的就是value值。
v-if v-else-if v-else
利用v-if可以直接写判断语句,直接在标签里判断,当istrue=0时只显示pop,当=1时显示pop1,当都不是时,显示v-else的内容。它们仨只有一个显示,一般只用到v-if。
哪个为真显示哪个,三者中间不能有别的标签。
<h4> v-if的用法</h4>
<p v-if="istrue==0">{{ pop }}</p>
<p v-else-if="istrue==1">{{ pop1 }}</p>
<p v-else>我是else</p>
const data = {
istrue:1,
pop:"我是if",
pop1:"istrue=1,我是else if",
}
它可以控制元素的显示与隐藏 ,(通过移除dom标签控制,用于只判断一次的(例如刚进页面时)。
也就是,表面上它只显示了pop1,实际上也只有pop1标签存在,其余两个均被移除。去浏览器控制台看。
元素显示与隐藏v-show
也是控制元素的显示与隐藏。(通过控制样式display:none)用于频繁切换显示与隐藏。
<p v-show="show">我是v-show</p>
data={
show:true,
}
如果show:false,则标签会加一行样式display:none来控制它的隐藏。
根据这个特性,v-if和v-show在应用显示与隐藏时还有另一个区别:
v-if可以用于虚拟的template标签里面,v-show不可以,因为虚拟标签无样式。虚拟标签这个标签不会显示在页面检查里。
template
所以在template里只能用v-if控制显示与隐藏。
循环语句v-for
<h4>创建数组,并且在页面中遍历数据 显示数据</h4>
<li v-for="item in arr">{{ item }}</li>
<h4>创建对象,并且在页面中遍历对象 显示数据</h4>
<li v-for="value in obj">{{ value }}---</li>
<!--v-for的item in arr==item of arr -->
const data = {
arr:[1,2,3,4,5],
obj:{
name:'xiaoming',
age:'19'
},
}
还可以这样写:
<!--1).数组 也可以不写小括号item,index in arr-->
<ul>
<li v-for="(item,index) in arr">{{item}}---{{index}}</li>
</ul>
<!--2).对象-->
<ul>
<li v-for="(value,key) in obj">{{value}}--{{key}}</li>
</ul>
<p>{{obj.name}}===={{obj.sex}}</p>
<!--3) 数字遍历-->
<ul>
<li v-for="item in 4">{{item}}</li>
</ul>
<!--4)字符串遍历-->
<ul>
<li v-for="item in 'Yahoo'">{{item}}</li>
</ul>
例:创建数组 长度为5,在页面中遍历数组的时候只显示1,2,3索引处的值
<li v-for="item in arr.slice(1,4)">索引{{item-1}}:{{ item }}</li>
// 回忆一下slice 和splice
// 1.slice: slice(index,index+1);
var arr=[1,2,3,4,5,6];
var arr2=arr.slice(2,4)//返回的应该是索引(2,3)之间的值
// 返回后原来arr无变化
arr2=[3,4];
arr=[1,2,3,4,5,6];
// 2.splice: 删除或添加
// 两个值:删除 splice(index,从索引处数几个)
// 三个值:添加 splice(index,0,"hello")
//在指定位置插入指定长度的字符,第二个代表占用字符的长度,0代表不占用字符
var arr1=[1,2,3,4,5,6];
var arr3=arr.splice(2,4);//删除arr1从索引2往后数4个的值,arr1=[1,2]
arr3=[3,4,5,6]//splice会形成新数组
//arr1会删减为剩下的。
或者,只想显示一个数组的前两项,可以用v-if决定。
<ul>
<li v-for="value,index in arr0" >
<span v-if="index<=1">{{ value }} {{ index }} </span>
</li>
</ul>
数组为空不显示做法
数组内有值就让他显示值,没有就显示数组为空。
应用if判断,长度不等于0就显示数组内容,=0就显示为空。
<ul v-if="arr.length!=0">
<li v-for="value,index in arr0" >
<span v-if="index<=1">{{ value }} {{ index }} </span>
</li>
</ul>
<p v-else>数组为空</p>
属性绑定v-bind
用于属性的绑定,当属性需要变化时,用v-bind绑定属性。
例如 title ,src, index等属性都可以绑定变量。
v-bind写法等同于冒号。
例如 v-bind:src=“imgUrl” 等同于:src=“imgUrl”
<h4>2.2 v-bind,也可以写:</h4>
<img :src="imgUrl" :alt="name" width="100" height="100" />
const data = { imgUrl:"https://ps.ssl.qhimg.com/sdmt/432_324_100/t01ecdff6694bf22e0c.webp",
}
当属性,一半需要变量,另一半需要写死怎么写:
例如鼠标移上显示标题:要求有个前缀:美味的+变量
这时我们可以把死的数据写在单引号里。
v-bind:title="'美味的'+pop"
添加样式 :class :style
:class
<!--直接写-->
<h2 :class="h2red">我是绑定红色的class</h2>
<!--数据层-->
data = {
h2red:red,
}
<!--css里面:-->
red:{
color:"red"
}
<!--或者也可以在数据层直接写:-->
data = {
h2red:{
color:"red"
}
}
<!--可以用对象判断是否给这个标签添加此样式,false不会执行此样式-->
<h5 :class="{blue:true}">添加蓝色</h5>
<!--数组用来绑定多个属性-->
<h2 :class="[h2red,bg]">我绑定了两个class</h2>
<!-- 也可以用字符串表示-->
<h2 :class="a">我绑定了两个class</h2>
data={
a:'h2red bg',
a:["h2red","bg"], //注意这里数组里是双引号的,上面h5的数组由于是个变量,不是带字符串的。
}
<!--对于原来就有的class为big,绑定class后原来的big 依然存在-->
<h6 :class="[{red:h6true},h5class]" class="big">{{ name }}</h6>
<!--绑定了多个class,再在后面写个class绑定,则不会执行后面的big,只执行第一个绑定-->
<h6 :class="[{red:h6true},h5class]" :class="big">{{ name }}</h6>
<!--class还可以用数组的项绑定-->
<h3 :class="h3arr[0]">class还可以用数组绑定</h3>
:style
<!--绑定style只能用对象,不可以直接写-->
<h4 :style="{border:'1px solid blue'}">style</h4>
<!--或者把对象写到data里面-->
<h4 :style="color1">style</h4>
data={
color1={border:'1px solid blue'},
}
<!--绑定多个style用数组。原来存在的style也会生效,color写在data里,也是一个对象-->
<h4 :style="[{border:'1px solid red'},color]" style="background-color: yellow;">style多个绑定</h4>
v-html
data里面想写标签可以用,并且这个标签包含在div这个标签里面。
<div v-html="html"></div>
data={
html:'<p>我是p标签</p>'
}
控制台:
如果不用v-html,直接用{{ }}引用的话,浏览器不会解析,浏览器上不会显示“我是p标签”,而是显示/
我是p标签/
。v-on添加点击事件
V-on:也可以写成@
事件对象—标签
事件类型—click
事件侦听函数–function
V-on:click=func(num)
Methods:{
Func(num){
Console.log(num)
}
}
<h4> v-on:click="handelclick()" 表示侦听点击事件</h4>
<button v-on:click="handelclick()" >点击事件</button>
<h4>this的指定</h4>
<button v-on:click="handleClick1 ()">点击我{{count}}</button>
<h4>传参</h4>
<ul>
<li v-for="value,index in arr0" v-on:click="handleClick2 (index)">{{ value }} {{ index }} </li>
</ul>
handleClick ()
点击事件函数都在methods里,给按钮绑定函数,点击按钮即可实现函数内容。
handleClick1 ()
比如我们想让handleClick1 ()实现点击一次按钮就加一,我们点击的这个按钮标签,就是点击事件的对象,需要用到this,this指的是事件对象,那这个对象在vue中就是data,,点击按钮实现count+1,需要写成this.count+=1。
this在methods里面代表的是data里面的数据和事件。
这句话有啥用嘞?
说明 当我们想在函数中得到data里面的数据时可以用this.xx获得,想得到某个事件时,用this指代事件对象。
那我们想在函数中得到html5的数据怎么办?可以用传参,也就是下面的handleClick2 (index)。
handleClick2 (index)
当我们需要参数时,可以传参,在调用函数时,把index传回函数即可。
returnfunc()
methods的函数调用也可以不用事件,直接用{{}}能调用,把值return回去即可。
记得一定要写return。
{{returnfunc()}}
<h3>{{returnfunc()}}</h3>
data{
count:10,
ret:'我是直接调用的函数'
}
const vm = Vue.createApp({
data() {
return data
},
methods:{
handelclick(){
console.log("已点击")
},
handleClick1 (){
console.log(this)
this.count+=1
},
handleClick2 (num){
console.log("点击得到index"+num)
},
//methods的函数调用也可以不用事件,也能调用,把值return回去即可
//调用直接写{{函数名()}}
//包括created computed等函数都直接调用
returnfunc:function(){
return this.ret;
}
}
}).mount('#app')
通过上述可以完成的两个小案例。
1.备忘录的做法
2.购物车增加和删除做法。