vue梳理

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的生命周期图示

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>
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 如何进行文件的打包

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容