笔记——Vue的慕课学习

Vue的三大特点:

1、响应式(双向绑定)
2、组件化(模块化)
3、单文件组件(.vue)
- 将js(即功能)、css(即样式)、html(即模板)存在于一个文件内
- 得益于这些来解读成浏览器能识别的文件:Webpack + vue-loader
- 好处1:style的作用域
- 好处2:预加载器(在template、style中的lang属性)

单页面

也就是路由跳转时不会强制刷新

组件的实例选项data避免引用赋值

如果实例化组件时,用的是data对象,那所有用的都是同一份data
解决方案:

data () {
    return {
        // ...属性
    }
}

Vue基本概念:

1、全局Api
- Vue.component、Vue.extends等等
2、实例选项
- 在创建一个Vue实例对象是可以使用的功能性项目
vm.$options 可以获取这个组件的实例选项
3、实例属性、方法
- 把创建的那个Vue实例对象赋值给一个变量,该变量的属性、方法(一般有$)
4、指令
- 写在模板里面,例如v-html
5、内置组件

<component :is="组件名">component>
<transition>transition>
<keppl-alive>keep-alive>
<slot>slot>

watch对象里面 监听的数组何时监听到改变?

也是要等到$set这样的响应式更新才可以监听到改变

调用子组件时,语法的好习惯

1、kebab-case(短横线分割)

即全部改成小写,且在 转换处的字母前 加个-(首字母除外)

(1) 定义 子组件名
(2) 调用 子组件
(3) 使用 标签属性 (包括 v-on:)、
(4) is的属性值、
(5) 发射 emit事件

2、使用 驼峰写法
(1) 引用 js变量 双向绑定
(2) 在props

例如: 
在注册 子组件 时,
components: {
    ComAHasChild
}
在<template>中引入 子组件 时,
<com-a-has-child></com-a-has-child>
// 或者:
// 

为何事件名需要用kebab-case

因为事件名不会被用作一个JavaScript变量名或属性名,所以就没有理由使用camelCase(小驼峰)或PascalCase(大驼峰)了。并且 v-on 事件监听器在DOM模板中会被自动转换为全小写(因为HTML是大小写不敏感的),所 v-on:myEvent 将会变成 v-on:myevent —— 导致 myEvent 不可能被监听到。

所以,推荐使用 kebab-case (短横线分割)事件名

is属性可以实现 组件的动态引入

父子组件通信

笔记——Vue的慕课学习_第1张图片

props

2种方式来定义props对象

// 1、数组
props: ['number-to-do', 'valueFromDad']

// 2、对象
props: {
    // 单个类型
    'numberToDo': Number,
    // 多个类型
    'valueFromDad': [Number, String],
    // 任何类型
    'anyType': null,
    // 必填字符串
    'requireString': {
        type: 'String',
        required: true
    },
    // 默认值数字
    'defaultNum': {
        type: Number,
        default: 100
    },
    // 默认值对象也可以(自行查官方文档)
    // 自定义验证函数
    'myValid': {
        validator (value) {
            // 该值要是下列字符串中的其中一个。
            // return 的东西,也就是为 当这个条件true时,能够验证成功的意思
            return [ 'success', 'warning' ].indexOf(value) !== -1
        }
    }
}

// 无论如何,在HTML属性里,父组件传的都是字符串
// 例如:

// 除非在传值之前,加个v-bind // 例如:

// 例如:

注意!
这些prop的验证是在 组件实例创建之前 就开始验证。所以,实例的属性,如data、computed等,在 default 或 validator 函数中是不可用的。

不注册prop

称为 “非Prop的特性”

  • 如果在子组件中不注册相应的prop的话,父组件传过来的这个属性 将会 直接写到 到 子组件 的根元素上!(父组件也仅仅只是“单相思”)
  • 如果子组件不希望 这些特性 加到自己的根元素上,那它的实例选项添加如下即可:
  • -
inheritAttrs: false // 禁用特性继承

// 默认情况下父作用域的不被认作 props 的特性绑定 (attribute bindings) 将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。
  • 同时子组件可以通过 $attrs 来操作这些 从父组件传递过来的,且没有注册prop 的特性 (不管 inheritAttrs 为何值,都存在这些 没注册过的特性)
    这里写图片描述

$attrs 类似的 $listeners

上面说到,$attrs 是一个对象,它存着由父组件传给子组件的、没有在子组件里prop的“特性”(即没有prop的标签属性)
那如果组件A -> 组件B -> 组件C,这样组件C如何触发组件A的方法呢?
解决方法:$listeners
它存储的是,在父组件(即组件A)中,给第一个(即组件B)定义的所有方法的集合,如:

