vue梳理

weixin_33816300發表於2018-03-01

vue使用總結心得

vue的安裝

在這裡我們主要針對的是vue的單頁面專案 如果僅僅是為了單個案例可以直接下載 然後script安裝

Vue 提供一個官方命令列工具,可用於快速搭建大型單頁應用。該工具為現代化的前端開發工作流提供了開箱即用的構建配置。只需幾分鐘即可建立並啟動一個帶熱過載、儲存時靜態檢查以及可用於生產環境的構建配置的專案:

# 全域性安裝 vue-cli
$ npm install --global vue-cli
# 建立一個基於 webpack 模板的新專案
$ vue init webpack my-project
# 安裝依賴,走你
$ cd my-project
$ npm install
$ npm run dev

vue的生命週期

vue的生命週期圖示

5703029-2053cda58f31f3e9..png
mark
header 1 header 2
beforeCreate 例項剛剛被建立 el和data並未初始化
created 例項建立完成 data被初始化 但是el沒有被初始化 dom不存在
beforeMount 完成了el的初始化 模板編譯之前
mounted 模板編譯之後 完成掛載
beforeUpdate 元件更新之前
uodated 元件更新之後
beforeDestory 元件銷燬前呼叫
destoryed 元件銷燬後呼叫

vue的核心思想(資料繫結和元件化)

  • ==vue的雙向資料繫結==
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <input type="text" v-model="text">
    {{ text }}

</div>
</body>
</html>
<script>
    /*
      1 資料監聽器 首先有一個資料監聽的函式 目的是 監聽資料的變化 拿到最新值 並通知訂閱者
      2 指令解析器 有一個編譯的函式 對元素的節點進行掃描和解析 並繫結相關的更新函式
      3 watcher 作為連線observe和compile的敲了
      3 訂閱者 這個訂閱者 負責與watcher 配合收到屬性變動的通知,執行相應的回撥函式 完成檢視的更新     */
    function observe(obj, vm) {
        //  對傳入的物件 遍歷 並分別新增 object.defineProperty
        Object.keys(obj).forEach((key) => {
            defineReactive(vm, key, obj[key])
        })
    }

    function defineReactive(vm, key, val) {
        var dep = new Dep();
        Object.defineProperty(vm, key, {
            get: function () {
                // 通過這一步 新增訂閱者
                if (Dep.target) dep.addSub(Dep.target)
                return val;
            },
            set: function (newval) {
                if (newval === val) return
                val = newval;
                // 通知訂閱者
                dep.notify()
            }
        })
    }

    // 需要實現一個訊息訂閱器
    function Dep() {
        // 訊息訂閱的讓容器是一個陣列 陣列的每一項 都是指代一個view和mode的中間者
        this.subs = []
    }

    Dep.prototype = {
        addSub: function (sub) {
            this.subs.push(sub)
        },
        notify: function () {
            this.subs.forEach((sub) => {
                // 在這裡 需要配合watcher進行更新
                sub.update()
            })
        }
    }

    //  在這裡增加dom編譯模板
    function nodeToFragment(node, vm) {
        var flag = document.createDocumentFragment();
        var child;
        while (child = node.firstChild) {
            compile(child, vm);
            // 將子節點劫持到文字節點中
            flag.appendChild(child)
        }
        return flag
    }

    function compile(node, vm) {
        var reg = /\{\{(.*)\}\}/;
        // 跟據節點型別去判斷
        if (node.nodeType === 1) {
            var attr = node.attributes;
            for (var i = 0; i < attr.length; i++) {
                if (attr[i].nodeName === 'v-model') {
                    // 此時 name為text
                    var name = attr[i].nodeValue;
                    // 增加資料的變化監聽
                    node.addEventListener('input', (e) => {
                        vm[name] = e.target.value;
                    });
                    // 在這裡 因為 我們的資料監聽器 已經封裝了vm[name]  觸發了 getter方法 完成了資料的初始化
                    node.value = vm[name];
                    node.removeAttribute('v-model')
                }
            }
            new Watcher(vm, node, name, 'input')
        }
        if (node.nodeType === 3) {
            if (reg.test(node.nodeValue)) {
                var name = RegExp.$1;
                name = name.trim();
                new Watcher(vm, node, name, 'text')
            }
        }
    }

    //訂閱者 搭建資料監聽變化和變異模板的橋樑
    function Watcher(vm, node, name, nodeType) {
        Dep.target = this;
        this.vm = vm;
        this.node = node;
        this.name = name;
        this.nodeType = nodeType
        this.update()
        Dep.target = null;
    }

    Watcher.prototype = {
        update: function () {
            this.get()
            if (this.nodeType === 'text') {
                this.node.nodeValue = this.value
            }
            if (this.nodeType === 'input') {
                this.node.value = this.value
            }
        },
        get: function () {
            this.value = this.vm[this.name];
        }
    }


    function Vue(options) {
        // 將options裡面的data屬性 放入資料監聽器
        this.data = options.data;
        var data = this.data;
        observe(data, this); // this指代vm
        // 對指定id的dom 進行頁面的渲染
        this.$el = options.el;
        var id = this.$el;
        var Dom = nodeToFragment(document.getElementById(id), this);
        // 編譯完成之後 將dom 新增到節點中
        document.getElementById(id).appendChild(Dom)
    }

    var vm = new Vue({
        el: 'app',
        data: {
            text: 'hello,world'
        }
    })

    vm.text = 'ma'

</script>
5703029-69cf49b5bc385b2d..png
mark
  • 元件化思想
  1. 將實現頁面的某一部分功能的結構,樣式和邏輯封裝為一個整體,使其高內聚,低耦合,達到分治和複用的目的

     為了提高程式碼複用性,減少重複性的開發,我們就把相關的程式碼按照 template、style、script 拆分,封裝成一個個的元件。元件可以擴充套件
    

    HTML 元素,封裝可重用的 HTML 程式碼,我們可以將元件看作自定義的 HTML 元素。在 Vue 裡面,每個封裝好的元件可以看成一個個的 ViewModel。

  2. 元件的執行順序

  • 子元件先在父元件中的 components 中進行註冊。
  • 父元件利用 Vue.component 註冊到全域性。
  • 當渲染父元件的時候,渲染到 <child-component> ,會把子元件也渲染出來。

vue的路由分發(vue-router)

vue的路由分發主要是使用vue-router 本質來說 使用了雜湊路徑和瀏覽器的history(html5新增api)

vue-router的安裝和專案中的配置

npm install vue-router --save

vue-router的官網

//  在main.js中這樣配置  
import Vue from 'vue'
import App from './App'
import router from './router'

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: {App},
  methods: {
    
  },
  created() {
    
  },
})

//  在router資料夾下的index.js中 這樣配置  

import Vue from 'vue';
import Router from 'vue-router';
import dashboard from '../pages/dashboard/dashboard.vue';


import index from '../pages/index.vue';
//系統設定頁面
import systemSetting from '../components/systemSetting/systemSetting.vue'
// 引入登入頁
import login from '../pages/auth/login/login.vue'
//引入註冊頁
import register from '../pages/auth/register/register.vue'

Vue.use(Router)

var router = new Router({
  routes: [
    {
      path: '/login',
      name: 'login',
      component: superTubeLogin,
    },
    {
      path: '/register',
      name: 'register',
      component: register
    },
   
    {
      path: '/',
      name: 'index',
      component: index,
      children: [
        {
          path: '/dashboard',
          name: 'dashboard',
          component: dashboard,
        },
        //系統設定的頁面
        {
          path: '/systemSetting',
          name: 'systemSetting',
          component: systemSetting,
        },
        //工作組

        //授權使用者管理
        {
          path: '/boxUserManageAllow',
          name: 'boxUserManageAllow',
          component: boxUserManageAllow
        },
      ]
    },
    {
      path: '*',
      component: notFoundComponent
    }
  ]
})


router.beforeEach((to, from, next) => {
  // 這裡寫的邏輯 任何路由跳轉之前都會執行
})


export default router



我們可以使用vue-router做那些事

  1. 配置路由分發

  2. 設定路由重定向

    • 典型的應用場景有 做登入前的禁止跳轉
    • 在使用者訪問不存在的頁面的時候 跳轉到自定義的404頁面
  3. 在元件中進行路由的跳轉

  4. 進行元件之間的傳參

    const router = new VueRouter({
      routes: [
        {
          // 
          path: '/user/:userId',
          name: 'user',
          component: User
        }
      ]
    })
    
    // 在元件中 應該這樣寫 router-link 在渲染時 會被轉化為a標籤
    <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
    // 在vue的生命週期 或者 methods中 應該這樣寫  
    router.push({ name: 'user', params: { userId: 123 }})
    
    // 關於如何使用query進行傳遞引數  這裡給出了一個示例
    // http://blog.csdn.net/k491022087/article/details/70214664
    

    向路由元件傳遞props

    https://router.vuejs.org/zh-cn/essentials/passing-props.html

  5. 根據路由元資訊 設定元件的初始化或者區別元件

  6. 設定過渡的動態效果

  7. 路由資訊物件

    https://router.vuejs.org/zh-cn/api/route-object.html

vue-router的使用注意事項

  • 在元件中跳轉的時候 和 獲取路由元資訊的時候

    //  元件中跳轉
    this.$router.push({
              name: page,
              params: {id: 0, type: page, content: item.content, template: item.template}
     })
     
     //  獲取路由元資訊 
    this.$route.params.apiId
     
    

  • 監聽路由變化

    wacth:{
      '$route'(to, from) {
           .....
          },
    }
    

vue的複雜儲存(vuex)

vue通訊

專案中遇到的比較通用的問題(易錯點)

1 如何阻止冒泡和事件的預設行為

2 多層資料的巢狀以及更改vue遍歷好的陣列之後 如何進行實時顯示

3 如果遇到跨域問題 如何解決

4 如何減少檔案壓縮體積

5 如何進行檔案的打包

相關文章