Vue知识回顾-零碎知识点

文章目录

        • 1. 传统的 MVP 开发模式与 MVVM 开发模式对比
        • 2. 一些指令以及使用技巧
          • 2.1. Vue 中计算属性的使用技巧
          • 2.2. v-bind 绑定 class 与 内联样式
            • 2.2.1. v-bind 绑定 class
            • 2.2.2. 绑定内联样式
          • 2.3. v-if 与 v-else 标签必须要连在一起使用,不然会抛出错误。
          • 2.4. key 值
          • 2.5. v-for 循环
          • 2.6. Vue 中操作数组
          • 2.7. template 模板占位符
          • 2.8. Vue 中遍历对象进行渲染以及对根级别响应式对象添加属性
          • 2.9. 对于数组的 set 方法
          • 2.10 v-text 与 v-html
        • 3. 组件的一些知识
          • 3.1. is属性
          • 3.2 . 子组件中 data
          • 3.3. 组件中操作 DOM
          • 3.4. 组件之间的通讯
            • 3.4.1 子组件向父组件派发事件
            • 3.4.2 父组件向子组件传递
          • 3.5 组件绑定原生事件
          • 3.6. 非父子组件传值( Bus 总线/发布订阅模式/观察者模式)
          • 3.7. 插槽相关知识
          • 3.8. 动态组件
          • 3.9. vue 中的动画
          • 3.11. 非 Props 特性
          • 3.12. 组件中替换/合并已有的特性
          • 3.13. 组件的禁用特性继承
        • 4. vue-cli 以及 vue-router
          • 4.1. Javascript 中 Promise 对象与 callbacks 的区别
          • 4.2. vue-cli 知识
          • 4.3. 项目中一些技巧
            • 4.3.1. import 引入 css
            • 4.3.2. 移动端 Click 事件延迟执行
            • 4.3.3. vue-cl项目中配置路径别名
            • 4.3.4. vue-cl项目中使用 stylus
            • 4.3.5. 移动端像素问题
        • 5. 项目开发中的一些知识
          • 5.1. 开发流程
          • 5.2. vue 第三方轮播图插件 vue-awesome-swiper
          • 5.3. 浏览器的小技巧模拟网络
          • 5.4. css 代码技巧
            • 5.4.1. 宽高保持一定的百分比
            • 5.4.2. 修改第三方插件样式
            • 5.4.3. div 元素垂直居中
            • 5.4.4. 移动端获取元素离顶部元素真实高度
          • 5.5. vue-cli 项目中的静态资源访问以及代码提交配置
          • 5.6. 项目接口的转接
          • 5.7. Math 对象的一些方法
          • 5.8. CSS 的 rem 以及 vm
          • 5.9. Better-scroll 插件
          • 5.10. 防抖节流的例子
          • 5.11. touch 事件与 click 事件的冲突
          • 5.12. 解决手机不支持 es6 新特性
        • 6. vuex 知识
          • 6.1. vuex 的使用
          • 6.2. 页面之间跳转
          • 6.3. 访问 vuex 数据技巧
            • 6.3.1. 组件中访问state数据
            • 6.3.2. mapState 辅助函数
            • 6.3.3. 使用常量替代 Mutation 事件类型
          • 6.4. vuex 中的 getters 属性
          • 6.5. 使用 keep-alive 优化性能
          • 6.6. router-link 一些知识
            • 6.6.1. tag 属性
            • 6.6.2. 返回到前一页
          • 6.7. \ 一些知识点
          • 6.8. vuex 中的插件
          • 6.8. 严格模式
        • 7. vue-router 知识点
          • 7.1. 路由中参数的传递
          • 7.2 组件中 name 的用法总结
            • 7.2.1. 去除缓存
            • 7.2.2. 清除页面滚动
            • 7.2.3. 组件的递归
          • 7.3. 响应路由参数的变化
          • 7.4. 路由中传递参数
          • 7.5. 命名路由
          • 7.6. 命名视图
          • 7.7. 组建内的守卫
          • 7.8.完整的导航解析流程
        • 8. 项目上线准备
          • 8.1. API 接口的替换
          • 8.2. 移动端项目真机调试
          • 8.3. 项目打包
        • 9. vue 学习路线
        • 10. 其他

