Vue學習小記

Vue的安裝及語法

  • 解析{{XXX}}
  • 頁面中的數據與內存中的數據雙向綁定
  • v-mdodel
  • v-show:暫時隱藏
  • v-if:直接從dom中刪除

v-for指令

v-bind指令(v-bind:可簡寫爲:)

  • 綁定數據和元素屬性:src、href
<style>
  .active {
    background: #a10;
  }
</style>
<a :class="{active: isActive}" :href="url">
  點我
</a>
var app = new Vue({
  el: '#app',
  data: {
    url: 'http://baidu.com',
    img: 'https://dummyimage.com/100x100/ffcc00/ffffff',
    klass: 'btn btn-default',
    isActive: true,
  }
});

v-on指令(v-on:可簡寫爲@,v-on=不可簡寫)

v-model指令及其修飾符

  • 適用於:input、textarea、select
  • v-model對變量進行綁定並操作,{{XXX}}輸出變量
  • v-model.lazy 失焦更新
  • v-model.trim 刪去空格
  • v-model.number 字符串轉爲number

v-model在其他元素及類型上的用法

控制流指令

  • v-if
  • v-else-if
  • v-else

計算屬性

  • method的區別:緩存數據,提高了性能
computed: {
    sum: function () {
      return parseFloat(this.math) + parseFloat(this.physics) + parseFloat(this.english);
    },
    average: function () {
      return Math.round(this.sum / 3);
    }
  },
});
<tr>
  <td>總分</td>
  <td>{{sum}}</td>
</tr>
<tr>
  <td>平均分</td>
  <td>{{average}}</td>
</tr>

組件 - 全局及局部組件

  • 全局組件
Vue.component('like', {
  template: ''
})
  • 局部組件
var alert_component = {
  template: '<button @click="on_click">彈彈彈</button>',
  methods: {
    on_click: function () {
      alert('Yo.');
    }
  }
};

new Vue({
  el: '#seg1',
  components: {
    alert: alert_component
  }
});

組件 - 配置組件

  • template必須放在el外面
Vue.component('like', {
  template: '#like-component-tpl',
  data: function () {
    return {
      like_count: 10,
      liked: false,
    }
  },
  methods: {
    toggle_like: function () {
      if (!this.liked)
        this.like_count++;
      else
        this.like_count--;

      this.liked = !this.liked;
    }
  }
})
<div id="app">
  <like></like>
</div>

<template id="like-component-tpl">
  <button :class="{liked: liked}" @click="toggle_like()">
    👍👍 {{like_count}}
  </button>
</template>

組件 - 父子通信

  • 自定義傳參
Vue.component('user', {
  template: '<a :href="\'/user/\' + username">{{username}}</a>',
  props: ['username'],
  methods: {}
})
<div id="app">
  <user username="biaoyansu"></user>
</div>

組件 - 子父通信

Vue.component('balance', {
  template: `
  <div>
    <show @show-balance="show_balance"></show> //監聽事件
    <div v-if="show">
    您的餘額:¥98逸
    </div>
  </div>
  `,
  methods: {
    show_balance: function(data) {
      this.show = true;
      console.log('data:', data);
      
    }
  },
  data: function() {
    return {
      show: false,
    }
  }
});
Vue.component('show', {
  template: '<button @click="on_click()">顯示餘額</button>',
  methods: {
    on_click() {
      this.$emit('show-balance', {a: 1, b: 2}); //$emit向父級元素傳遞事件,觸發一個事件
    }
  }
});

new Vue({
  el: '#app',
})

組件 - 任意及平行組件間通信

  • 模板必須有最外層根元素div
var Event = new Vue(); //調度器

Vue.component('huahua', {
  template: `
    <div>
        我說:<input @keyup="on_change" v-model="i_said"/>
    </div>`,
  methods: {
    on_change: function () {
      Event.$emit('huahua-said-something', this.i_said); //$emit觸發器返回函數名和函數值
    }
  },
  data: function () {
    return {
      i_said: '',
    }
  }
})
Vue.component('shuandan', {
  template: `<div>花花說:{{huahua_said}}</div>`,
  data: function () {
    return {
      huahua_said: '',
    };
  },
  mounted: function () { //鉤子,生命週期完成後,成熟後觸發事件
    var me = this;
    Event.$on('huahua-said-something', function(data) {
      me.huahua_said = data;
    });
  }
})

new Vue({
  el: '#app',
})

過濾器

  • filter和計算屬性類似,簡單的用filter,複雜的用計算屬性,計算屬性有緩存
Vue.filter('meter', function (val, unit) {
  val = val || 0; //無val默認值爲0
  unit = unit || 'm'; //無unit默認值爲m
  return (val / 1000).toFixed(2) + unit;
});

