Vue基础知识浅谈

mvc和mvvm

  • mvc和mvvm

    • 都是软件架构思想

    • mvc (react)

      • model: 数据保存

      • view: 用户界面

      • Controller: 业务逻辑

      • 所有通信都是单向的. view -> controller -> model -> view

    • mvvm(vue)

      • model: 数据层

      • view: 视图层

      • viewmodel: 视图模型层

      • view和viewmodel是同步更改的,viewmodel再和model层进行通信

      • 数据流向 都是单向

        • mvc: view -> controller -> model -> view

        • mvvm: view <-> viewmodel -><- model

vue中常见的指令

  • v-for 循环
  • v-if 判断是否成立,它不成立代码不加入
  • v-show 是否显示,显示后display为block,如果后面不成立变为none
  • v-bind 绑定变量 简写:
  • v-on 事件 简写@
  • v-else 如果v-if不成立,这个就成立
  • v-else-if 再次判断
  • v-model 绑定一个变量和当前表单的值绑定
  • v-html 解析标签
  • v-text 不解析标签
  • v-once 只运行一次
  • v-slot 插槽
  • v-pre 不解析标签包裹中的{{变量}},这个变量不解析
  • v-cloak 防止闪烁,在生命周期mounted前,变量在标签内无实际数据,这个可以防止在未有数据之前显示,而是有了数据后再显示出来

v-if和v-show的区别和场景,v-html和v-text的区别

v-if和v-show

区别:

1.手段:v-if是通过控制dom节点的存在与否来控制元素的显隐;v-show是通过设置DOM元素的display样式,block为显示,none为隐藏;

2.编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;

3.编译条件:v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载); v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素保留;

4.性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;

场景:

如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好

v-html和v-text

v-text和{{}}表达式渲染数据,不解析标签。

v-html不仅可以渲染数据,而且可以解析标签。

vue生命周期

    初始化事件,生命周期

beforeCreate

    注入数据,初始化响应式数据

cteated

    是否有el和template选项

beforeMount

    将数据挂载到模板中,将虚拟DOM转成真实dom

mounted

    数据改变时触发,dom的更新前后

beforeUpdate

updated

    组件销毁的时候触发

beforeDestroy

destroyed

activated

    缓存组件被激活时调用

deactivated

    缓存组件被停用时调用

errorCaptured

    子孙组件出错时调用

计算属性,方法,侦听器的区别

计算属性有缓存,方法无缓存,所以只有在数据发生变化的时候,计算属性才行重新执行

watch适合处理的场景是,侦听一个数的变化,当该数据变化,来处理其他与之相关数据的变化(该数据影响别的多个数据)

computed适合处理的场景是,获得一个值或者结果,该结果受其他的依赖的影响。(一个数据受多个数据影响)

描述一下插槽,过滤器和混入

Mixin混入:把各个组件下相同的js部分提取出来,分发给每一个用到的组件,这样可以减少代码量进行优化,但是分发到各个组件下的数据都是相互独立的 全局的mixin不需要在vue实例下进行mixins=[mixin] ,局部的要

//全局的mixin,不需要在实例vue里进行mixins=[mixin]

    Vue.mixin({

        methods: {

            hand() {

                console.log(1)

            }

        }

    })

//局部

const mixin = {

        data() {

            return {

                pageNum: 1,

                pageCount: 10

            }

        },

        created() {

            console.log("mixin")

        }

    }

插槽:在子组件调用处的中间插入HTML的内容,叫做插槽

-具名插槽:在子组件分发插槽处,寻找父组件对应的插槽名字,把相应的HTML内容渲染到子组件中,注意HTML结构,如果不写名字,默认名字为default

-作用域插槽:子组件的数据传递给父组件时,使用作用域插槽

过滤:将传入的数据进行改变在输出

什么是前端路由,传统的路由实现?

  • 一个url与相应的处理程序之间的映射关系

    • 根据不同的url地址展示不同的内容或者页面
  • 因为vue是个spa(单页面应用,只有一个html文件)

    • 监听hashchange事件

vue-router

  • vue路由有哪几种模式,有什么区别

    • 三种
      • hash模式(hashchange事件)
        • 他带#号,用起来比较好用,比较丑
      • history模式(html5实现)
        • 不带#号,比较好看,需要后端配合
      • abstract
        • 在 Weex 环境中使用
  • 什么是嵌套路由,动态路由和路由重定向
    嵌套路由:如果一个页面内点击跳到下一个地址,但是页面没有进行跳转,那么这个跳转的路由写在当前路由下,作为child路由
    动态路由:- 例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果
    - 动态路径参数 以冒号开头
    path: ‘/detail/:id’
    路由重定向:redirect
    重定向也是通过 routes 配置来完成,可以从一个url重定向到另一个url
    { path: '/', // redirect是重定向 redirect: '/index', },
    - 路由传参怎么做?

    • 通过动态路由做
      - 描述一下路由守卫

    全局前置守卫

    const router = new VueRouter({ … })
    router.beforeEach((to, from, next) => {
    // …
    })

    to: Route: 即将要进入的目标 路由对象
    from: Route: 当前导航正要离开的路由

    全局后置钩子

    router.afterEach((to, from) => {
    // …
    })

    路由独享守卫, 只有在这个路由里面做守卫

    beforeEnter: (to, from, next) => {
    // …
    }
    写在路由内部的

    组件内的守卫

    写在.vue文件里面,当作option使用
    beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 this
    // 因为当守卫执行前,组件实例还没被创建
    },
    beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 this
    },
    beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 this
    }

描述一下vuex(从下面几个方向回答)

  • 是做什么的?
    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

  • 有哪几个部分
    -state

    • mutations
    • actions
    • getters
    • module
  • 每个部分都做什么

    state

    • 存放全局的状态的
    • 获取: this.$store.state.xxx 这样也能修改,但是不推荐,因为无法事件记录变化,并且在严格模式下是无法这样修改的
    • 修改: 通过mutations
    • 辅助函数: …mapState(), 括号内可以写数组或者对象,写数组的话,名字无法改变,对象的话名字可以自己写;写在computed里面

    mutations

    • 写同步方法的,是唯一改变state的地方
    • 书写: xxx(state) {} 可以直接调用state
    • 调用: this.$store.commit(‘xxx’, payload), payload最好是传对象
    • 辅助函数: …mapMutations(), 写在methods里面

    actions

    • 写异步方法,在异步方法里面调用mutations的方法
    • 书写: xxx(context) {} context是一个对象,可以结构
    • 调用: this.$store.dispatch(‘xxx’, payload)
    • 辅助函数: …mapActions(), 写在methods里面

    getters

    • 相当于vuex里面的计算属性,逻辑复杂且多个组件都要用的时候
    • 书写: xxx(state) { return …} 可以直接调用state
    • 获取: this.$store.getters.xxx
    • 辅助函数: …mapGetters(), 写在computed里面

    module

    • Vuex 允许我们用module将 store 分割成模块,模块化划分,便于管理
      const moduleA = {
        state: () => ({ ... }),
        mutations: { ... },
        actions: { ... },
        getters: { ... }
      }
    
      const moduleB = {
        state: () => ({ ... }),
        mutations: { ... },
        actions: { ... }
      }
    
      const store = new Vuex.Store({
        modules: {
          a: moduleA,
          b: moduleB
        }
      })
    
      store.state.a // -> moduleA 的状态
      store.state.b // -> moduleB 的状态
    
    • 获取state: this.$store.state.a.xxx
    • 调用mutations: this.store.commit(‘xxx’) 方法是写在全局的,所以不需要写是哪个模块的,但是如果模块有命名,this.store.commit(‘b/xxx’)
  • 状态的流向(流程图)
    Vue基础知识浅谈_第1张图片

  • 辅助函数
    辅助函数: …mapState(), 括号内可以写数组或者对象,写数组的话,名字无法改变,对象的话名字可以自己写;写在computed里面
    辅助函数: …mapMutations(), 写在methods里面
    辅助函数: …mapActions(), 写在methods里面
    辅助函数: …mapGetters(), 写在computed里面

组件传参怎么做

  • 父子传参
  • 非父子传参
    • 父子组件之间的传参
      • 父传子:

        • 父组件用自定义的属性
        • 子组件用props去接受 props: [‘msg’] this.msg
      • 子传父

        • 父组件用自定义事件,在父组件的template里写子组件
          method (val) {
          console.log(val)
          }
        • 子组件用emit去发布 this.emit(‘message’, 传递的值),这个会自动激发父组件写的自定义事件

你常用的git命令有哪些

  • init 初始化
  • config 配置
    git config --global user.name ‘用户名’
    git config --global user.email ‘邮箱’
  • add 提交到暂存区
  • commit 提交到本地仓库
  • push 上传到远程仓库
  • pull 从远程仓库获取
  • git log --graph --pretty=oneline 查看分支记录
  • branch 查看分支 如果加个分支名就会创建一个分支 ; branch -a 查看远程分支
  • fetch --all 获取远程分支名称到本地
  • checkout 切换分支 ; checkout -b 分支名 这样就会创建并且切换
  • merge 合并分支
  • clone + 地址 克隆一个与远程仓库有关联的文件夹
  • status 查看git的状态
  • reset HEAD^ 回退一个版本
  • git reset --hard 版本id 回退到指定版本
  • remote add origin +地址 与远程仓库创建联系
  • git diff 查看版本的差别

Vue基础知识浅谈_第2张图片

如果前端已经开发完成了,后端接口还没有给到,你是怎么做的

  • 使用mock数据 采用fetchmock创建线上接口

TypeScript

typescript它不是一门新的语言,它是一门用来规范js的语言

js依旧是一门弱类型的语言

ts是js的一个超集,广义的js是es,dom,bom,ts是es的超集

比方说强类型,面对对象的开发体系

ts常用在大型项目中,使得代码更加规范,协作更加友好,维护更加方便

特点:

增加了静态类型检查,增加了代码的健壮性

是编写时报错,js是执行时报错

使得重构更加的安全与便捷

多人协作的时候,提高生产力,降低维护成本

常用的类型

string, number, boolean, any, void, never, Array / string[], 枚举, 元组

string | number,  interface

在vue里面使用ts

类组件,扩展组件, 函数组件

修饰器

服务端渲染

优势:

  更好的SEO 搜索引擎优化

  更快的到达时间

劣势:

  更高的开发要求

  更高的服务器的要求

nuxt.js

vue响应式原理

vue是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的getter,setter,当属性发生改变的时候,将变动发布给订阅者,触发监听回调

由于 JavaScript 的限制,Vue 不能检测数组和对象的变化

vue3.0使用了proxy

浏览器的渲染原理和流程

  1. 浏览器将获取的HTML文档解析成DOM Tree(DOM树)。
  2. 将CSS样式表,解析成CSSOM Tree(CSS树)。
  3. 将DOM和CSSOM合并为渲染树(rendering tree),attachment
  4. 渲染树的每个元素经过精确的计算后,给出坐标,laylout。
  5. 将渲染树的各个节点绘制到屏幕上,painting。

为什么要使用虚拟DOM

  • 虚拟DOM是为了解决浏览器性能问题而被设计出来的。
  • 比如有10次循环,虚拟DOM不会立即操作DOM,而是将10次的diff内容保存在一个js对象里面,然后一次性的操作,避免大量无谓的计算
  • 操作内存中的js对象的速度显然更快,等更新完后,再将最终的js对象映射成真实的DOM,交由浏览器绘制。

diff操作

数据改变,虚拟DOM也会改变

我们不想重新渲染vdom,我们只想渲染改变的部分,就需要用到diff算法

两个树如果完全比较,时间复杂度是O(n^3),Vue的Diff算法的时间复杂度是O(n),意味着只能平层的比较两棵树的节点,放弃了深度遍历。似乎牺牲了一定的精准性来换取速度,但考虑到前端页面通常不会跨层移动DOM元素,这样做是优先的

采用了同级比较,只有count相同的children进行比较

	比较他们的key,进行增加,删除,替换,换位等操作

自定义指令

全局定义:他也可以加修饰符,绑定元素的所有内容,全部在binding里,可以通过判断修饰符的内容进行一些操作

//写法一

Vue.directive(‘focus’, { //定义一个v-focus

        // 当被绑定的元素插入到 DOM 中时……

        inserted: function(el, binding) { //el指的是绑定的元素

            // 聚焦元素

            el.focus()

        }

    })

//全局的第二种写法

    Vue.directive('focus', {

        bind() {},//bind表示当前指令绑定到该元素身上,立刻触发

        // inserted表示绑定的元素已经渲染为真实的dom,并且在页面中已经可以看到

        inserted: function(el) {

            // 聚焦元素

            el.focus()

        }

    })

局部定义,只能在当前组件使用

directives: {

            focus: {

              // 指令的定义

              inserted: function (el) {

                el.focus()

              }

            }

}

你可能感兴趣的:(vue)