1. 传统的 MVP 开发模式与 MVVM 开发模式对比

  1. 对于传统的mvp开发模式,m也就是model一般是通过发送ajax请求获取到的数据,v也就是视图,p就是Presenter相当于控制器,
    Presenter作为View和Model之间的“中间人”,除了基本的业务逻辑外,还有大量代码需要对从ViewModel和从ModelView的数据进行“手动同步”,这样Presenter显得很重,维护起来会比较困难。而且由于没有数据绑定,如果Presenter对视图渲染的需求增多,它不得不过多关注特定的视图,一旦视图需求发生改变,Presenter也需要改动,我们大部分的关注点是在视图与数据,以及通过控制器进行操作。
  2. 对于vue的开发模式mvvm,他把ViewModel的同步逻辑自动化了,与MVP不同,没有了ViewPresenter提供的接口,之前由Presenter负责的ViewModel之间的数据同步交给了ViewModel中的数据绑定进行处理,当Model发生变化,ViewModel就会自动更新;ViewModel变化,Model也会更新。我们的关注点主要是在modelview之间,而model发生变化,view进行同步更新,这些都交给了viewmodelmvp的模式我们大部分的关注点是在操作了dom,提高了开发效率。

2. 一些指令以及使用技巧

2.1. Vue 中计算属性的使用技巧

get、set;如果是获取数值,通过get获取到值,也可以通过set函数设置值,注意如果你为一个计算属性使用了箭头函数,则 this 不会指向这个组件的实例,不过可以通过其实例作为函数的第一个参数来访问:

computed: {
  aDouble: vm => vm.a * 2
}

get、set用法:

var vm = new Vue({
  data: { a: 1 },
  computed: {
    // 仅读取
    aDouble: function () {
      return this.a * 2
    },
    // 读取和设置
    aPlus: {
      get: function () {
        return this.a + 1
      },
      set: function (v) {
        this.a = v - 1
      }
    }
  }
})
vm.aPlus   // => 2
vm.aPlus = 3
vm.a       // => 2
vm.aDouble // => 4

计算属性的结果会被缓存,除非依赖的变量变化才会重新计算。注意,如果某个依赖 (比如非响应式属性) 在该实例范畴之外,则计算属性是不会被更新的。 我们一般如果处理数据显示,如果声明函数、计算属性、侦听器这三者都可以实现的话,一般建议使用计算数据,因为存在缓存机制。

计算属性设置值的时候直接使用=,如上面的aPlus数值,而不是与函数类似进行赋值。

aPlus = 10
2.2. v-bind 绑定 class 与 内联样式
2.2.1. v-bind 绑定 class

v-bind中,绑定class,使用:class="{active:isActive}",前面的active如果没有在data中定义是不会报错的,他是一个对象表达式,意思就是active这个类的显示与否都在于isActive这个变量,该变量为布尔类型,为true为显示,为false是不显示。

<div
  class="static"
  v-bind:class="{ active: isActive, 'text-danger': hasError }"
>div>

data

data: {
  isActive: true,
  hasError: false
}

渲染的结果:如果hasError的值为trueclass 列表将变为"static active text-danger"

<div class="static active">div>

而如果使用:class="[chextType, active ]",这样chextType这个必须在data中定义。div显示的类名就是显示chextType、active变量中存储的类名。另外他也可以与普通的 class共存

<div v-bind:class="[activeClass, errorClass]">div>

data

data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

渲染的结果:如果hasError的值为trueclass 列表将变为"static active text-danger"

<div class="active text-danger">div>

这样写将始终添加errorClass,但是只有在isActivetrue时才添加 activeClass。不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法:

<div v-bind:class="[{ active: isActive }, errorClass]">div>

当在一个自定义组件上使用 class属性时,这些类将被添加到该组件的根元素上面。这个元素上已经存在的类不会被覆盖。
例如,如果你声明了这个组件:

Vue.component('my-component', {
  template: '

Hi

'
})

然后在使用它的时候添加一些 class

<my-component class="baz boo">my-component>

HTML 将被渲染为:

