标签 Vuejs 下的文章

watch

使用这个 属性,可以监视 data 中指定数据的变化以及路由等的变化,然后触发这个 watch 中对应的 function 处理函数。而且可以获取改变后和改变之前的值

watch: { 
        'firstname': function (newVal, oldVal) {
        
          this.fullname = newVal + '-' + this.lastname
        },
        'lastname': function (newVal) {
          this.fullname = this.firstname + '-' + newVal
        }
      }

computed

在 computed 中,可以定义一些 属性,这些属性,叫做 【计算属性】, 计算属性的,本质,就是 一个方法,只不过,我们在使用 这些计算属性的时候,是把 它们的 名称,直接当作 属性来使用的;并不会把 计算属性,当作方法去调用;

注意:

  • 计算属性,在引用的时候,一定不要加 () 去调用,直接把它 当作 普通 属性去使用就好了;
  • 只要 计算属性,这个 function 内部,所用到的 任何 data 中的数据发送了变化,就会 立即重新计算 这个 计算属性的值
  • 计算属性的求值结果,会被缓存起来,方便下次直接使用; 如果 计算属性方法中,所以来的任何数据,都没有发生过变化,则,不会重新对 计算属性求值。

    computed: { 
          'fullname': function () {
            console.log('ok')
            return this.firstname + '-' + this.middlename + '-' + this.lastname
          }
        }

watch、computed和methods之间的对比

  1. computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;
  2. methods方法表示一个具体的操作,主要书写业务逻辑;
  3. watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computed和methods的结合体;

路由概念

  1. 对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源;
  2. 对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现;
  3. 在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由。

vue 中使用 vue-router

  1. 导入 vue-router 组件类库:
    <script src="./lib/vue-router-2.7.0.js"></script>
  2. 使用 router-link 组件来导航
    router-link 默认渲染为一个a 标签,可以通tag属性来指定渲染的标签。

    <router-link to="/login" tag="span">登录</router-link>
    <router-link to="/register">注册</router-link>
  3. 使用 router-view 组件来显示匹配到的组件
    vue-router 提供的元素,专门用来 当作占位符的,将来,路由规则,匹配到的组件,就会展示到这个 router-view 中去.我们可以把 router-view 认为是一个占位符 .
    <router-view></router-view>
  4. 创建使用Vue.extend创建组件

     // 4.1 使用 Vue.extend 来创建登录组件
    var login = Vue.extend({
      template: '<h1>登录组件</h1>'
    });
    
    // 4.2 使用 Vue.extend 来创建注册组件
    var register = Vue.extend({
      template: '<h1>注册组件</h1>'
    });
  5. 创建一个路由 router 实例,通过 routers 属性来定义路由匹配规则
    创建一个路由对象, 当 导入 vue-router 包之后,在 window 全局对象中,就有了一个 路由的构造函数,叫做 VueRouter,在 new 路由对象的时候,可以为 构造函数,传递一个配置对象,route属性就是配置路由规则的地方,每个路由规则,都是一个对象,这个规则对象,身上,有两个必须的属性:属性1 是 path, 表示监听 哪个路由链接地址;属性2 是 component, 表示,如果 路由是前面匹配到的 path ,则展示 component 属性对应的那个组件, component 的属性值,必须是一个 组件的模板对象, 不能是 组件的引用名称;可以通过redirect指定默认路由

     var router = new VueRouter({
     routes: [
       { path: '/', redirect: '/login' },
       { path: '/login', component: login },
       { path: '/register', component: register }
     ]
     });
  6. 使用 router 属性来使用路由规则'

    var vm = new Vue({
      el: '#app',
      router: router // 使用 router 属性来使用路由规则
    });

路由的传参

方式一:

 <!-- 如果在路由中,使用 查询字符串,给路由传递参数,则 不需要修改 路由规则的 path 属 性 -->
   <router-link to="/login?id=10&name=zs">登录</router-link>
   <router-link to="/register">注册</router-link> 
