认识vue:
Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架。
Vue 只关注视图层, 采用自底向上增量开发的设计。
Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
采用了MVVM的分层开发思想。
使用前需要先进行安装或导包 (可以在CDN下载,或在项目下npm来下载)
基本结构:
<script src="./vue.js"></script> <!-导包-->
//body中的html代码就是MVVM中的V,视图层。
<div id="app">
<p>{{ msg }}</p>
</div>
//2.创建一个vue实例
//当我们导入vue的包时,浏览器中就多了一个Vue构造函数
//new出来的这个vm对象就是MVVM中VM(调度者)
var vm = new Vue({
el: '#app', //el:element,当前new的这个vue实例,会控制这个页面上的区域
//data就是MVVM中的M,专门用来保存每个页面的数据
data:{ //data属性中,要存放 el 需要的数据
msg:'第一个学习vue' //通过Vue提供的指令,很方便的就能把数据渲染到页面上,程序员不在需要手动操作DOM元素,
//vue之类的的框架,不提倡我们去手动操作DOM元素
}
});
常用指令:
- 内容渲染
插值表达式: {{ msg }} 、v-text 、v-html
[v-cloak]{ display:none; } //style中样式的设置
<p v-cloak>{{ msg }}</p>
<p v-text="msg"></p>
<p v-html="msg"></p> //可以用来解析html代码字符
/*
区别:
msg是vm实例中data中封装的数据
当网络请求缓慢时,v-text不会出现闪烁现象,而使用插值表达式时,数据未加载出来前会将 {{msg}} 当做字符来展示。
解决闪烁问题:添加 v-cloak指令,使用后直到编译介绍才会显示内容
*/
- 绑定
属性指令绑定:v-bind:要绑定的属性 (简写 :要绑定的属性 )
事件绑定机制:v-on:要绑定的事件 (简写 @要绑定的事件 )
<input type="button" value="按钮" v-bind:title="mytitle+'123'">
<!-- 注意:v-bind: 中可以写合法的js表达式 -->
<input type="button" value="按钮" :title="mytitle">
<!-- v-on: 事件绑定中,不能够识别出alert()方法,需要在methods中定义 -->
<!--<input type="button" value="事件绑定" :title="mytitle" v-on:click="alert('aa')">-->
<input type="button" value="事件绑定" :title="mytitle" v-on:click="show"> <!--show方法在vm实例中的 methods定义过-->
- 事件修饰符
在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。
同样 v-on 也提供了一下事件修饰符:
<!--使用 .stop 来阻止冒泡,由内向外-->
<div class="inner" @click="div1Handler">
<input type="button" value="点我" @click.stop="btnHandler">
</div>
<!--使用 .prevent 来阻止默认行为-->
<a href="http://wwww.baidu.com" @click.prevent="linkClick">点我去百度</a>
<!--使用 .capture 来实现捕获事件的触发机制 ,由外向内-->
<div class="inner" @click.capture="div2Handler">
<input type="button" value="点我" @click="btn2Handler">
</div>
<br>
<!--使用 .self 实现只触发当前元素的时间,只能够起到对当前元素的作用,不同于.stop-->
<div class="inner" @click.self="div2Handler">
<input type="button" value="点我" @click="btn2Handler">
</div>
<!--使用 .once 只能触发一次事件处理函数-->
<a href="http://wwww.baidu.com" @click.prevent.once="linkClick">点我去百度</a>
/*
.self 和 .stop 的作用类似
但是.self 只能消除自己身上的冒泡行为
.stop 可以正真意义上实现阻止冒泡行为
*/
- 事件双向绑定
v-model
限制:input、textarea、select 等表单控件
修饰符:.lazy 、 .number 、 .trim
v-bind 只能够实现数据的单向绑定
注意:v-model 指令用在 type=“checkbox” 中时,会触发其选中与否的状态,取决于 v-model 的值,非空即真。即为选中。
<input type="text" v-model="msg" style="width: 100%;">
- Class 与 Style 的绑定
<!-- 传统的写法 -->
<h1 class="red thin italic active">我是一个h1标签,很大很大的!</h1>
<!-- vue实现 -->
<!-- 数组语法:需要用属性绑定v-bind,传递一个数组即可
注意:属性不加引号时,会在data里面进行查找
-->
<h1 v-bind:class="['red','thin',flag ? 'active' : '']">我是一个h1标签,很大很大的!</h1>
<!--对象格式-->
<h1 v-bind:class="['red','thin',{'active':flag}]">我是一个h1标签,很大很大的!</h1>
<!--直接使用对象
对象中对象属性可加引号,也可不加引号 属性值是一个标识符
-->
<h1 v-bind:class="{red:true, thin:true, italic:false, active:false}">我是一个h1标签,很大很大的!</h1>
<h1 v-bind:class="classObj">我是一个h1标签,很大很大的!</h1>
<!--style绑定-->
<h1>style绑定</h1>
<!--fontWeight 还可以写成 font-weight -->
<h1 :style="{color:'red',fontWeight:'lighter'}">这是另一个h1!</h1>
<!--将其封装成对象-->
<h1 :style="styleObj1">这是另一个h1!</h1>
<!--数组语法-->
<h1 :style="[styleObj1,styleObj2]">这是另一个h1!</h1>
//vm实例中的data
data: {
flag:true,
classObj:{red:true, thin:true, italic:false, active:false},
styleObj1:{color:'red',fontWeight:'lighter',fontStyle:'italic'},
styleObj2:{fontSize:'20px'},
}
- 循环指令
v-for 、 key关键字
v-for循环的时候,key属性只能用 number/string类型
key在使用的时候,必须使用 v-bind 属性绑定的形式
在组件中使用v-for时,key可以保证数据的唯一性
<!--循环数组-->
<p v-for="(item,index) in list">索引值:{{index}}----对应值:{{item}}----姓名:{{item.name}}</p>
<br>
<!--同理循环对象-->
<!--第三个index可有可无-->
<p v-for="(val,key,index) in people" :key="index">索引:{{index}}----key:{{key}}----val:{{val}}</p>
<!--in后面可以是普通数组、对象、还可以是数字-->
<!--注意:遍历数字时,从1开始-->
<p v-for="count in 5">这是第{{count}}次遍历</p>
- v-if 、v-show
区别:
v-if 的特点:每次都会重新删除或创建元素
v-show的特点:每次不会重新进行DOM元素的删除和创建操作,只是在切换元素的display属性
v-if有较高的切换性能消耗 切换频率频繁是不推荐使用
v-show有较高的初始渲染消耗 元素压根不需要显示时不推荐使用
<h3 v-if="flag">这是一个用v-if控制的元素</h3>
<h3 v-show="flag">这是一个用v-show控制的元素</h3>
- 过滤器(常用来处理文本格式)
使用Vue.filter(“String”,fn);
注意:当同时在全局和局部定义了一个过滤器时,使用时采用就近原则。
//使用过滤器
{{item.ctime | dateFormat() }} //第一个数表示要传递过去处理的字符;第二个表示使用某个过滤器
//定义一个全局过滤器(所有的vm实例都共享)
Vue.filter('dateFormat',function (dateStr,partten='') { //第一个参数:过滤器名称;第二个:处理函数
//根据给定的时间字符串,得到特定的时间
var dt = new Date(dateStr);
// yyyy-mm-dd
var y = dt.getFullYear();
//补全
var m = (dt.getMonth() + 1).toString().padStart(2,'0'); //ES6中的字符串处理方法
var d = (dt.getDate()).toString().padStart(2,'0');
// return y + "-" + m + "-" + d;
//采用ES6中模板字符串
if(partten.toLowerCase() === "yyyy-mm-dd"){
return `${y}-${m}-${d}`;
}
else{
var hh = (dt.getHours()).toString().padStart(2,'0');
var mm = (dt.getMinutes()).toString().padStart(2,'0');
var ss = (dt.getSeconds()).toString().padStart(2,'0');
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
}
});
//私有过滤器
//需要在 Vue 实例中的 filters 中编写
filters: {
dateFormat: function (dateStr,partten='') {
.......................
}
},
- 自定义按键修饰符
Vue.config.keyCodes.f2 = 113; // 通过编码集实现
// 可以使用 `v-on:keyup.f2`
- 自定义指令
使用 Vue.directive(“String”,{}); 定义一个全局指令
第一个参数:指令名称,不要有加 v-,使用时需要加 v-
第二个参数:是一个对象,对象中包含了一些与指令相关的函数
//使用
<input type="text" class="form-control" v-model="keywords" v-focus v-color="'green'">
//传递多个参数
<input type="text" class="form-control" v-model="keywords" v-focus v-color="{color:'red',fontSize:'30px'}">
//重命名
<input type="text" class="form-control" v-model="keywords" v-focus v-color:{a:1,b:2}="{color:'red',fontSize:'30px'}">
//全局的
Vue.directive('color',{
/*
el:指令所绑定的元素,可以用来直接操作 DOM 。
binding:一个对象,包含以下属性:name value
*/
//el参数是指所绑定的参数,就是当前的DOM元素,就是原生的js对象
bind:function (el) { //每当指令绑定到元素上的时候,会立即执行bind函数,只执行一次
//不起作用,只有将其插入到DOM中,才会有作用
el.focus();
},
inserted:function (el) { //当元素插入到DOM中时,会执行inserted函数 (触发一次)
//和js行为有关的操作,最好在inserted中设置,防止js行为失效
el.focus();
},
updated:function () { //当VNode有更新时就会执行,可多次触发
}
bind:function (el,binding) {
//与样式相关的操作,一般都可以在 bind 中执行
// el.style.color = 'red';
// console.log(binding.value);
el.style.color = binding.value;
}
});
//私有指令需要在 Vue 实例下的 directives 中实现
//定义一个私有指令
directives:{
'fontweight':{
bind:function (el,binding) {
// console.log("aa");
el.style.fontWeight = binding.value;
}
},
//简写:function 等同于把代码写到bind和update中去
'fontsize':function (el,binding ) {
el.style.fontSize = parseInt(binding.value) + 'px';
}
}
-
生命周期函数
参考链接 -
过渡类名实现动画
使用动画的元素需要放在 transition 标签下
列表动画需要放在 transition-group 标签下
可以给标签添加 name 属性,改变 v- 为 name属性值-
还可通过自定义过渡类名来实现,使用第三方类库 animate.css
<!--注意:需要执行的动画的元素需要用特定的标签包起来-->
<!--<ul>-->
<!--在实现过渡列表的时候,如果过度的元素是通过 v-for 循环渲染出来的,不能使用transition来包裹,
需要使用 transition-group来包裹-->
<!-- 给 transition-group 添加 appear 属性,实现页面刚展示出来时候,入场时候的效果 -->
<!-- 通过 为 transition-group 元素,设置 tag 属性,指定 transition-group 渲染为指定的元素,如果不指定 tag 属性,默认,渲染为 span 标签 -->
<transition-group appear tag="ul">
<li v-for="(item,index) in list" :key="item.id" @click="del(index)">
{{item.id}}----{{item.name}}
</li>
</transition-group>
<!--</ul>-->
//JavaScript钩子函数实现动画
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
//在Vue实例中的methods下编写钩子函数。
// 注意: 动画钩子函数的第一个参数:el,表示要执行动画的那个DOM元素,是个原生的 JS DOM对象
// 可以看作 el 是通过 document.getElementById('') 方式获取到的原生JS DOM对象
beforeEnter(el){
//该函数表示动画入场前进行
el.style.transform = "translate(0,0)"; //设置动画的起始位置
},
enter(el, done){
//动画进入过程中执行
//如果不写el.offsetWidth,则没有动画效果
el.offsetWidth; //offsetHeight、offsetLeft等均可
...
// 这里的 done,其实就是 afterEnter 这个函数,也就是说:done 是 afterEnter 函数的引用
//调用了done函数后,动画执行完毕后,将立即消失
done();
},
afterEnter(el){
...
}
-
组件
创建:Vue.component(“String”,{组件模板});
注意 :组件名称使用了驼峰命名,则在引用组件的时候,需要把大写的驼峰改为小写的字母,同时两个单词之前,使用 - 链接;如果不使用驼峰,则直接拿名称来使用即可;
Vue中提供了 component 组件,他是一个占位符,通过 :is 属性来指定对应要显示的组件。<component :is="comName"></component>
子组件中的data:
- 组件可以有自己的 data 数据
- 组件的 data 和 实例的 data 不一样,实例中的 data 可以为一个对象,但组件中的 data 必须是一个方法
- 组件中的 data 除了必须为一个方法之外,这个方法内部,还必须返回一个对象才行;
- 组件中 的data 数据,使用方式和实例中的 data 使用方式完全一样
父组件向子组件传值:在使用子组件时,通过 v-bind 属性绑定来获取父组件的数据,注意 :子组件需要在自己组件下的 props 数组(或对象)中定义名称和属性绑定名称一样的值, props 数组是只读的,用来存放父组件传递过来的值。
子组件向父组件传值:在使用子组件时,通过 v-on 事件绑定来获取子组件要传递的数据,注意 :事件绑定的方法是父组件的方法,并含有参数,在子组件中通过 this.$emit(fnName,“要传递的参数”); 来传递参数。
同理,父组件也可以以同样的方式来将方法传递给子组件。子组件在 props 中接受,类型为 Function。
emit 英文原意: 是触发,调用、发射的意思
补充: 可以通过 ref 来获取DOM元素和组件引用;console.log(this.$ref); 查看相关信息。
//全局组件
//第一种方式
//使用Vue.extend()和Vue.component()来创建
var com1 = Vue.extend({
//通过template属性来指定组件要展示的HTML结构
template:"<h3>这是使用Vue.extend()来创建的组件</h3>"
});
//Vue.component("组件名称","要展示的组件模板对象")
Vue.component("myCom1",com1); //驼峰命名
Vue.component("mycom1",com1);
//还可将Vue.extend()和Vue.component()组合到一起
Vue.component("mycom2",Vue.extend({
template:"<h3>这是使用Vue.extend()来创建的组件</h3>"
}));
//第二种方式
Vue.component("mycom3",{
//注意:不论是哪种方式创建出来的组件,组件的 template 属性指向的模板内容,必须有且只能有唯一的一个根元素
// template:"<h3>这是使用了第二种方式创建组件</h3><span>我跟h3平级</span>",
template:"<div><h3>这是使用了第二种方式创建组件</h3><span>我跟h3平级</span></div>"
});
//第三种方式
Vue.component("mycom4",{
template:"#tmp1",
});
//私有组件需要在 Vue 实例下的 components 下定义
components:{
mycom5:{
// template:"<h4>我是h4标签,用私有组件创建而成的</h4>",
template:"#tmp2" //id为 tmp2 的模板已经事先在body中完成
}
}
-
路由
参考链接 -
vue-resource请求
使用前先导入 vue-resource.js 包。
三种请求格式和万能测试地址: https://blog.csdn.net/zlq_CSDN/article/details/89444579 -
methods、watch、computed之间的对比
computed
属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用,可以动态来监听数据的变化;methods
方法表示一个具体的操作,主要书写业务逻辑;watch
一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computed
和methods
的结合体;