<p class="foo bar baz boo">Hip>

对于带数据绑定的class跟前面是一样的。

2.2.2. 绑定内联样式

对象语法:
v-bind:style 的对象语法十分直观——看着非常像CSS,但其实是一个 JavaScript 对象。CSS属性名可以用驼峰式 或短横线分隔 (记得用引号括起来) 来命名:

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">div>
data: {
  activeColor: 'red',
  fontSize: 30
}

直接绑定到一个样式对象通常更好,这会让模板更清晰:同样的,对象语法常常结合返回对象的计算属性使用。

<div v-bind:style="styleObject">div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

数组语法:
v-bind:style的数组语法可以将多个样式对象应用到同一个元素上:

<div v-bind:style="[baseStyles, overridingStyles]">div>

自动添加前缀:
v-bind:style 使用需要添加浏览器引擎前缀的 CSS属性时,如transformVue.js 会自动侦测并添加相应的前缀。

2.3. v-if 与 v-else 标签必须要连在一起使用,不然会抛出错误。
2.4. key 值

Vue在重新渲染页面的时候,会尝试复用页面里面的dom元素,如果页面有两个相同的标签可以添加一个key,这样,vue会区分,不会复用。

2.5. v-for 循环

一般在v-for循环的时候,一般建议加一个:key值,绑定一个唯一的标识,不建议直接绑定循环的index,会消耗性能,建议绑定后台传入的数据的主键。

2.6. Vue 中操作数组

Vue中,不能直接通过数组下标的方法,进行添加数据,这样页面不会渲染的,需要通过数据的操作函数进行增删改查:push、pop、shift、unshift、splice、sort、reverse

2.7. template 模板占位符

template模板占位符,比如我们使用v-for要循环两个标签,可以在两个标签外层加一个div,但是这个div会在页面显示出来,我们可以把外层的div换成template,不会显示在页面。

2.8. Vue 中遍历对象进行渲染以及对根级别响应式对象添加属性

对象的循环:key是,键;index是位置信息,item是值;

<div v-for="(value, name, index) in object">
  {{ index }}. {{ name }}: {{ value }}
div>

渲染结果:

<div id="v-for-object-value-name-index" class="demo"><div>
    0. title: How to do lists in Vue
  div><div>
    1. author: Jane Doe
  div><div>
    2. publishedAt: 2016-04-10
  div>div>

给对象直接修改属性是可以再次进行渲染。
给对象直接添加值,是不变的,可以直接改变引用,换成一个全新的对象,也可以使用set方法,Vue.set(vm.userInfo,"address","wuhan")这样,userInfo对象会增加数据,页面也会变动,重新渲染。也可以使用实例的$set方法vm.$set(vm.userInfo,"address","wuhan")
对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value)方法向嵌套对象添加响应式属性。

2.9. 对于数组的 set 方法

对于数组的set方法。Vue.set(vm.userInfo,4,5),将第四个位置的数据改成5,也可以用实例vm.$set(vm.userInfo,4,5),所以改变数组的值有两种方法,第一个是使用js的数组操作函数,另一个是使用vueset方法、

2.10 v-text 与 v-html

这两个指令旨在显示数值,跟我们直接在html中使用插值表达式类似:

<div>{{message}}div>

v-text显示的结果与插值表达式一致的,而v-html会展示为html,如果字符串是一个html的字符串,他会进行渲染显示。

3. 组件的一些知识

3.1. is属性

