Vue学习(二)
Vue.js基础知识
①模板语法
代码如下:
<div id="app">
<h3>普通文字</h3>
<p>{{mustache}}</p>
<p v-text="mustache"></p>
<h3>插入原始html</h3>
<p v-html="htmls"></p>
<h3>html属性上插值</h3>
<ul>
<li v-for="i in 10" v-bind:id="'list'+i">{{i}}</li>
</ul>
<h3>对于属性值是false时在html上不显示</h3>
<button type="button" v-bind:disabled="no">点击</button>
<h3>js表达式</h3>
<p>表达式是由变量、常量、运算符、函数,并返回一个值</p>
<p>{{num*num}}、{{true?"yes":"no"}}</p>
<h3>沙盒模式</h3>
<p>{{Date()}}</p>
<p>{{school}}</p>
</div>
<div id="app1">
<h3>在v-开头的都是指令,指令通常需要一个js表达式</h3>
<p v-if="send">看的到的</p>
<p v-else>看不到的</p>
<h3>指令参数</h3>
<button type="button" v-on:click="show">点击</button>
<h3>缩写</h3>
<p>v-bind缩写 :属性名</p>
<ul>
<li v-for="i in 10" :id="'list'+i">{{i}}</li>
</ul>
<p>v-on缩写 @属性名</p>
<button type="button" @click="show1">点击</button>
</div>
</body>
<script>
var school="智学无忧";//报错全局变量不是沙盒中的
var vm=new Vue({
el:"#app",
data:{
mustache:"文本插入",
htmls:"<strong>原始html</strong>",
no:false,
num:10,
school,//不加报错
}
})
var app=new Vue({
el:"#app1",
data:{
send:true,
},
methods:{
show(){
alert("click也是指令参数");
},
show1(){
alert("v-on缩写")
}
}
})
</script>
②计算属性和侦听器
计算属性:带有一点逻辑的属性,在使用是可以当做data属性一样使用,定义在computed上。
侦听器:使用watch监听到某个属性的变化,watch属性要和data属性名称一样,watch属性传递两个参数newValue和oldValue。
<div id="app">
<p>原始内容{{mag}}</p>
<p>计算后内容:{{reversemag}}</p>
<p>方法计算:{{reversemags1()}}</p>
<p> <input type="text" v-model="fristname"/>+<input v-model="lastname"/>={{fullName}}</p>
<input type="text" v-model="fullName"/>
<!-- 侦听 -->
<h3>侦听器</h3>
<input type="text" v-model="msg"/>
</div>
<div id="watch-example">
<p>
Ask a yes/no question:
<input v-model="question">
</p>
<p>{{ answer }}</p>
</div>
<script>
var app=new Vue({
el:"#app",
data:{
mag:"hello vue",
fristname:"",
lastname:"",
msg:"",
arr:[
{1:"a"},
{2:"b"},
{3:"c"},
{4:"d"}
]
},
computed:{
//计算属性的getter
reversemag:function(){
//this指向app实例
return this.mag.split("").reverse().join("");
},
fullName:{
get(){
return this.fristname+" "+this.lastname;
},
set(newv){
var names=newv.split(" ");
this.fristname=names[0];
this.lastname=names[names.length-1];
return this.fristname+" "+this.lastname
}
}
},
methods:{
//计算属性有缓冲作用,依赖的变量没有变化不在重新计算
//方法没有缓冲作用,每次调用都会执行
reversemags1(){
return this.mag.split("").reverse().join("");
}
},
watch:{
//侦听属性msg的变化
msg:function(newv,oldv){
console.log(newv,oldv);
}
}
})
</script>
<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
<script>
var watchExampleVM = new Vue({
el: '#watch-example',
data: {
question: '',
answer: 'I cannot give you an answer until you ask a question!'
},
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
},
created: function () {
// `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
// 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
// AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
// `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
// 请参考:https://lodash.com/docs#debounce
this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
},
methods: {
getAnswer: function () {
if (this.question.indexOf('?') === -1) {
this.answer = 'Questions usually contain a question mark. ;-)'
return
}
this.answer = 'Thinking...'
var vm = this
axios.get('https://yesno.wtf/api')
.then(function (response) {
vm.answer = _.capitalize(response.data.answer)
})
.catch(function (error) {
vm.answer = 'Error! Could not reach the API. ' + error
})
}
}
})
</script>
③条件渲染
与js中的if结构和if-else结构类似的。
在<template>元素上使用v-if条件,template标签不会渲染 只是一个将包裹的元素作为一个整体。
v-show:只是控制css的display值,添加内样式。 v-show的元素始终会被渲染并保留在dom中,只是简单的的切换css的display。 v-show不支持template元素,也不支持v-else。
v-show和v-if的比较:v-if是“真正”的条件渲染。v-show元素总是会被渲染,并且只是简单的css切换。v-if有更高的切换开销,而v-show有更高的初始渲染开销。
使用场景:需要非常频繁地切换使用v-show比较好,如果在运行时条件很少改变,则使用v-if较好。
<div id="app">
<h3>v-if</h3>
<template v-if="show">
<h3>template标签不会渲染 只是一个将包裹的元素作为一个整体</h3>
<span>v-if判断</span>
</template>
<template v-else-if="show1">
<span>v-else-if</span>
<p>v-else-if判断</p>
</template>
<template v-else>
<span>v-else判断</span>
</template>
<div v-show="show">
<span>v-show显示
<!-- 只是控制css的display值,添加内样式
v-show的元素始终会被渲染并保留在dom中,只是简单的的切换css的display
v-show不支持template元素,也不支持v-else -->
</div>
<!-- v-if vs v-show
v-if是“真正”的条件渲染。v-show元素总是会被渲染,并且只是简单的css切换
v-if有更高的切换开销,而v-show有更高的初始渲染开销
使用场景:需要非常频繁地切换使用v-show比较好,如果在运行时条件很少改变,则使用v-if较好 -->
<div>
<template v-if="dis">
<label>手机号:</label><input type="text" placeholder="输入手机号" key="da"/>
</template>
<template v-else>
<label>email:</label><input type="text" placeholder="输入email" key="em"/>
</template>
</div>
<button type="button" @click="dis=dis==false?true:false">切换</button>
</div>
<script>
var vm=new Vue({
el:"#app",
data:{
show:true,
show1:false,
dis:false,
}
})
</script>
④列表渲染
与js中的for循环类似。在与v-if处于同一节点时,v-for的优先级比v-if高,可以理解为for循环嵌套if结构。
<div id="app">
<!-- 数组的遍历 -->
<ul>
<li v-for="(itme,index) in arr">{{itme.name}}, 下标:{{index}}</li>
</ul>
<!-- 对象遍历 -->
<ul>
<li v-for="(value,keys,index) in school":key="keys">下标:{{index}} 属性名:{{keys}} 属性值:{{value}}</li>
</ul>
</div>
</body>
<script>
var vm=new Vue({
el:"#app",
data:{
arr:[{name:"张三",age:10},{name:"jack",age:20},{name:"rose",age:18}] ,
school:{
name:"张三",
age:20,
sex:"男"
}
}
})
</script>
⑤数据变化的检测与跟踪
<div id="app">
<table border="1" cellpading="0" cellspacing="0" width="50%">
<thead>
<tr>
<th>#</th>
<th>姓名</th>
<th>年龄</th>
<th>操作</th>
</tr>
</thead>
<tbody style="text-align: center">
<tr v-for="(itme,index) in (isf?schoolfil:school)">
<td>{{index}}</td>
<td>{{itme.name}}</td>
<td>{{itme.age}}</td>
<td><button type="button" @click="schoolRemove(index)">删除</button></td>
</tr>
</tbody>
</table>
<label>姓名:</label><input type="text" v-model="names"/>
<label>年龄:</label><input type="text" v-model="ages"/>
<button type="button" @click="schoolPush">在末尾追加</button>
<button type="button" @click="schoolUnshift">在第一个添加</button>
<button type="button" @click="schoolPop">删除末尾</button>
<button type="button" @click="schoolReverse">反转</button></br>
<button type="button" @click="schoolSortS">升序</button>
<button type="button" @click="schoolSortJ">降序</button>
<label>搜索</label><input type="text" v-model="studentName"/>
<div>
<h3>弥补数组缺陷</h3>
<!-- 缺陷
1.利用索引直接设置一个项时vm.itmes[indexOfItem]=newValue
2.修改数组的长度时vm.items.length=newlength
-->
<ul>
<li v-for="items in arr">{{items}}</li>
</ul>
<h3>弥补对象的缺陷</h3>
<p>name:{{obj.name}} age:{{obj.age}} sex:{{obj.sex}}</p>
<p>地址:{{obj.arrt}} 班级:{{obj.sce}}</p>
</div>
</div>
</body>
<script>
var vm=new Vue({
el:"#app",
data:{
school:[{ name:"小莉",age:20,},{name:"张三",age:30},{name:"rose",age:22},{name:"jack",age:18}],
names:"",
ages:18,
studentName:"",
schoolfil:[],
isf:false,
arr:[1,2,3,4,5],
obj:{
name:"xiao",
age:10,
}
},
watch:{
studentName(m,n){
if (m.trim()==""||m.trim()==null) {
this.isf=false;
}else{
this.find();
this.isf=true;
}
}
},
methods:{
//删除
schoolRemove(index){
this.school.splice(index,1);
},
//在末尾追加
schoolPush(){
this.school.push({"name":this.names,"age":this.ages});
},
//在第一个添加
schoolUnshift(){
this.school.unshift({"name":this.names,"age":this.ages});
},
//删除末尾
schoolPop(){
this.school.pop();
},
//反转
schoolReverse(){
this.school.reverse();
},
//升序
schoolSortS(){
this.school.sort(function(a,b){
//返回值>0 a插入到b后面
//返回值=0 a和b位置不变
//返回值<0 b插入到a后面
return a.age-b.age;
})
},
//降序
schoolSortJ(){
this.school.sort(function(a,b){
//返回值>0 a插入到b后面
//返回值=0 a和b位置不变
//返回值<0 b插入到a后面
return -(a.age-b.age);
})
},
find(){
//数组过滤器
this.schoolfil=this.school.filter(function(a,b,c){
return a.name.indexOf(vm.studentName)!=-1;
})
}
}
})
//vm.$forceUpdate()重新渲染数据
//数组缺陷的弥补 对象也一样
//1.使用vue提供的方法
Vue.set(vm.arr,0,10)
//2.vm.$set是全局方法Vue.set的别名
vm.$set(vm.arr,1,100)
//3.使用原生的方法
vm.arr.splice(4,1,9)
//vm.items.splice(nrelength)
//对象
//修改
Vue.set(vm.obj,"name","dasdas")
//添加
vm.$set(vm.obj,"sex","女")
//Vue.set(vm.obj,"sex","男")
//一次添加多个属性
vm.obj=Object.assign({},vm.obj,{"sex":"男","arrt":"深圳市","sce":10})
</script>
⑥事件处理
v-on指令:监听DOM事件,并在触发时运行一些js代码。事件处理方法,方法定义在methods属性上。
<div id="app">
<h3>v-on指令:监听DOM事件,并在触发时运行一些js代码</h3>
<button type="button" @click="show1($event)"/>v-on</bUtton>
<div>
<div @click="show1">
<h3>.stop阻止事件冒泡</h3>
<!-- <button type="button" @click="show2">点击</button> -->
<button type="button" @click.stop="show2">点击</button>
</div>
</div>
<h3>按键修饰符</h3>
<label>enter键</label><input type="text" @keyup.enter="enter1" placeholder="按enter键提交"/>
<label>tab键</label><input type="text" @keyup.tab="tab1" placeholder="按tab键触发"/>
<label>delete键</label><input type="text" @keyup.delete="delete1" placeholder="按delete键触发"/>
<label>esc键</label><input type="text" @keyup.esc="esc1" placeholder="按esc键触发"/>
<div>
<h3>组合按键修饰符</h3>
<label>同时按alt键和C键触发</label><input type="text" @keyup.alt.67="alt_C" placeholder="同时按alt键和C键触发"/>
</div>
<div>
<h3>鼠标按钮修饰符</h3>
<button type="button" @click.left="left1" @click.right="right1($event)" @click.middle="middle1">鼠标按钮</button>
</div>
</div>
</body>
<script>
var vm=new Vue({
el:"#app",
data:{
},
methods:{
//$event传递原始的DOM事件
show1(ev){
console.log(ev)
alert("v-on指令");
},
show2(){
alert(".stop阻止冒泡事件");
},
enter1(){
alert("按enter键触发事件")
},
tab1(){
alert("按tab键触发")
},
delete1(){
alert("按delete键触发")
},
esc1(){
alert("按esc键触发")
},
//space键的触发是 .space
//up键的触发是 .up
//down键的触发是 .down
//left键的触发是 .left
//right键的触发是 .right
alt_C(){
alert("组合按键")
},
left1(){
alert("鼠标左键")
},
right1(ev){
ev.preventDefault();
alert("鼠标右键");
},
middle1(){
alert("鼠标中键")
}
}
})
</script>
⑦表单输入绑定
v-model指令:双向绑定数据,作用在input、textarea、select标签上,默认值来自data的初始化数据。
<div id="app">
<h3>复选</h3>
<input type="checkbox" v-model="chk" value="复选1"/>复选1
<input type="checkbox" v-model="chk" value="复选2"/>复选2
<input type="checkbox" v-model="chk" value="复选3"/>复选3
<input type="checkbox" v-model="chk" value="复选4"/>复选4</br>
<label>你的选择是:</label>{{chk}}
<h3>单选</h3>
<input type="radio" v-model="rad" value="男"/>男
<input type="radio" v-model="rad" value="女"/>女
{{rad}}
<h3>选择框</h3>
<select v-model="sel">
<option value="选择1">选择1</option>
<option value="选择2">选择2</option>
<option value="选择3">选择3</option>
<option value="选择4">选择4</option>
</select>
{{sel}}
<h3>修饰符</h3>
<h4>.lazy input事件改成change事件</h4>
<input v-model.lazy="laz"/>{{laz}}
<h4>number输入值转为数值类型</h4>
<input type="number" v-model.number="age"/>{{age}}
<h4>.trim去首尾空格</h4>
<input v-model.trim="tri"/>{{tri}}
</br>{{tri.length}}
</div>
</body>
<script>
var vm=new Vue({
el:"#app",
data:{
chk:["复选1"],
rad:"男",
sel:"选择1",
laz:"",//懒加载
age:0,
tri:"",
},
})
</script>
⑧Class与Style绑定
<div id="app">
<h3>绑定class</h3>
<h4>对象</h4>
<p :class="{red:isRad,'font-size':isSiza}">对象的绑定</p>
<p :class="objclass">对象定义在data上</p>
<h3>绑定数组</h3>
<h4>单个原始数组</h4>
<p :class="[arrred,arrsize]">单个原始数组</p>
<h4>对象数组</h4>
<p :class="[{red:isRad},{'font-size':isSiza}]">对象数组</p>
<h3>绑定内联样式</h3>
<h4>对象</h4>
<P :style="{color:objco,fontSize:objsz+'px'}">对象语法</P>
<h4>数组</h4>
<p :style="[arr1,arr2]">数组语法</p>
</div>
<script>
var vm=new Vue({
el:"#app",
data:{
isRad:true,
isSiza:true,
objclass:{
//这里isRad都是调用的初始化值false
red:this.isRad,'font-size':this.isSiza
},
//也可以定义在计算属性,方法上 只要返回值是对象的都可以
//绑定数组
arrred:"red",
arrsize:"font-size",
objco:"red",
objsz:30,
arr1:{
color:"red"
},
arr2:{
fontSize:30+'px'
}
}
})
</script>