// 组件A:
 <comp-b
 @test1="onTest1" //此处监听了两个事件,可以在B组件或者C组件中直接触发
 @test2="onTest2"> 
 </comp-b>
 // 则是事件test1、test2

// 组件B:
<comp-c v-bind="$attrs" v-on="$listeners"></comp-c>
// 通过v-bind="$attrs",即可向组件C传递那些从组件A给组件B的、且在B中没有prop的特征
// 通过v-on="$listeners",即可向组件C传递那些从组件A给组件B定义的事件,如test1、test2

// 组件C:
mounted () {
    this.$emit('test1'); // 即可触发父组件的test1事件来执行OnTest1方法,多亏了组件B向组件C传递了$listeners
}

这样的缩写是,prop中, 传入一个对象的所有属性 的写法

有关 $listeners 的例子:http://www.jb51.net/article/132371.htm

任何类型的值都可以传给一个prop


// 传数字
<blog-post :count="42">blog-post>

// 传布尔值(prop没有值,默认true)
<blog-post favorited>blog-post>
<blog-post :facorited="false">blog-post>

// 传数组、对象同理,加个v-bind就好

改变prop的解决方法

Vue一般防止子组件改变父组件的状态,所以不应该在子组件内部改变prop

【只改子组件,不改父组件】
(1)data。(方便子组件改)

  • 在子组件定义一个本地 data 属性,并将这个 prop 用作其初始值。以后修改本地的 data 就好了
props: [ 'initialCounter' ],
data () {
    return {
        counter: this.initialCounter
    }
}

(2)computed。
- 这种“改变”不太灵活,只能 “听父由命”,自己在子组件想改这个 prop属性 ,只能在 return 前修改一下返回的逻辑

props: [ 'size' ],
computed: {
    normalizedSize () {
        return this.size.trim().toLowerCase()
    }
} 

注意:对于一个数组或对象的prop来说,在子组件的改变会影响到父组件的状态

【改子组件,又改父组件】
(3).sync。
- sync修饰符的功能是:当一个子组件改变了prop值,这个变化也同步到父组件中所绑定。

"bar">
// 等价于:
"bar"
      @update:foo="val => bar = val">

// 同样地,子组件也要在props中注册
props: [ 'foo' ]

// 当子组件需要更新foo时,它需要显式地触发一个更新事件:
this.$emit('update:foo', newVal);// 这里的newVal指的是新值

// 这样做的结果,子组件中foo的prop更新了,父组件的bar也更新了

出处:https://www.jianshu.com/p/6b062af8cf01

.native

给普通的HTML标签监听一个事件,之后添加 .native 修饰符是 不起作用的

<button @click.native="say"> 按我 button>
// 无用

因为他是给某个组件的根元素上,监听一个事件的

<my-comp-a @click.native="saySomething"></my-comp-a>

// my-comp-a.vue:
Vue.component('my-comp-a', {
    template: ``
})

// 这样做的结果,就是在子组件的根元素 button ,添加了一个事件,这个事件是用来触发在父组件中的 saySomething 方法的

过渡效果

CSS阶段类名

笔记——Vue的慕课学习_第2张图片

// 写一个淡入淡出
<transition name="fade">
    <p> text </p>
</transtion>

// css (.fade-leave不动,因为就是在那个位置)
.fade-enter-active, .fade-leave-active {
    transition: opacity .5s ease-out; /* 第一个参数是要啥属性过渡 */
}

.fade-enter, fade-leave-active {
    opacity: 0;
}

多元素(或多组件)过渡

可以给 mode 来规定时间序列:

  • mode=”in-out” // 默认,(新)先进,(旧)后出
  • mode=”out-in” // 先出后进
    注意:因为vue 通常会复用已有元素(如同一种HTML标签),而不会重新渲染!
    所以这样的情况下需要加个 key
<transtion name="fade" mode="out-in">
    <p v-if="show" key="1"> I am show p>
    <p v-else key="2"> Not in show p>
transition>

JS实现过渡

  • 比CSS要丰富,但一般要引入第三方库,如JQuery

各种钩子事件:
before-enter、before-leave、before-appear
enter、leave、appear
after-enter、after-leave、after-appear
enter-cancelled、leave-cancelled、appear-cancelled

公用库可以放index.html

直接用

你可能感兴趣的:(红本本)