Vue.filter('currency', function (val, unit) {
  val = val || 0;
  unit = unit || '元';
  return val + unit;
});

new Vue({
  el: '#app',
  data: {
    price: 10,
    length: 10,
  }
})
<div>
  <input v-model="length"> mm
  <br>
  {{length | meter}}
</div>
<hr>
<div>
  <input v-model="price">
  <br>
  {{ price | currency('USD') }}
</div>

自定義指令 - 基礎配置

Vue.directive('pin', function (el, binding) {

  var pinned = binding.value; //默認爲false
  console.log(pinned)
  if (pinned) {
    el.style.position = 'fixed';
    el.style.top = '10px';
    el.style.left = '10px';
  } else {
    el.style.position = 'static';
  }
})

new Vue({
  el: '#app',
  data: {
    card1: {
      pinned: false,
    },
    card2: {
      pinned: false,
    },
  }
})
<div v-pin="card1.pinned" class="card">
  <button @click="card1.pinned = !card1.pinned">釘住/取消</button>
  Lorem ipsum dolor sit amet, consectetur
</div>
<div v-pin="card2.pinned" class="card">
  <a @click="card2.pinned = !card2.pinned" href="#">pin it</a>
  Lorem ipsum dolor sit amet, consectetur
</div>

自定義指令 - 配置傳參及修飾符

Vue.directive('pin', function (el, binding) {

  var pinned = binding.value;
  //modifiers:一個包含修飾符的對象。例如:v-my-directive.foo.bar 中,修飾符對象爲 { foo: true, bar: true }。
  var position = binding.modifiers;
  var warning = binding.arg; //arg緊跟:

  if (pinned) {
    el.style.position = 'fixed';

    for (var key in position) {
      if (position[key]) {
        el.style[key] = '10px';
      }
    }
    if (warning === 'true') {
      el.style.background = 'yellow';
    }
  } else {
    el.style.position = 'static';
  }
})

new Vue({
  el: '#app',
  data: {
    card1: {
      pinned: false,
    },
    card2: {
      pinned: false,
    },
  }
})
<div v-pin:true.bottom.left="card1.pinned" class="card">
  <button @click="card1.pinned = !card1.pinned">釘住/取消</button>
  Lorem ipsum dolor sit amet, consectetur
</div>
<div v-pin="card2.pinned" class="card">
  <a @click="card2.pinned = !card2.pinned" href="#">pin it</a>
  Lorem ipsum dolor sit amet, consectetur
</div>

###混合 mixins

  • component中代碼複用
var base = {
  methods: {
    show: function () {
      this.visible = true;
    },
    hide: function () {
      this.visible = false;
    },
    toggle: function () {
      this.visible = !this.visible;
    }
  },
  data: function () {
    return {
      visible: false,
    }
  }
};

Vue.component('tooltip', {
  template: `
  <div>
    <span @mouseenter="show" @mouseleave="hide">bys</span>
    <div v-if="visible">
    白巖鬆
    </div>
  </div>
  `,
  mixins: [base],
  data: function () {
    return {
      visible: true,
    }
  }
});

Vue.component('popup', {
  template: `
  <div>
    <button @click="toggle">Popup</button>
        <div v-if="visible">
        <span @click="hide">X</span>
          <h4>title</h4>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet dolorum, iusto non nostrum porro ratione. Dolor dolorem id impedit. Dolore excepturi exercitationem incidunt iste magnam odio quas temporibus. Assumenda, magni.
        </div>
  </div>
  `,
  mixins: [base]
});

new Vue({
  el: '#app',
  data: {}
})
<div id="app">
  <tooltip></tooltip>
  <popup></popup>
</div>

插槽 slots

  • 相當於component中的變量
<div id="app">
  <panel>
    <div slot="title">
        Yo.
    </div>
    <div slot="content">
        Yo
        Yo
        Yo
    </div>
  </panel>
</div>

<template id="panel-tpl">
  <div class="panel">
    <div class="title">
        <slot name="title"></slot>
    </div>
    <div class="content">
        <slot name="content"></slot>
    </div>
    <div class="footer">
      <slot name="footer">
        更多信息
      </slot>
    </div>
  </div>
</template>

vue-router是什麼和怎麼用

無整頁刷新,表單數據點回來仍保留

安裝和基本配置

var routes = [
  {
    path: '/',
    component: {
      template: `
      <div>
        <h1>首頁</h1>
      </div>
      `,
    },
  },
  {
    path: '/about',
    component: {
      template: `
      <div>
        <h1>關於我們</h1>
      </div>
      `,
    },
  },
];

var router = new VueRouter({
  routes: routes,
});

new Vue({
  el: '#app',
  router: router,
});
<div id="app">
  <div>
    <router-link to="/">首頁</router-link>
    <router-link to="/about">關於我們</router-link>
  </div>
  <div>
    <router-view></router-view>
  </div>
