Vue.js自定义指令
1.自定义全局指令
在Vue.js处理默认设置的核心指令(v-model和v-show),Vue也允许注册自定义指令。如下实例,注册一个全局指令v-focus,功能为在页面加载时,元素获得焦点。
<div id="app">
<input v-focus>
</div>
<srcipt>
Vue.directive("focus",{
inserted:fuction(el){
el.focus()
}
})
new Vue({
el:"#app"
})
</srcipt>
2.自定义局部指令
<div id="app">
<input v-fouces>
</div>
<script>
new Vue({
el:"#app",
directives:{
focues:{
inserted:function(el){
el.fouces()
}
}
}
})
</script>
#3.钩子函数参数
钩子函数的参数有:
el:指令所绑定的元素,可以直接操作DOM。
binding:一个对象,包含以下属性:
value:指令绑定的值,例如:v-my-directive=“1+1”,value的值是2
oldValue:指令绑定的前一个值,仅在updata和componentUpdated钩子中可用。无论值是否改变都可用。
arg:传给指令的参数。例如v-my-directive:foo,arg的值是"foo"。
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar,修饰符对象modifiers的值是{foo:true,bar:true}。
vnode:Vue编译生成的虚拟节点。
<div id="app" v-run:hello.a.b="message"></div>
<script>
Vue.directive("run",{
bind:function(el,bingding,vnode){
var s=JSON.stringify
el.innerHTML="name:"+s(binding.name)+"<br>"+
"value"+s(binding.value)+"<br>"+
"expression"+s(binding.expression)+"<br>"+
"argument"+s(binding.arg)+"<br>"+
"modifiers"+s(binding.modifiers)+"<br>"+
"vnode keys"+Object.keys(vnodes).join(",")
}
})
new Vue({
el:"#app",
data:{
message:"hello world"
}
})
</script>
4.简写钩子函数
如果不要其他钩子函数,可用简写函数,如下格式
Vue.directive("run",function(el,binding){
el.style.backgroundColor=binding.value.color
})
5.指令函数接受JavaScript表达式
<div id="app">
<div v-run="{color:'green',text:'hello'}"></div>
</div>
<script>
Vue.directive("run",function(el,binding){
el.innerHTML=binding.value.text
el.style.backgroundColor=binding.value.color
})
new Vue({
el:"#app"
})
</script>
#Vue.js路由
Vue.js路由允许我们通过不同的URL访问不同的内容。通过Vue.js可用实现多试图的单页Web应用。Vue.js路由需要载入vue-router库。
1.简单实例
是一个组件,该组件用于设置一个导航链接,切换不同的HTML内容。to属性为目标地址,即要显示的内容。
<div id="app">
<p>
<!--使用router-link组件来导航-->
<!--通过传入to属性指定链接-->
<!--<router-link>默认会被渲染成一个<a>标签-->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/Bar">Go to Bar</router-link>
</p>
<!--路由出口-->
<!--路由匹配到的组件将渲染在这里-->
<router-view></router-view>
</div>
<script>
//如果使用模块化机制编程,导入Vue和VueRouter,要调用Vue.use(VueRouter)
//定义组件
//可以从其他文件import进来
const Foo={template:"<div>foo</div>"}
const Bar={template:"<div>bar</div>"}
//定义路由
//每个路由应该映射一个组件。其中"component"可以是
//通过Vue.extend()创建的组件构造器,
//或者,只是一个组件配置对象
const routes=[
{path:"/foo",component:Foo},
{path:"/bar",component:Bar}
]
//创建router实例,然后传routes配置
const router=new VueRouter({
routes
})
//创建和挂载根实例
//记得要通过router配置参数注入路由
//从而让整个应用都有路由功能
const app= new Vue({
router
}).$mount("#app")
</script>
2.router-link相关属性
<!--字符串-->
<router-link to="home">Home</router-link>
<!--渲染结果-->
<a href="home">Home</a>
<!--使用v-bind的JS表达式-->
<router-link v-bind:to"'home'">Home</router-link>
<!--不屑v-bind也可以,就像绑定别的属性一样-->
<router-link:to="'home'">Home</router-link>
<!--同上-->
<router-link:to="{path:'home'}">Home</router-link>
<!--命名的路由-->
<router-link:to="{name:'user',params:{userId:123}}">User</router-link>
<!--带查询参数,下面的结果为/register?plan=private-->
<router-link:to="{path:'register',query:{plan:'private'}}">Register</router-link>
replace:设置replace属性的话,当点击时,会调用router.replace()而不是router.push(),导航后不会留下history记录。
<router-link:to="{path:'/abc'}" replace></router-link>
append:设置append属性后,则在当前(相对)路径前添加基路径。例如,我们从/a导航到一个相对路径b,如果没有配置append,则路径为/b,如果配了,则为/a/b
<router-link:to="{path:'relative/path'}">append</router-link>
tag:有时候想要<router-link>渲染成某种标签,例如<li>可以用tag prop类指定某种标签,同样还是会监听点击,触发导航。
<router-link to="/foo" tag="li">foo</router-link>
<!--渲染结果-->
<li>foo</li>
active-class:设置链接激活时使用css类名。
<style>
._active{
background-color:red;
}
</style>
<p>
<router-link v-bind:to="{path:'/route1'}" active-class="_active">Router Link1</router-link>
<router-link v-bind:to="{path:'/route2'}" tag="span">Router Link2</router-link>
</p>
注意:这里class使用active_class="_active"。
exact-active-class:配置当链接被精确匹配的时候应该激活class。可以通过以下代码来替代。
<p>
<router-link v-bind:to = "{ path: '/route1'}" exact-active-class = "_active">Router Link 1</router-link>
<router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
</p>
event:声明可以用来触发导航事件。可以时一个字符串或是一个包含字符串的数组。
<router-link v-bind:to="{path:'/route1'}" event="mouseover">Rounter Link1</router-link>
以上代码设置了 event 为 mouseover ,及在鼠标移动到 Router Link 1 上时导航的 HTML 内容会发生改变。
Vue.js过渡&动画
过渡:Vue在插入、更新或者移除DOM时,提供多种不同方式的应用过渡效果。Vue提供了内置的过渡封装组件,该组件用于包裹要实现过渡效果的组件。
语法格式:<transition name="nameoftransition">
<div></div>
</transition>
1.实例
<style>
/* 可以设置不同的进入和离开动画 */
/* 设置持续时间和动画函数 */
.fade-enter-active, .fade-leave-active {
transition: opacity 2s
}
.fade-enter, .fade-leave-to /* .fade-leave-active, 2.1.8 版本以下 */ {
opacity: 0
}
</style>
<div id="app">
<button v-on:click="show!=show">点我</button>
<transition name="fade">
<p v-show="show" v-bind:style="styleobj">动画</p>
</transition>
</div>
<script>
new Vue({
el:"#app",
data:{
show:true,
styleobj:{
fontSize:"30px",
color:"red"
}
},
methods:{
}
})
</script>
通过点击 “点我” 按钮将变量 show 的值从 true 变为 false。如果为 true 显示子元素 p 标签的内容。
过渡其实就是一个淡入淡出的效果。Vue在元素显示与隐藏的过渡中,提供了6个Class来切换:
v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
v-enter-to:2.1.8版及以上定义过渡的结束状态。在元素被插入之后下一帧生效(与此同时v-enter被移除),在过渡/动画完成之后移除。
v-leave-active:定义离开过渡生效时的状态。在整个离开过渡阶段中应用,在离开过渡触发时立刻生效。在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
对于这些在过渡中切换的类名来说,如果你使用一个没有名字的,则v-是这些类名的默认前缀。如果你使用了,那么v-enter会替换为my-transition-enter。
v-enter-active和v-leave-active可以控制进入/离开过渡的不同的缓和曲线。
2.css过渡
<style>
.slide-fade-enter-active{
transition:all .3s ease;
}
.slide-fade-leave-active{
transition:all .8s cubic-bezier(1.0,0.5,0.8,1.0);
}
.slide-fade-enter,.slide-fade-leave-to{
transform:translateX(10px);
opacity:0
}
</style>
<div id="app">
<button v-on:click="show=!show">点我</button>
<transition name="slide-fade">
<p v-if="show">hello</p>
</transition>
</div>
<script>
new Vue({
el:"#app",
data:{
show:true
}
})
</script>
3.css动画
<style>
.bounce-enter-active {
animation: bounce-in .5s;
}
.bounce-leave-active {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
</style>
<div id = "databinding">
<button v-on:click = "show = !show">点我</button>
<transition name="bounce">
<p v-if="show">hello</p>
</transition>
</div>
<script type = "text/javascript">
new Vue({
el: '#databinding',
data: {
show: true
}
})
</script>
4.自定义过渡的类名
enter-class
enter-active-class
enter-to-class()
leave-class
leave-active-class
leave-to-class
自定义过渡的类名优先级高于普通的类名
<div id="app">
<button v-on:click="show=!show">点我</button>
<transition name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
></transition>
<p v-if="show">hello</p>
</div>
<script>
new Vue({
el:"#app",
data:{
show:true
}
})
</script>
5.同时使用过渡和动画
Vue为了知道过渡的完成,必须设置相应的事件监听器。它可以时transitionend或者transitionend,这取决于给元素应用的CSS规则。如果你使用其中任何一种,Vue能自动识别类型并设置监听。但是在一些场景中,需要给同一个元素同时设置两种过渡动效,比如,animation很快的被触发并完成了,而transition效果还没有结束。在这种情况下需要使用type特性并设置animation或transioton来明确你需要Vue监听的类型。
6.显性的过渡持续时间
在很多情况下,Vue可以自动得出过渡效果的完成时机。默认情况下,Vue会等待其在过渡效果的根元素的第一个transitionend或animationend事件。然而也可以不这样设定。可以使用一些嵌套的内部元素相比于过渡效果的根元素有延迟的或更长的过渡效果。可以使用组件上的duration属性定制一个显性的过渡持续时间。
<transition :duration="1000"></transition>
定制进入和移除的持续时间。
<transition:duration="{enter:500,leave:800}"></transition>
Vue.js混入
混入定义了一部分可复用的方法或者计算属性。混入对象可以包含任意组件选项。当组件使用混入时,所有混入对象的选项将被混入该组件本身的选项。
<div id="app"></div>
<script>
new Vue({
el:"#app",
data:{},
methods:{}
});
//定义一个混入对象
var myMixin={
created:function(){
this.startmixin()
},
methods:{
startmixin:function(){
document.write("hello")
}
}
};
var Component=Vue.extend({
mixins:[myMixin]
})
var component=new Component();
</script>
#2.选项合并
当组件和混入对象含有同名选项时,这些选项将以恰当的方式混合。数据对象在内部会进行浅合并,在和组件的数据发生冲突时以组件数据优先。
<div id="app"></div>
<script>
var mixin={
created:function(){
document.write("hello")
}
}
new Vue({
mixins:[mixin],
document.write("hi")
})
</script>
3.实例优先级
如果methods选项中有相同的函数名,则Vue实例优先级高。
<div id="app"></div>
<script>
var mixin={
methods:{
helloworld:function(){
document.write("hello")
},
samemethod:function(){
document.write("Mixsame")
}
}
};
var vm=new Vue({
mixins:[mixin],
methods:{
start:function(){
document.write("start");
},
samemethod:function(){
document.write("mainsame")
}
}
});
vm.helloworld();
vm.start();
vm.samemethod();
</script>
methods选项中如果碰到相同的函数名则Vue实例有更高的优先级会执行输出。
#4.全局混入
可以全局注册混入对象。一旦使用全局混入对象,会影响到所有之后创建的Vue实例。使用恰当时,可以为自定义对象注入处理逻辑。
<script>
Vue.mixin({
created:function(){
var myOption=this.$.options.myOption
if(myOption){
document.write(myOption)
}
}
})
new Vue({
myOption:"hello"
})
</script>
全局混入对象要谨慎使用,因为会影响到每个单独创建的Vue实例。
Vue.js中的Ajax(axios)
1.GET方法
<div id="app">
{{info}}
</div>
<script>
new Vue({
el:"#app",
data(){
return{
info:null
}
},
mouted(){
axios
.get("json/a.json")
.then(response=>(this.info=response))
.catch(function(error){ //请求失败处理
console.log(error);
});
}
})
</script>
2.response.data读取数据
<div id="app">
<div v-for="site in info">
{{site.name}}
</div>
</div>
<script>
new Vue({
el:"#app",
data:(){
return{
info:null
}
},
mounted(){
axios
.get("json/a.json")
.then(response=>(this.info=response.data.male))
.catch(function(error){
console.log(error);
})
}
})
</script>
3.GET方法传递参数
/直接在URL上添加参数
axios.get("/user?ID=123456")
.then(function(response){
console.log(response);
}).catch(function(error){
console.log(error);
})
//也可以通过params设置参数
axios.get("/user",{
params:{
ID:12345
}
}).then(function(response){
console.log(response);
}).catch(function(error){
console.log(error);
})
4.POST方法
<div id="app">
<div v-for="site in info">
{{site.name}}
</div>
</div>
<script>
new Vue({
el:"#app",
data:(){
return{
info:null
}
},
mounted(){
axios
.post("json/a.json")
.then(response=>(this.info=response.data.male))
.catch(function(error){
console.log(error);
})
}
})
</script>
5.POST方法传递参数格式
axios.post("/user",{
firstName:"fred",
lastName:"filntstone"
})
.then(function(response){
console.log(response);
})
.catch(function(error){
console.log(error);
})
6.执行多个并发请求
function getUserAccount(){
return axios.get("/user/12345");
}
function getUserPermissions(){
return axios.get("/user/12345/permisssion");
}
axios.all([getUserAccount(),getUserPermission()])
.then(axios.sperd(function(acct,perms)));
axios API
1.实例
可以通过axios传递相关配置来创建请求
axios(config)
//发送post请求
axios({
method:"post",
//路径
url:"/user/12345"
//数据
data:{
firstName:"fred"
}
});
//GET请求远程图片
axios({
method:"get",
url:"xxxxx",
responseType:"stream"
})
.then(function(response){
response.data.pipe(fs.createWriteStream("xxx.jpg"))
});
axios(url[,config])
axios("/user/12345")
2.请求方法的别名
Vue.js为所有支持的请求方法提供了别名,可以直接使用别名来发起请求。
axios.request(config)
axios.get(url[,config])
axios.delete(url[,config])
axios.head(url[,config])
axios.post(url[,data[,config]])
axios.put(url[,data[,config]])
axios.patch(url[,data[,config]])
注意:在使用别名方法时,url、method、data这些属性都不必在配置中指定。
3.并发
处理并发请求的助手函数:axios.all(interable)axios.spread(callback)
4.创建实例
可以使用自定义配置新建axios实例
axios.create([config])
const instance=axios.create({
baseURL:“xxxxx”,
timeout:1000,
headers:{“X-Custom-Heander”:“foobar”}
})
5.实例方法
axios#request(config)
axios#get(url[,config])
axios#delete(url[,config])
axios#head(url[,config])
axios#put(url[,data[,config]])
axios#patch(url[,data[,config]])
以下创建请求时可用的配置选项,只有URL是必须的。如果没有指定method,请求默认使用get方法。
auth:{
onDownloadProgress: function (progressEvent) {
// 这将会设置一个Proxy-Authorization头,覆写掉已有的通过使用 header设置的自定义Proxy-Authorization头。
6.响应结构
axios请求的响应包含信息
{
//data由服务器提供的响应
data:{},
//status、Http状态码
status:200,
//statusText来自服务器响应的Http状态信息
statusText:"ok",
//headers服务器响应的头
headers:{},
//config是为请求提供的配置信息
config:{}
}
使用then时,会接收下面这样的响应
axios.get("/user/12345")
.then(function(response){
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
})
在使用catch时,或传递rejection callback作为then的第二个参数时,响应可以通过error对象可被使用。
7.配置的默认值
可以指定将被用在各个请求的默认值。
全局的axios默认值。
axios.defaults.baseURL="";
axios.defaults.headers.common[‘Authorization’]=AUTH_TOKEN;
axios.defaults.headers.post[‘Content-Type’]=“application/x-www-form-urlencoded”;
自定义实例默认值:
//创建实例时设置配置的默认值
var instance=axios.create({
var instance = axios.create({
baseURL: ‘https://api.example.com’
});
// 在实例已创建后修改默认值
instance.defaults.headers.common[‘Authorization’] = AUTH_TOKEN;
})
8.配置的优先顺序
配置会以一个优先顺序进行合并。这个顺序是:在lib/defaults.js找到的库的默认值,然后是实例的defaults属性,最后是请求的config参数。后者优于前者。
//使用由库提供的配置的默认值来创建实例
//此时超时配置的默认值为0
var instance=axios.create();
//覆写库的超时默认值
//在超时前,所有请求都会等待2.5秒
instance.defaults.timeout=2500;
//为已知需要花费很长时间的请求覆写超时设置
instance.get("/longRequest",{
timeout:5000
})
9.拦截器
在请求或响应then或catch处理前拦截
axios.interceptors.request.use(function(config){
//在发送请求之前做些什么
return config;},funcrtion(errot){
//对请求错误做些什么
return Promise.reject(error);
});
//添加响应拦截器
axios.interceptors.response.use(response){
//对响应数据做什么
return response;
},function(error){
//对响应错误做点什么
return Promise.reject(error);
});
如果想在稍后移除拦截器
var myInterceptor=axios.interceptors.request.use(function(){/*...*/});
axios.interceptors.request.eject(myInterceptor);
错误处理:
axios.get("/user/12345")
.catch(function(error){
if(error.response){
//请求已发出,但服务器响应的状态码不在2xx范围内
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
}else{
console.log("error",error.message);
}console.log(error,config);
})
可以使用validateStatus配置选项定义一个自定义HTTP状态码的错误范围。
axios.get("/user/12345",{
validateStatus:function(status){
return status<500; //状态码在大于或等于500时才会reject
}
})
10.取消
使用cancel token取消请求。
Axios的cancel token API 基于cancelable promises proposal
可以使用CancelToken.source工厂方法创建cancel token
var CancelToken =axios.CancelToken;
var source=CancelToken.source();
axios.get("/user/12345",{
cancelToken:source.token
}).catch(function(thrown){
if(axios.isCancel(thrown)){
console.log("requesr canceled",thrown.message);
}else{
//处理错误
}
});
//取消请求(message参数是可选的)
source.cancel("Operation canceled by the user")
还可以通过传递一个executor函数到CancelToken的构造函数来创建cancel token;
var CancelToken=axios.CancelToken;
var cancel;
axios.get("/user/12345",{
cancelToken:new CancelToken(function executor(c){
//executor函数接受一个cancel函数作为参数
cancel=c;
})
});
//取消请求
cancel();
注意:可以使用同一个cancel token取消多个请求
Vue.js响应接口
Vue可以添加数据动态响应接口。
<div id = "app">
<p style = "font-size:25px;">计数器: {{ counter }}</p>
<button @click = "counter++" style = "font-size:25px;">点我</button>
</div>
<sctipt>
var vm = new Vue({
el: '#app',
data: {
counter: 1
}
});
vm.$watch('counter', function(nval, oval) {
alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
});
setTimeout(
function(){
vm.counter += 20;
},10000
);
</sctipt>
Vue不允许在已经创建的实例上动态添加新的根级响应式属性。Vue不能检测到对象属性的添加或删除,最好的方式就是初始化实例前声明根级响应式属性,可以为空值。如果需要在运行过程中实现属性的添加或删除,则可以使用全局Vue,Vue.set和Vue.delete方法。
1.Vue.set
Vue.set方法用于设置对象的属性。可以解决Vue无法检测添加属性的限制。语法格式为:Vue.set(target,key,value)target:可以是对象或数组key:可以是字符串或数字value:可以是任何类型
2.Vue.delete
Vue.delete用于删除动态添加的属性Vue.delete(target,key)target:可以是对象或者数组key:可以是字符串或数字