var login = {
     template: '<h1>登录 --- {{ $route.query.id }} --- {{ $route.query.name }}</h1>',
     data(){
       return {
         msg: '123'
       }
     },
     created(){ // 组件的生命周期钩子函数
       // console.log(this.$route)
       // console.log(this.$route.query.id)
     }
   }

方式2:

 <!-- 如果在路由中,使用 查询字符串,给路由传递参数,则 不需要修改 路由规则的 path 属性 -->
  <router-link to="/login/12/ls">登录</router-link>
  <router-link to="/register">注册</router-link>
 var login = {
     template: '<h1>登录 --- {{ $route.params.id }} --- {{ $route.params.name }}</h1>',
     data(){
       return {
         msg: '123'
       }
     },
     created(){ // 组件的生命周期钩子函数
       console.log(this.$route.params.id)
     }
   }

路由的嵌套

使用 children 属性实现路由嵌套

 <div id="app">
  <router-link to="/account">Account</router-link>

  <router-view></router-view>
</div>

<script>
  // 父路由中的组件
  const account = Vue.extend({
    template: `<div>
      这是account组件
      <router-link to="/account/login">login</router-link> | 
      <router-link to="/account/register">register</router-link>
      <router-view></router-view>
    </div>`
  });

  // 子路由中的 login 组件
  const login = Vue.extend({
    template: '<div>登录组件</div>'
  });

  // 子路由中的 register 组件
  const register = Vue.extend({
    template: '<div>注册组件</div>'
  });

  // 路由实例
  var router = new VueRouter({
    routes: [
      { path: '/', redirect: '/account/login' }, // 使用 redirect 实现路由重定向
      {
        path: '/account',
        component: account,
        children: [ // 通过 children 数组属性,来实现路由的嵌套
          { path: 'login', component: login }, // 注意,子路由的开头位置,不要加 / 路径符
          { path: 'register', component: register }
        ]
      }
    ]
  });

  // 创建 Vue 实例,得到 ViewModel
  var vm = new Vue({
    el: '#app',
    data: {},
    methods: {},
    components: {
      account
    },
    router: router
  });
</script>

注意: 使用 children 属性,实现子路由,同时,子路由的 path 前面,不要带 / ,否则永远以根路径开始请求,这样不方便我们用户去理解URL地址。

命名视图实现经典布局

标签代码结构:

<div id="app">
    <router-view></router-view>
    <div class="content">
      <router-view name="a"></router-view>
      <router-view name="b"></router-view>
    </div>
  </div>

js代码:

<script>
    var header = Vue.component('header', {
      template: '<div class="header">header</div>'
    });

    var sidebar = Vue.component('sidebar', {
      template: '<div class="sidebar">sidebar</div>'
    });

    var mainbox = Vue.component('mainbox', {
      template: '<div class="mainbox">mainbox</div>'
    });

    // 创建路由对象
    var router = new VueRouter({
      routes: [
        {
          path: '/', components: {
            default: header,
            a: sidebar,
            b: mainbox
          }
        }
      ]
    });

    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {},
      router
    });
  </script>

样式:

 <style>
    .header {
      border: 1px solid red;
    }

    .content{
      display: flex;
    }
    .sidebar {
      flex: 2;
      border: 1px solid green;
      height: 500px;
    }
    .mainbox{
      flex: 8;
      border: 1px solid blue;
      height: 500px;
    }
  </style>

ref和$.refs可以很方便的调用元素,以及组件里面里面的方法是属性

<div id="app">
    <input type="button" value="获取元素" @click="getElement" ref = "mybtn">

    <h3 id = "myh3" ref = "myh3">我是h3</h3>

    <hr>

    <login ref = "mylogin"></login>

</div>

<script>
    var login = {
        template:'<h1>登录组件</h1>',
        data(){
            return {
                msg:'登录组件的数据'
            }
        },
        methods:{
            show(){
                console.log('login里面的方法')
            }
        }
    }

    var vm = new Vue({
        el:'#app',
        data:{

        },
        methods:{
            getElement() {
                //console.log(document.getElementById('myh3').innerText)
                //console.log(this.$refs.myh3.innerText)
                this.$refs.mylogin.show()

            }
        },
        components:{
            login
    }

    })