</div>

傳參及獲取傳參

path: '/user/:name',
component: {
  template: `
  <div>
    <div>我叫:{{$route.params.name}}</div>
    <div>我今年:{{$route.query.age}}歲了</div>
  </div>
  `,
},
<div id="app">
  <div>
    <router-link to="/">首頁</router-link>
    <router-link to="/about">關於我們</router-link>
    <router-link to="/user/王花花">王花花</router-link>
    <router-link to="/user/李拴蛋">李拴蛋</router-link>
  </div>
  <div>
    <router-view></router-view>
  </div>
</div>

子路由

var routes = [
  {
    path: '/',
    component: {
      template: `
      <div>
        <h1>首頁</h1>
      </div>
      `,
    },
  },
  {
    path: '/about',
    component: {
      template: `
      <div>
        <h1>關於我們</h1>
      </div>
      `,
    },
  },
  {
    path: '/user/:name',
    component: {
      template: `
      <div>
        <div>我叫:{{$route.params.name}}</div>
        <router-link to="more" append>更多信息</router-link>
        <router-view></router-view>
      </div>
      `,
    },
    children: [
      {
        path: 'more',
        component: {
          template: `
          <div>
          用戶{{$route.params.name}}的詳細信息
          Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci cum deleniti doloribus expedita inventore natus officiis quod quos similique voluptate! Distinctio nisi sequi tenetur voluptatum? Debitis iste neque pariatur voluptatibus?
            </div>
          `
        }
      }
    ]
  },
];

var router = new VueRouter({
  routes: routes,
});
<div id="app">
  <div>
    <router-link to="/">首頁</router-link>
    <router-link to="/about">關於我們</router-link>
    <router-link to="/user/王花花">王花花</router-link>
    <router-link to="/user/李拴蛋">李拴蛋</router-link>
  </div>
  <div>
    <router-view></router-view>
  </div>
</div>

手動訪問和傳參

命名視圖

var routes = [
  {
    path: '/',
    component: {
      template: `
      <div>
        <h1>首頁</h1>
      </div>
      `,
    }
  },
  {
    path: '/user',
    components: {
      sidebar: {
        template: `
        <div>
          <ul>
              <li>用戶列表</li>
              <li>權限管理</li>
          </ul>
        </div>
        `
      },
      content: {
        template: `
            <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti in, laborum molestias necessitatibus optio perferendis quaerat quas qui quisquam sapiente. Architecto corporis eos eum libero optio, perspiciatis quo rem vel!</div>
        `
      }
    }
  },
  {
    path: '/post',
    components: {
      sidebar: {
        template: `
        <div>
          <ul>
              <li>帖子列表</li>
              <li>標籤管理</li>
          </ul>
        </div>
        `
      },
      content: {
        template: `
            <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti in, laborum molestias necessitatibus optio perferendis quaerat quas qui quisquam sapiente. Architecto corporis eos eum libero optio, perspiciatis quo rem vel!</div>
        `
      }
    }
  }
];

導航鉤子

訪問限制,中間件,組件的生命週期

var routes = [
  {
    path: '/',
    component: {
      template: `<h1>首頁</h1>`
    }
  },
  {
    path: '/login',
    component: {
      template: `<h1>登錄</h1>`
    }
  },
  {
    path: '/post',
    component: {
      template: `<h1>帖子管理</h1>`
    }
  },
];

var router = new VueRouter({
  routes: routes,
});

router.beforeEach(function (to, from, next) {
  var logged_in = true;

  if (!logged_in && to.path == '/post')
    next('/login');
  else
    next();
});

router.afterEach(function (to, from) {

});

元數據及路由匹配

使用meta元數據進行訪問限制

var routes = [
  {
    path: '/',
    component: {
      template: `<h1>首頁</h1>`
    }
  },
  {
    path: '/a',
    meta: {
      login_required: true,
    },
    component: {
      template: `<h1>A</h1>`
    }
  },
  {
    path: '/login',
    component: {
      template: `<h1>登錄</h1>`
    }
  },
  {
    path: '/post',
    meta: {
      login_required: true
    },
    component: {
      template: `<div>
        <h1>帖子管理</h1>
        <router-link to="rain" append>後座</router-link>
        <router-view></router-view>
      </div>`,
    },
    children: [
      {
        path: 'rain',
        component: {
          template: `<h2>雨天asdf後座</h2>`
        }
      }
    ]
  },
];

var router = new VueRouter({
  routes: routes,
});

router.beforeEach(function (to, from, next) {
  var logged_in = true;

  if (!logged_in && to.matched.some(function (item) {
      return item.meta.login_required;
    }))
    next('/login');
  else
    next();
});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章