有些 HTML 元素,诸如

      ,只能出现在其它某些特定的元素内部。比如tbody里只能显示tr,我们希望在tr里放其他的内容,可以借助is属性:

      <table>
        <blog-post-row>blog-post-row>
      table>
      

      这个自定义组件 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is 特性给了我们一个变通的办法:

      <table>
        <tr is="blog-post-row">tr>
      table>
      

      这句代码就是说,我们在tbody是显示tr,其实是is里面的组件;遇到组件上的小bug,可以使用is进行解决;比如ol、select等等。

      3.2 . 子组件中 data

      子组件中data为函数;是为了保证每一个组件中的数据互不干扰;

      3.3. 组件中操作 DOM

      ref:引用 ,被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs对象上。如果在普通的DOM元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例:

      
      <p ref="p">hellop>
      
      
      <child-component ref="child">child-component>
      

      获取dom节点,通过this.$refs.ref的值这样获取dom节点;比如上面的结构,如果需要获取this.$refs.child就会获取到对应的dom信息。
      当 v-for 用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组。
      关于 ref 注册时间的重要说明:因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在!$refs 也不是响应式的,因此你不应该试图用它在模板中做数据绑定。

      3.4. 组件之间的通讯
      3.4.1 子组件向父组件派发事件

      使用this.$emit('change');在父组件触发change事件。@change="handleChange";父组件的change事件执行handleChange方法。

      3.4.2 父组件向子组件传递

      父组件向子组件传递是通过属性,用v-bind进行绑定,子组件尽量不要修改父组件传进来的参数,可以使用data复制一份传入的值;
      对于组件参数的校验,直接在props,接收的时候,为一个对象,type为类型,default为默认值,required为设置参数是否必须,validator(value){return (value.length>5)}传入的值必须大于五;

      Vue.component('my-component', {
        props: {
          // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
          propA: Number,
          // 多个可能的类型
          propB: [String, Number],
          // 必填的字符串
          propC: {
            type: String,
            required: true
          },
          // 带有默认值的数字
          propD: {
            type: Number,
            default: 100
          },
          // 带有默认值的对象
          propE: {
            type: Object,
            // 对象或数组默认值必须从一个工厂函数获取
            default: function () {
              return { message: 'hello' }
            }
          },
          // 自定义验证函数
          propF: {
            validator: function (value) {
              // 这个值必须匹配下列字符串中的一个
              return ['success', 'warning', 'danger'].indexOf(value) !== -1
            }
          }
        }
      })
      

      还是需要注意的是v-bind绑定的属性后面是一个对象,直接跟class一样绑定属性,为字符串;props传递的属性,在dom渲染出来的HTML上不会显示出来。

      3.5 组件绑定原生事件

      给父组件绑定事件,其实是一个自定义事件,想要给组件绑定事件,需要在template里面进行绑定。子组件想要触发自定义事件,需要使用this.$emit('chandleClick');如果想在父组件添加事件,需要添加native事件修饰符:@click.native="handleClick";

      这里在子组件向父组件传值定义事件名的时候需要注意,不同于组件和 prop,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。所以如果我们定义了一个this.$emit('myEvent'),然后在父组件监听的时候:使用短横行的方式去监听,是监听不到的,因为不同于组件和prop,事件名不会被用作一个 JavaScript 变量名或属性名,所以就没有理由使用 camelCasePascalCase 了。并且v-on事件监听器在DOM模板中会被自动转换为全小写 (因为 HTML是大小写不敏感的),所以v-on:myEvent将会变成 v-on:myevent——导致 myEvent不可能被监听到。
      所以推荐我们一般使用短横线的方式去命名。

      3.6. 非父子组件传值( Bus 总线/发布订阅模式/观察者模式)
      Vue.prototype.bus = new Vue();
      //子组件触发事件
      this.bus.$emit('change',this.value)//来触发事件;然后组件进行监听:
      //在父组件的mounted中去监听子组件触发的事件
      mounted(){
        this.bus.$on('change',function(msg)
          {
            //...
          }
      );
      
      3.7. 插槽相关知识

      slot插槽中,如果在父组件中不进行插入dom,在子组件的默认内容,里面的字会显示出来,自定义的内容放在中间,如果父组件有数据,则不会显示;具名插槽也可以有默认内容。
      具名插槽:
      有时我们需要多个插槽。例如对于一个带有如下模板的 组件:

      <div class="container">
        <header>
          
        header>
        <main>
          
        main>
        <footer>
          
        footer>
      div>
      

      对于这样的情况,元素有一个特殊的特性:name。这个特性可以用来定义额外的插槽:

      <div class="container">
        <header>
          <slot name="header">slot>
        header>
        <main>
          <slot>slot>
        main>
        <footer>
          <slot name="footer">slot>
        footer>
      div>
      

      一个不带name出口会带有隐含的名字“default”
      在向具名插槽提供内容的时候,我们可以在一个