</script>

什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可;
组件化和模块化的不同:

  • 模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
  • 组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用;

    全局组件定义的三种方式

  1. 使用 Vue.extend 配合 Vue.component 方法:

    var login = Vue.extend({
          template: '<h1>登录</h1>'
        });
        Vue.component('login', login);
  2. 直接使用 Vue.component 方法:

    Vue.component('register', {
          template: '<h1>注册</h1>'
        });
    注意:如果使用 Vue.component 定义全局组件的时候,组件名称使用了 驼峰命名,则在引用组件的时候,需要把 大写的驼峰改为小写的字母,同时,两个单词之前,使用 - 链接.
    Vue.component 第一个参数:组件的名称,将来在引用组件的时候,就是一个 标签形式 来引入 它的,第二个参数: Vue.extend 创建的组件 ,其中 template 就是组件将来要展示的HTML内容.
  3. 将模板字符串,定义到script标签种:

    <script id="tmpl" type="x-template">
          <div><a href="#">登录</a> | <a href="#">注册</a></div>
     </script>
  4. 同时,需要使用 Vue.component 来定义组件:

    Vue.component('account', {
          template: '#tmpl'
        });
    注意: 组件中的DOM结构,有且只能有唯一的根元素(Root Element)来进行包裹!不论是哪种方式创建出来的组件,组件的 template 属性指向的模板内容,必须有且只能有唯一的一个根元素.也可以在页面中使用<template id="tmpl"></template>包裹模板内容,使用id进行调用。

组件中展示数据和响应事件

  1. 在组件中,data需要被定义为一个方法,例如:

    Vue.component('account', {
          template: '#tmpl',
          data() {
            return {
              msg: '大家好!'
            }
          },
          methods:{
            login(){
              alert('点击了登录按钮');
            }
          }
        });
  2. 在子组件中,如果将模板字符串,定义到了script标签中,那么,要访问子组件身上的data属性中的值,需要使用this来访问;

组件的切换

  1. 使用flag标识符结合v-ifv-else切换组件

    页面结构:

    <div id="app">
        <input type="button" value="toggle" @click="flag=!flag">
        <my-com1 v-if="flag"></my-com1>
        <my-com2 v-else="flag"></my-com2>
      </div>

    Vue实例定义:

    <script>
        Vue.component('myCom1', {
          template: '<h3>奔波霸</h3>'
        })
    
        Vue.component('myCom2', {
          template: '<h3>霸波奔</h3>'
        })
    
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            flag: true
          },
          methods: {}
        });
      </script>
  2. 使用:is属性来切换不同的子组件,并添加切换动画
    Vue提供了 component ,来展示对应名称的组件,component 是一个占位符, :is 属性,可以用来指定要展示的组件的名称.
    组件实例定义方式:

     // 登录组件
    const login = Vue.extend({
      template: `<div>
        <h3>登录组件</h3>
      </div>`
    });
    Vue.component('login', login);
    
    // 注册组件
    const register = Vue.extend({
      template: `<div>
        <h3>注册组件</h3>
      </div>`
    });
    Vue.component('register', register);
    
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: { comName: 'login' },
      methods: {}
    });

    使用component标签,来引用组件,并通过:is属性来指定要加载的组件:

     <div id="app">
       <a href="#" @click.prevent="comName='login'">登录</a>
       <a href="#" @click.prevent="comName='register'">注册</a>
       <hr>
       <transition mode="out-in">
         <component :is="comName"></component>
       </transition>
     </div>

    附:添加切换动画样式:

     <style>
    .v-enter,
    .v-leave-to {
      opacity: 0;
      transform: translateX(30px);
    }
    
    .v-enter-active,
    .v-leave-active {
      position: absolute;
      transition: all 0.3s ease;
    }
    
    h3{
      margin: 0;
    }
     </style>

父组件向子组件传值

父组件,可以在引用子组件的时候, 通过 属性绑定(v-bind:) 的形式, 把 需要传递给 子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用,子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的, 组件中的 所有 props 中的数据,都是通过 父组件传递给子组件的props 中的数据,都是只读的,无法重新赋值.而子组件自己的数据 data 上的数据,都是可读可写的。
组件实例定义方式,注意:一定要使用props属性来定义父组件传递过来的数据

<script>
   // 创建 Vue 实例,得到 ViewModel
   var vm = new Vue({
     el: '#app',
     data: {
       msg: '这是父组件中的消息'
     },
     components: {
       son: {
         template: '<h1>这是子组件 --- {{finfo}}</h1>',
         props: ['finfo']// 把父组件传递过来的 parentmsg 属性,先在 props 数组中,定义一下,这样,才能使用这个数据
       }
     }
   });
  </script>

使用v-bind或简化指令,将数据传递到子组件中:

 <div id="app">
   <son :finfo="msg"></son>
 </div>

子组件向父组件传值

  1. 原理:父组件将方法的引用,传递到子组件内部,子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去;
  2. 父组件将方法的引用传递给子组件,其中,getMsg是父组件中methods中定义的方法名称,func是子组件调用传递过来方法时候的方法名称
    <son @func="getMsg"></son>
  3. 子组件内部通过this.$emit('方法名', 要传递的数据)方式,来调用父组件中的方法,同时把数据传递给父组件使用.

    <div id="app">
    <!-- 引用父组件 -->
    <son @func="getMsg"></son>
    
    <!-- 组件模板定义 -->
    <script type="x-template" id="son">
     <div>
       <input type="button" value="向父组件传值" @click="sendMsg" />
     </div>
    </script>
     </div>
    
     <script>
    // 子组件的定义方式
    Vue.component('son', {
     template: '#son', // 组件模板Id
     methods: {
       sendMsg() { // 按钮的点击事件
         this.$emit('func', 'OK'); // 调用父组件传递过来的方法,同时把数据传递出去
       }
     }
    });
    
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
     el: '#app',
     data: {},
     methods: {
       getMsg(val){ // 子组件中,通过 this.$emit() 实际调用的方法,在此进行定义
         alert(val);
       }
     }
    });
     </script>

类名过渡

在进入/离开的过渡中,总共有6个累进行切换。

  1. v-enter:进入之前,元素的起始状态,此时还没有开始进入.这是一个时间点
  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。即:入场动画的时间段.
  3. v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。即:是动画离开之后,离开的终止状态,此时,元素动画已经结束了(这是一个时间点)
  4. v-leave: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。这是一个时间点.
  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  6. v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

示例图:
transition.png

对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 <transition>,则 v- 是这些类名的默认前缀。如果你使用了 <transition name="my-transition">,那么 v-enter 会替换为 my-transition-enter。也可以<transition name="my">修改前缀名字。
.v-move 和 .v-leave-active 配合使用,能够实现列表后续的元素,渐渐地漂上来的效果

注意:

  • 在实现列表过渡的时候,如果需要过渡的元素,是通过 v-for 循环渲染出来的,不能使用 transition 包裹,需要使用 transition-group.
    如果要为 v-for 循环创建的元素设置动画,必须为每一个 元素 设置 :key 属性.
  • ransition-group 添加 appear 属性,实现页面刚展示出来时候,入场时候的效果.
  • 通过 为 transition-group 元素,设置 tag 属性,指定 transition-group 渲染为指定的元素,如果不指定 tag 属性,默认,渲染为 span 标签
  • 示例:

       <transition-group appear tag="ul">
         <li v-for="(item, i) in list" :key="item.id" @click="del(i)">
           {{item.id}} --- {{item.name}}
         </li>
       </transition-group>

使用第三方CSS动画库

  1. 导入动画类库:

    <link rel="stylesheet" type="text/css" href="./lib/animate.css">

    2.定义 transition 及属性:

    <transition
      enter-active-class="fadeInRight"
      leave-active-class="fadeOutRight"
      :duration="{ enter: 500, leave: 800 }">
      <div class="animated" v-show="isshow">动画哦</div>
    </transition>

    使用 :duration="毫秒值" 来统一设置 入场 和 离场 时候的动画时长.
    :duration="{ enter: 200, leave: 400 }" 来分别设置 入场的时长 和 离场的时长

    使用钩子函数

  2. 定义 transition 组件以及三个钩子函数
    动画钩子函数的第一个参数:el,表示 要执行动画的那个DOM元素,是个原生的 JS DOM对象

    <div id="app">
     <input type="button" value="切换动画" @click="isshow = !isshow">
     <transition
     @before-enter="beforeEnter"
     @enter="enter"
     @after-enter="afterEnter">
       <div v-if="isshow" class="show">OK</div>
     </transition>
      </div>
    • beforeEnter 表示动画入场之前,此时,动画尚未开始,可以 在 beforeEnter 中,设置元素开始动画之前的起始样式.
  3. enter 表示动画 开始之后的样式,这里,可以设置小球完成动画之后的,结束状态.
  4. 动画完成之后,会调用 afterEnter
  5. 定义三个 methods 钩子方法:

    methods: {
         beforeEnter(el) { // 动画进入之前的回调
           el.style.transform = 'translateX(500px)';
         },
         enter(el, done) { // 动画进入完成时候的回调
           // 这句话,没有实际的作用,但是,如果不写,出不来动画效果;
           // 可以认为 el.offsetWidth 会强制动画刷新
           el.offsetWidth;
           el.style.transform = 'translateX(0px)';
           //这里的 done, 起始就是 afterEnter 这个函数,也就是说:done 是 afterEnter 函数的引用
           done();
         },
         afterEnter(el) { // 动画进入完成之后的回调
           this.isshow = !this.isshow;
         }
       }
  6. 定义动画过渡时长和样式

    .show{
       transition: all 0.4s ease;
     }

v-for的列表过渡

  1. 定义过渡样式

    <style>
    .list-enter,
    .list-leave-to {
      opacity: 0;
      transform: translateY(10px);
    }
    
    .list-enter-active,
    .list-leave-active {
      transition: all 0.3s ease;
    }
    </style>
  2. 定义DOM结构,其中,需要使用 transition-group 组件把v-for循环的列表包裹起来:

     <div id="app">
    <input type="text" v-model="txt" @keyup.enter="add">
    
    <transition-group tag="ul" name="list">
      <li v-for="(item, i) in list" :key="i">{{item}}</li>
    </transition-group>
     </div>
  3. 定义 VM中的结构

     var vm = new Vue({
      el: '#app',
      data: {
        txt: '',
        list: [1, 2, 3, 4]
      },
      methods: {
        add() {
          this.list.push(this.txt);
          this.txt = '';
        }
      }
    });

1.引入vue-resource

  <script src="./lib/vue-2.4.0.js"></script>
  <script src="./lib/vue-resource-1.3.4.js"></script>

注意:vue-resource依赖于 Vue,所以vue-resource一定要在Vue的后面。

方法列表:

  • get(url, [options])
  • head(url, [options])
  • delete(url, [options])
  • jsonp(url, [options])
  • post(url, [body], [options])
  • put(url, [body], [options])
  • patch(url, [body], [options])

选项:

参数类型描述
urlstring请求的目标URL
bodyObject, FormData, string作为请求体发送的数据
headersObject作为请求头部发送的头部对象
paramsObject作为URL参数的参数对象
methodstringHTTP方法 (例如GET,POST,...)
timeoutnumber请求超时(单位:毫秒) (0表示永不超时)
beforefunction(request)在请求发送之前修改请求的回调函数
progressfunction(event)用于处理上传进度的回调函数 ProgressEvent
credentialsboolean是否需要出示用于跨站点请求的凭据
emulateHTTPboolean是否需要通过设置X-HTTP-Method-Override头部并且以传统POST方式发送PUT,PATCH和DELETE请求。
emulateJSONboolean设置请求体的类型为application/x-www-form-urlencoded

响应:

通过如下属性和方法处理一个请求获取到的响应对象:

属性类型描述
urlstring响应的URL源
bodyObject, Blob, string响应体数据
headersHeader请求头部对象
okboolean当HTTP响应码为200到299之间的数值时该值为true
statusnumberHTTP响应吗
statusTextstringHTTP响应状态
方法类型描述
text()约定值以字符串方式返回响应体
json()约定值以格式化后的json对象方式返回响应体
blob()约定值以二进制Blob对象方式返回响应体

例子:
get请求:

this.$http.get('/get').then(function (result) {
            // 通过 result.body 拿到服务器返回的成功的数据
            // console.log(result.body)
          })

post请求:

this.$http.post('/post', {}, { emulateJSON: true }).then(result => {
            console.log(result.body)
          })

注意:通过 post 方法的第三个参数, { emulateJSON: true } 设置 提交的内容类型 为 普通表单数据格式

JSON请求

this.$http.jsonp('/jsonp').then(result => {
            console.log(result.body)
          })

定义:
全局的自定义指令:

Vue.directive('focus', {
  inserted: function (el) {
 
  }
})

私有的自定义属性:
组件中接受一个 directives 的选项:

directives: {
  focus: {
    inserted: function (el) {
      
    }
  }
}

调用:v-指令名

钩子函数
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。

钩子函数参数

指令钩子函数会被传入以下参数:
el:指令所绑定的元素,可以用来直接操作 DOM 。
binding:一个对象,包含以下属性:
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

注意:自定义指令里面的样式样,只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式。将来元素肯定会显示到页面中,这时候,浏览器的渲染引擎必然会解析样式,应用给这个元素。

这个 function 等同于 把 代码写到了 bind 和 update 中去

function (el, binding) {
         
}

函数详解:

  • 创建期间的生命周期函数

    • beforeCreate()表示的是实例创建之前就会调用改方法,在执行此函数的时候,data和methods中的数据还没有初始化。
    • created()在执行此方法的时候,data和methods中的数据已经初始化,所以,这里是最早可以调用methods里面的方法,和处理data中的数据的地方。
    • beforeMount()此时模板已经在内存中编辑完成了,但是还没有渲染到页面中。此时页面中的元素还没有真正的替换过来吗,还只是模板中的字符串。
    • mounted()内存中的模板已经挂载到了页面中了。用户已经可以看到渲染好的页面了。 mounted 是 实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,此时,如果没有其它操作的话,这个实例在内存中就不会在改变了。
  • 运行期间的生命周期函数

    • beforeUpdate()在执行此方法的时候,页面中的数据还没有发生改变,但是data中的数据已经发生了改变。
    • updated()页面中的数据和data中的数据全部是最新的了。
  • 销毁期间的生命周期函数:

    • beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
    • destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

lifecycle1.png

Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示。

过滤器语法:Vue.filter('过滤器的名称', function(){})
过滤器中的 function ,第一个参数已经固定,永远都是过滤器管道符前面传递过来的数据。

私有过滤器

定义私有过滤器过滤器有两个条件:过滤器名称和处理函数
定义:

filters: {
  capitalize: function (value) {
    //函数体
  }
}

调用:
过滤器调用时候的格式 :{{ name | 过滤器1的名称| 过滤器2的名称 }}

<td>{{item.ctime | capitalize(value)}}</td>

全局过滤器

在创建 Vue 实例之前全局定义过滤器
定义

Vue.filter('capitalize', function (value) {
 //函数体
})

注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!

简介

vue在小编看来就是一个很流行,很火的前端框架之一。那么官方怎么说的呢,我们一起看看:Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
说了这么多,小编还是不懂。不过接下来小编整理了一些经常用的东东。希望有所帮助。

使用

  1. 引入:首先引入你的vue.js.当我们导入包之后,在浏览器的内存中,就多了一个 Vue 构造函数。
  2. 使用:当 new 出来的这个 vm 对象,就是我们 MVVM中的 VM调度者。Vue 实例所控制的这个元素区域,就是MVVM的 V。
    示例:

    <div id="app">
     <p>{{ msg }}</p>
    </div>
    
    <script>
     var vm = new Vue({
         el:'#app',// 表示当前我们 new 的这个 Vue 实例,要控制页面上的哪个区域
         data:{// data 属性中,存放的是 el 中要用到的数据
             msg:'Hello World'
         }
     })
    </script>

    常用指令

  3. {{}}插值表达式。
  4. v-cloak解决未编译时期,显示未编译的代码,能够解决插值表达式闪烁的问题。这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
  5. v-text它会覆盖元素中原本的内容,但是插值表达式只会替换自己的这个占位符,不会把整个元素的内容清空。而且v-text没有闪烁问题。
  6. v-htmlv-text类似,但是v-html可以把html解析,然而v-text会把所有的值以字符串的形式输出,包括html。
  7. v-bind:简写为: 是 Vue中,提供的用于绑定属性的指令。可以写合法的JS表达式.
  8. v-on: 简写为:@事件绑定机制。为元素指定处理函数的时候,如果加了小括号,就可以给函数传参了
  9. v-model 指令,可以实现表单元素和 Model 中数据的双向数据绑定.v-model 只能运用在表单元素中。而v-bind 只能实现数据的单向绑定,从 M 自动绑定到 V, 无法实现数据的双向绑定。

事件修饰符

  • .stop 阻止冒泡。
  • .prevent 阻止默认行为。
  • .capture 实现捕获触发事件的机制。添加事件侦听器时使用事件捕获模式。
  • .self 只当事件在该元素本身(比如不是子元素)触发时触发回调。.self 只会阻止自己身上冒泡行为的触发,并不会真正阻止 冒泡的行为。
  • .once 只触发一次事件处理函数。

在Vue中使用样式

使用class样式

这些样式都需要使用v-bind做数据绑定.

  • 数组

     <h1 :class="['top','res']">我是h1</h1>
  • 三元表达式

    <h1 :class="['top','res', isactive?'active':'']">我是h1</h1>
  • 对象

    • 数组中的对象

      <h1 :class="['top','res', {'active': isactive}]">我是h1</h1>
    • 对象
    <h1 :class="{red:true, italic:true, active:true, thin:true}">我是h1</h1>

    注意:在为 class 使用 v-bind 绑定 对象的时候,对象的属性是类名,由于 对象的属性可带引号,也可不带引号; 属性的值是一个标识符。

使用内联样式

  1. 直接在元素上通过 :style 的形式,书写样式对象

     <h1 :style="{color: 'red', 'font-size': '40px'}">我是h1</h1>
  2. 将样式对象,定义到 data 中,并直接引用到 :style

       <h1 :style="[ styleObj1, styleObj2 ]">我是h1</h1>
       <h1 :style="styleObj1">这是一个h1</h1>

    在data上定义样式:

     data: {
             h1StyleObj: { color: 'red', 'font-size': '40px' },
             styleObj2: { 'font-style': 'italic' }
     }

    v-for、v-if、v-show

v-for

  • 迭代数组

    <li v-for="(item, i) in list">索引:{{i}} --- 姓名:{{item.name}} --- 年龄:{{item.age}}</li>
  • 迭代对象中的属性

    <div v-for="(val, key, i) in userInfo">{{val}} --- {{key}} --- {{i}}</div>
  • 迭代数字

    <p v-for="i in 10">这是第 {{i}} 个P标签</p>

    注意:2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的而且只接受 string / number数据类型。当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。

     <p v-for="item in list" :key="item.id">
      <input type="checkbox">{{item.id}} --- {{item.name}}
     </p>

    v-if、v-show

  • v-if 的特点:每次都会重新删除或创建元素,有较高的切换性能消耗.
  • v-show 的特点: 每次不会重新进行DOM的删除和创建操作,只是切换了元素的 display:none 样式,有较高的初始渲染消耗.
  • 如果元素涉及到频繁的切换,最好不要使用 v-if, 而是推荐使用 v-show,如果元素可能永远也不会被显示出来被用户看到,则推荐使用 v-if 。