尚硅谷Vue2-3, 学习笔记

(一) 基本模块

01基础模板语法

1.1插值语法 -- 解析标签体里的内容

data -> {{}} 里可以写js表达式,或者js语句 : 通过{{}}在标签体里插入data里面的数据

  
{{}}
//{{}}:插值语法 - vue模板

1.2指令语法 -- 解析标签 数据绑定 条件渲染

1.2.1**v-bind:xxx **

简写 -> : xxx 一般用于解析标签属性,经过解析后 值也要写成js表达式,

    **v-bind:为单向数据绑定 ,数据只能从data流向页面**
  
{{school.age}}
// : 指令语法 - v-bind简写

v-bind:动态绑定样式

1.2.2v-model:xxx

**为双向数据绑定,数据可以在页面与data中双向流动,但是一般用于表单类元素上(如:inport, select等) **

  • **在获取表单数据时, v-model会获取value值 **

    **对于一般的文本框, 则输入的内容就是value的值 **

    **对于单选 则要设置要获取的value值 **

    对于多选框 设置要获取的value后还要把v-model绑定的数据写成数组的形式

  • 修饰符

    v-model.number 使输入的数据类型转换成 Number类型

    v-model.lazy 时输入的数据在失去焦点后, 才会被收集

    v-model.trim 去掉前后的空格

1.2.3**v-on:xxx **

简写 -> @xxx 用于绑定事件, 事件的回调要配置在methods中最终会在Vue实例(vm)上,存放在data里的数据才会有数据劫持数据代理 ,@click='showInfo(event)' 使用/占位符,可以传递even参数

  

{{name}}

{{address}}

1.2.4事件的修饰符:

Vue中的事件修饰符:

1.prevent:阻止默认事件(常用);

**2.stop:阻止事件冒泡(常用); **

3.once:事件只触发一次(常用)

4.capture:使用事件的捕获模式,在事件捕获阶段进行处理;

5.self:只有event.target是当前操作的元素时才触发事件;

6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

在绑定事件的后面添加

点我提示信息

修饰符可以连用

1.2.5键盘事件:

1.Vue中常用的按键别名:

   回车 => enter

   删除 => delete (捕获“删除”和“退格”键)

   退出 => esc

   空格 => space

   换行 => tab (特殊,必须配合keydown去使用)

   上 => up

   下 => down

   左 => left

   右 => right

2.系统修饰键(用法特殊):ctrl、alt、shift、meta

   (1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。

   (2).配合keydown使用:正常触发事件。

4.也可以使用 keyCode去指定具体的按键 编码(不推荐,以后可能会移除)

5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名

Vue.config.keyCodes.huiche = 13 //定义了一个别名按键

1.2.6 v-if/v-else-if

写法: v-if=‘表达试’ , 功能与js中的一样, 适用于切换频率比较低的场景, 不展示的DOM元素会直接别移除, 且与v-else-if 结合使用时中间不能添加其他元素, 否则结构会被打断

1.2.7 v-show

写法: v-show=‘表达式’, 适用于切换频率比较低的场景, 不展示的DOM元素会不会被移出,而是使用样式进行隐藏,

vue3中v-if 比 v-show 的优先级要高, 但使用v-if时, 元素可能会获取不到, 而使用v-show时则一定会获取到

1.2.8 v-for

v-for用于展示列表数据

语法: v-for=“(item, index) in xxx “ :key=”yyy”

可以遍历: 数组, 对象, 字符串, 指定遍历次数

1.2.9 其他不常用的内置指令

  • v-text v-html

与差值语法类似,但 v-text不能解析 标签, v-html可以解析 结构标签转成字符串, 但会造成xss(跨域脚本攻击)漏洞

  • v-cloak

为使用该指令的标签 提供一个遮罩, 在Vue实例创建完成,并接管容器后, 会删除v-cloak

使用css的display:none属性, 配合v-cloak解决网速过慢时页面展示出 {{xxx}} 的问题, 防止页面闪烁

  • v-once v-pre

v-once: 所在节点模板只 动态渲染 一次,然后视为静态渲染, 可以优化性能,

v-pre: 跳过所在节点的编译过程, 可用于不使用插值语法,指令语法 的节点, 会加快编译

1.2.10 自定义指令

见1.3.6

1.3Vue实例里的配置项

1.3.1 el [element(元素)]

el:'xxx' 用于挂载当前vue实例指定的容器,值一般为css的选择器字符串,

本质是调用了vue实例里的$mount属性

const vm = new Vue({
  el:'#root'
})
vm.$mount('root')

1.3.2 data

data 用于定义属性(属性名+属性值)

const vm = new Vue({
  el:'#root',
  //对象方法,一般用法
  data: {
      name: '张三'
  },
  //函数方法,用于组件,使函数的this指向Vue实例
  data() {
      name: '张三'
  }
})

1.3.3 methods

methods 方法,主要用于定义 绑定事件的 方法

{{name}}

{{address}}

methods定义的方法也可以在插值语法{{}},中使用 当data里的数据发生改变则vue会对模板进行重新解析,当解析到定义的函数时,进行调用

1.3.4 computed

computed 计算属性:

 1.定义:要用的属性不存在,要通过已有属性计算得来。

 2.原理:底层借助了`Objcet.defineproperty`方法提供的getter和setter。

 3.get函数什么时候执行?

    (1).初次读取时会执行一次。

    (2).当依赖的数据发生改变时会被再次调用。

 4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。

 5.备注:

   1.计算属性最终会出现在vm上,直接读取使用即可。

   2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。

   3.==注意: computed里不能写异步任务==

1.3.5 watch

监视属性watch:

 `immediate:true` 在初始化时就进行调用

 `handler(新值,旧值){  }`

 1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作

 2.监视的属性必须存在,才能进行监视!!

 3.监视的两种写法:

   (1).new Vue时传入watch配置

   (2).通过vm.$watch监视

 4.`deep:true` 开启深度监视, 要写成完整形式

1.3.6 directives

  • 用于自定义指令
    

放大10倍后的n值是:

new Vue({ el:'#root', data:{ name:'尚硅谷', n:1 }, //定义全局指令 yyy是对象形式, 如果配置函数形式的全局,则使用回调函数 Vue.directive('yyy',{ //注意在定义全局时, 是directive 不是 directives //指令与元素成功绑定时(一上来) bind(element,binding){ element.value = binding.value }, //指令所在元素被插入页面时 inserted(element,binding){ element.focus() }, //指令所在的模板被重新解析时 update(element,binding){ element.value = binding.value } }) directives: { //xxx函数合适会被调用? 1,指令与元素绑定成功时 2,指令所在的模板被重新解析时 //函数形式, 适合简单的操作 xxx(element, binding) { //element:绑定v-xxx所在的元素(span) binnding:绑定v-xxx所在的值(n) console.log(this) // 此处的this是指向window }, //对象形式, 适合一些细节上的操作 yyy: { } } })

(1).局部指令:

new Vue ({ directives:{指令名:配置对象} })

new Vue ({ directives{指令名:回调函数} )}

(2).全局指令:

Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数)

1.3.7 mounted

Vue完成模板的解析并把初始的, 真实DOM元素放入页面后(挂载完毕)调用mounted(回调函数)

02MVVM模型

01.png

02.png
  • 模板(view)通过 --> Vue实例对象 --> 监听对应data中的数据(model)

  • data中的数据(model)通过 --> Vue实例对象 --> 绑定模板(view)

  1. data中的所有属性,最后都会出现在vm身上
  2. vm身上所有的数据, 及Vue原型身上所有的属性, 在Vue模板中都可以直接使用

==03数据代理==

    

数据代理 -- 通过一个对象代理对另一个对象中属性的操作(读/写)

        

使用数据代理可以 通过obj2.x来操作obj.x的值得变化

03.png

通过vm对象来代理data对象中的属性操作(读/写),更方便的data中的数据,通Object.defineProperty()把data对象中所有属性添加到vm上, 并为每个添加上的属性都指定一个 getter/setter 来操作(读/写)data中的对应属性 如果不做数据处理 则 在使用插值语法 插入data中的数据时 要这样{{ _data.name }} {{ _data.adderss }}插入

04监视数据原理

**Vue监视数据的原理: **

1.vue会监视data中所有层次的数据。

2.如何监测对象中的数据?

    通过setter实现监视,且要在new Vue时就传入要监测的数据。

     (1).对象中后追加的属性,Vue默认不做响应式处理

     (2).如需给后添加的属性做响应式,请使用如下API:

         Vue.set(target,propertyName/index,value) 或 

         vm.$set(target,propertyName/index,value)

3.如何监测数组中的数据?

04.png
     通过包裹数组更新元素的方法实现,本质就是做了两件事:

      (1).调用原生对应的方法对数组进行更新。

      (2).重新解析模板,进而更新页面。

4.在Vue修改数组中的某个元素一定要用如下方法

   1.使用这些API:   push()、pop()、shift()、unshift()、splice()、sort()、reverse()

   2.Vue.set() 或 vm.$set()

特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性!!!

==05Vue的生命周期==

生命周期:

  1.又名:**生命周期回调函数**、生命周期函数、**生命周期钩子**。

  2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。

  3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。

  4.生命周期函数中的this指向是vm 或 组件实例对象。
生命周期.png

常用的生命周期钩子:

  1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等**【初始化操作】**。

  2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等**【收尾工作】**。

**关于销毁Vue实例**

  1.销毁后借助Vue开发者工具看不到任何信息。

  2.销毁后自定义事件会失效,但原生DOM事件依然有效。

  3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。

(二)组件化模块

01 组件基本使用

定义: 实现应用中局部功能 代码 和资源的 集合

Vue中使用组件的三大步骤:

 一、定义组件(创建组件)

 二、注册组件

 三、使用组件(写组件标签)

一、如何定义一个组件?

  使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;

  区别如下:

    1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。

    2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系(this指向)。

  备注:使用template可以配置组件结构。

二、如何注册组件?

   1.局部注册:靠new Vue的时候传入components选项

   2.全局注册:靠Vue.component('组件名',组件)

三、编写组件标签

   ``

        
//全局组件标签

==02关于VueComponent:==

  1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。

  **2.我们只需要写``或``,Vue解析时会帮我们创建(new 了一个)school组件的实例对象,即Vue帮我们执行的:new VueComponent(options), 当然你也可以自己new一个。**

  **3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!**

  4.关于this指向:

    (1).组件配置中:

       data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。

    (2).new Vue(options)配置中:

       data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。

==03对象原型==

对象原型.png

Vue构造函数的属性中存在一个prototype属性, 值为一个对象, this指向他的 原型对象. 这个指向也叫作做 ==显式原型链==. 当new一个Vue的实例对象时,他的属性中存在一个__proto__属性, 值为一个对象, this也指向Vue原型对象, 这个指向也叫作,==隐式原型链==. 而Vue的原型对象属性里也会在一个__proto__属性, this指向Object的原型对象, 他的属性中也存在一个__proto__属性, this指向为null

VueComponent构造函数的属性中存在一个prototype属性, 值为一个对象, this指向他的 原型对象. 这个指向也叫作做 ==显式原型链==. 当编写一个组件标签时(或者new一个VueComponent的实例对象)时,他的属性中存在一个__proto__属性, 值为一个对象, this也指向VueComponent原型对象, 这个指向也叫作,==隐式原型链==. 而VueComponent的原型对象属性里也会在一个__proto__属性, (原本的this指向应该指向Object的原型对象, ), 但是在Vue中, Vue把这条==隐式原型链==, 指向了Vue的原型对象, 即:

==VueComponent.prototype.__proto__ === Vue.prototype== , 从而使组件实例对象可以访问到Vue原型上的属性和 方法

04render()函数

关于不同版本的Vue:

1.vue.js与vue.runtime.xxx.js的区别:

(1).vue.js是完整版的Vue,包含:核心功能+模板解析器。

(2).vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。

2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用 render函数接收到的 ceateElement函数去指定具体内容。

new Vue({
    el:'#app',
    //render函数完成了这个功能:将App组件放入容器中
  render: h => h(App),
    // render:q=> q('h1','你好啊')
    // template:`

你好啊

`, // components:{App}, })

(二)脚手架

01 文件目录结构

├── node_modules 
├── public
│   ├── favicon.ico: 页签图标
│   └── index.html: 主页面
├── src
│   ├── assets: 存放静态资源
│   │   └── logo.png
│   │── component: 存放组件
│   │   └── HelloWorld.vue
│   │── App.vue: 汇总所有组件
│   │── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件 
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件

02 vue.config.js配置文件

  1. 使用vue inspect > output.js可以查看到Vue脚手架的默认配置。
  2. 使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh

03 ref属性

  1. 被用来给元素或子组件注册引用信息(id的替代者)
  2. 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
  3. 使用方式:
    1. 打标识:

      .....

    2. 获取:this.$refs.xxx

04 props配置项

  1. 功能:让组件接收外部传过来的数据

  2. 传递数据: 父组件 ===> 子组件

  3. 接收数据:

    1. 第一种方式(只接收):props:['name']

    2. 第二种方式(限制类型):props:{name:String}

    3. 第三种方式(限制类型、限制必要性、指定默认值):

      props:{
        name:{
        type:String, //类型
        required:true, //必要性
        default:'老王' //默认值
        }
      }
      

    备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。

05 mixin(混入)

  1. 功能:可以把多个组件共用的配置提取成一个混入对象

  2. 使用方式:

    第一步定义混合:

    {
        data(){....},
        methods:{....}
        ....
    }
    

    第二步使用混入:

    全局混入:Vue.mixin(xxx)
    局部混入:mixins:['xxx']

06 插件

  1. 功能:用于增强Vue

  2. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。

  3. 定义插件:

    对象.install = function (Vue, options) {
        // 1. 添加全局过滤器
        Vue.filter(....)
        // 2. 添加全局指令
        Vue.directive(....)
        // 3. 配置全局混入(合)
        Vue.mixin(....)
        // 4. 添加实例方法
        Vue.prototype.$myMethod = function () {...}
        Vue.prototype.$myProperty = xxxx
    }
    
  4. 使用插件:Vue.use()

05 scoped样式

  1. 作用:让样式在局部生效,防止冲突。
  2. 写法: