[TOC]

Vue.js安装

  1. 下载到本地, 在项目文件中直接引入
  2. NPM安装

Vue的渐进式

简单使用

  1. 在项目中引入

    <script type="text/javascript" src="js/vue.js"></script>
    
  2. 建立基本元素

    1. v-for进行循环遍历显示
    2. 当代码加载到这一个代码块,还未执行第三个代码块时,页面上显示的还是原有东西{{message}},只有当它加载了Vue对象,就会把页面当中的东西替换掉。
      <div id="app">{{message}}
      <div>{{s1}}</div>
      <ul>
        <!-- 遍历movies  创建li  写入数据 -->
        <li v-for="item in movies">{{item}}</li>
      </ul>
      </div>
      
  3. 建立Vue对象,传入一个对象参数,绑定元素

    1. 创建Vue时,options可以放 el data methods 生命周期函数等
      const app = new Vue({
      el: '#app',    // 用于挂在要管理的元素
      data: {        // 定义数据
        message:'kon ni chi wa',
        s1: 'kon ban wa',
        movies: ['星际穿越', '教父', '大鱼', '哈利波特']
      }
      });
      
      原始JS将数据动态写入标签时,需要 获取元素、定义值、将值放入元素,这种方式叫做命令式编程
      VUE的这种赋值方式叫做声明式编程,将数据与页面分离
      若data中的数据值发生改变时,页面上显示的数据也会自动跟着改变 — **响应式**
  • 但有些改变不会产生响应式,有些方法可以
  • 对数组this.names[0] = 'ldf',页面上的内容不跟随改变 新版好像可以
  • 可以产生响应式的方法有:
    • push() 在尾部添加
    • pop() 弹出并删除最后一个元素
    • shift() 删除数组中的第一个元素
    • unshift() 在头部添加
    • splice() 删除、插入元素 array.splice(start, end[, str]) end为 0 时就不删除元素
    • sort() 排序
    • reverse() 颠倒 反转
    • Vue.set(array, 下标, 值)

      生命周期

      图:
      lifecycle.svg
      图中,绿色的是内部实现的;红色的是钩子,交由用户实现的
      常用生命周期函数
      created() 创建(组件)后
      destroyed() 销毁后。一般情况时,从一个组件跳转到另一个组件中时,前者即被销毁,除非使用了 keep-live
      mounted() 挂载后
      activated() 组件被激活后

插值 Mustache语法

  1. {{message}},又称双大括号语法
    1. 只有当该内容出现在被管理的范围内时,才会被解析出来
    2. 只能直接使用在首尾标签的内部
    3. 当头标签里面的属性要用到 data 中的数据时,需要 v-bind
  2. 响应式,当数据更改时 页面上的内容也会立刻变化
    1. 若元素加上v-once指令,则不能被再次改变值
  3. v-html指令的使用,将字符串中的html标签解析出来

    <div id="contain">
         <h3 v-html="data_url"></h3>
     </div>
    
     <script type="text/javascript" src="js/vue.js"></script>
     <script type="text/javascript">        
         const app = new Vue({
             el: '#contain',
             data: {
                 data_url: '<a href="http://www.biying.com">必应</a>'
             }
         })
     </script>
    
  4. 在双大括号中可以使用简单的表达式

    1. 比如:{{message + text}}{{count * 2}}
  5. v-pre指令,将标签内的双大括号以原始样子 {{}} 显示
  6. v-cloak指令。在某个标签中加上该指令,可以用来控制解析之前标签的显示与否等
    1. 在vue解析之前,标签中的该指令存在
    2. 在vue解析之后,标签中的该指令消失

语法

动态绑定属性 v-bind

  1. v-bind指令,用来动态绑定标签中的各种属性值 ```html
    Vue 2 - 图2
``` 2. v-bind 可以简写成一个`:`,如`:src=""` `:class=""` `:to="'/index/'+userId"` 2. 改变标签的class属性 1. class属性的值可以是一个对象,以 `key: value`的形式,即 类名:布尔值,指示使用与否 1. class的值可以是一个字符串,对应data中的元素,且该元素值就是一个类名 ```html

中村桑

``` b. 把若干class对象写在方法中 ```html
Vue view
``` 4. 动态绑定style属性的值,`v-bind:style=""` `:style=""` 1. 以对象或数组形式 ```html
动态绑定style1
动态绑定style2
``` b. 在对象形式中,key为style名,value为字符串或vue对象data中的属性值 如果要绑定的属性值过于复杂,可以将值抽取到 methods 或 computed 里面 ## 监听事件 v-on 1. `v-on:click = "函数名"`,表示监听点击事件. 1. 可以简写为`@click = '方法名'` 1. 函数名即为`methods`中的元素 ```html // html:
{{counter}}
// 这个 counter 就是下面data中的数据。counter++ 相当于一个表达式
// js ``` 参数中的非数字且未加引号时,会被认为是变量 且是data中的元素 2. 参数 1. 没有参数时,可以省略`()` 1. 需要一个参数event 但没有传入时,默认形参为该事件本身PointerEvent 1. 需要多个参数,但有一个没传入时,它为undefined 1. 需要多个参数,但都没有传入时,默认第一个参数为该事件本身 1. 当需要一般参数 又需要事件时,用**$event**作为实参 3. 修饰符,方便处理一些事件 1. `.stop` 调用 `event.stopPropagation()`,阻止事件冒泡 1. `.prevent` 调用 `event.preventDefault()`,阻止原始事件的调用,比如表单的submit按钮的提交 1. `.{keyCode | keyAlias}` 只当事件是从特定键触发时才触发回调,比如`.enter`就只有按enter键时才触发 1. `.native` 监听组件根元素的原生事件,新版不需要,可以直接监听事件 1. `.once` 只触发一次回调,在第一次触发时回调 ## 条件判断 - `v-if`,当满足一定条件时,标签才被渲染出来 ```html

morning~

afternoon

``` - `v-else`,当条件if的条件不满足时,显示else里面的内容 - `v-else-if`,一般不用,因为较复杂的判断 ```html

morning~

afternoon

55

``` - 用户切换的小案例 - label的for属性使其能够自动聚焦对应的输入框 ```html
``` - 案例中的小问题 - 当前一个input中已经输入的一些内容时,再点击切换,虽然input变了,但里面输入的内容还被保留了下来 - 解答 - 因为Vue在进行DOM渲染时,处于性能考虑,会尽可能复用已经存在的元素,而不是创建新的元素 - 在上面的案例中,Vue内部发现原来的input元素不再使用,直接将其作为else中的input来使用了 - 虚拟DOM,diff算法 - 解决 - 如果不希望Vue出现复用问题,可以给对应不同的input添加不同的key值 - `key='username'` 2. `v-show` 是否显示 1. 当条件为false时,自动为元素添加属性值`display: none`。当元素的显示与隐藏会切换频繁时,一般使用 v-show 1. `v-if` 当条件为false时,将该元素从页面去除 ## 遍历 1. `v-for` 1. **遍历数组**,`v-for='item in names'` 1. 第一个参数是每一个子元素。第二个参数是索引 从0开始 ```html
  • {{index+1}}.{{item}}
``` 3. **遍历对象**,item为每一个元素的value值 `v-for='item in yuuichi'` 3. 两个参数时,第一个为值 第二个为键 ```html
  • {{key}}-{{value}}
``` 5. 在使用 v-for 时,推荐为每一个元素或组件添加一个`:key`属性,其值唯一且与元素的内容对应(用item而不是index)。方便更新虚拟DOM - **三种 for 循环** ```javascript // books 为一个数组 let result = 0; // 1. for (let i = 0; i < books.length; i++){ result += books[i].price; } // 2. for(let i in books){ result += books[i].price; } // 3. for (let book of books){ result += book.price; ``` - **高阶函数 filter map reduce** ```javascript const nums = [3, 43, 90, 8, 20, 3, 0]; // 1. filter 遍历数组,每拿一个数组元素(n)就调用一次回调函数,且该回调函数必须返回一个布尔值 // true 时,函数内部就会自动将这次回调使用的元素n加入到新的数组中 // false时,函数内部就会自动过滤掉这个n let newNums = nums.filter(function(n){ return n < 10; }); // 2. map 遍历数组,每次拿一个数组元素,返回对该元素的操作结果 let new2Nums = newNums.map(function (n) { return n*2; }); // 3. reduce 对数组中所有的元素进行汇总 // previousValue 前一个元素 // currentValue 当前元素 // ... reduce(function(pre, curV, curI, array) { }, 0) 0 为初始化pre let new3Nums = new2Nums.reduce(function (previousValue, currentValue, currentIndex) { return previousValue + currentValue; }) // 链式调用 let total = nums.filter( n => n<10).map(n => n*2).reduce((pre, cur) => pre+cur); ``` ## v-model - 可以实现**双向绑定** - 更改输入框中的内容,data中的message也会实时跟着改变 ```html
{{message}} 等同于:
``` - v-mode 结合 radio ```html 选择性别:{{sex}} ``` - v-model 结合 checkbox,自动获取所选内容 - 单选时,值为布尔类型 - 多选时,为具体内容 ```html

您选择的是: {{isAgree}}

篮球 排球 足球 游泳

所选:{{hobbies}}

``` - v-model 与 select,也支持单选与多选(multiple) - 值绑定,将用户要选择的选项从服务器获取,动态展示到页面中 - **修饰符** - `v-model.lazy=''` input失去焦点或敲回车时 再进行变量更新 - `v-model.number=''` 根据data中关联的元素内容 可以限定输入数字,且不会把输入的数字自动转为字符串 - `v-model.trim=''` 自动去掉字符串左右的空格 ## mixin 混入 将组件的内容提取出去,导入后 `mixins: [对象名]`,作用是可以将一些重复的代码提取出去。
也可以将导入的内容与原来的内容合并。 ```javascript export const mixinListener = { mounted() { console.log('This is a mixin part'); }, } ``` ```javascript import { mixinListener } from "@/common/mixin.js" export default { ... mixins: [mixinListener], mounted() { ... } } ``` # 计算属性 computed 1. 作用,将data中的属性处理之后再直接使用 1. 实质上是一个属性,使用时不用加`()` 1. 计算属性在多次使用时只执行一次 **有缓存,**当再次执行的内容与前一次完全一致时 不会再执行该函数;而methods调用多少次就执行多少次 没有缓存 ```html
计算属性 {{fullName}}
``` ## get set 计算属性有get 和set方法,但是一般只写get方法(只读属性) - 因此可以看出,计算属性里面的元素本身并不是函数 ```javascript computed:{ car: { get: function(){ return content; } } } // 省略如下 computed:{ car: function(){ return content; } } ``` # 组件 component 基本步骤: 1. 创建组件构造器,调用`Vue.extend()`方法 1. 传入template模板 2. 注册组件。调用`Vue.component()`方法 1. 标签名,组件构造器 1. 下面例子为注册**全局组件**,可以在多个Vue的实例中使用 3. 使用组件,在Vue实例的作用范围内使用 ```html
``` - **局部组件**在某个Vue实例中注册,`标签名:构造器` ```javascript const app = new Vue({ el: '#app', data: { }, components: { cpn: cpnConstructor } }); ``` **组件模板里面的html代码必须要有一个根标签,否则会出错** ## 父子组件 在一个组件构造器里面使用另一个组件 - 在构造器cpnC2里面通过components属性注册组件cpn2,再在自己的template中使用cpn2 - 在app的components里面只需注册cpn2 - cpn1是子,cpn2是父 - 这种情况下,在`
`里面不能使用子组件cpn1,( 因为在父组件里面注册时 已经被解析出来了,之后就找不到那个名字 ```html
``` ## 语法糖 将定义组件的`extend()`省去 ```javascript Vue.component('cpn', { template: `
内容
` }); // 或 const app = new Vue({ el: '#app', components: { cpn2: { template: `
内容
` } } }); ``` **分离组件模板** 1. 使用`script`标签 ```html
``` 2. 使用`template`标签 ```html
``` ## 组件的data 组件不能直接使用Vue实例里面的data数据,且他的这个data是一个函数 返回一个对象 ```html 在cpn5组件里面使用{{author}} ``` - data是一个函数,可以在组件多次使用时,防止多个组件操作同一个数据 ## 父子组件通信 Vue实例可以看成是根组件
![](https://cdn.nlark.com/yuque/0/2021/jpeg/495969/1636277178556-b233e3d0-d570-42e1-8aee-8a8197d5e3e1.jpeg) - 在使用组件的时候,在组件标签中 通过`**v-bind**`将父组件的数据绑定给对应的元素 - 在定义组件时,通过`**props**`属性 声明需要的变量名称及其类型及相关约束 - 当类型为`Array Object`时,设置的默认值必须通过一个函数返回 - 可以自定义验证类型 - 默认有的数据类型: - String、Number、Boolean、Array、Object、Date、Function、Symbol ```html
``` - data值名称是驼峰时,在html中绑定时,需要写小写 用`-`连接各单词,如 `theFinalMessage: String` ---> `:the-final-message='theFinalMessage'` ,使用的时候`{{theFinalMessage}}` - 子组件的props的数据,只能由父组件传来,不可由子组件自己改变 2. **子传父** - 通过在子组件的函数中使用 `this.$emit('子方法名', 参数)` 把子组件的数据传给父组件 - 再在使用子组件时,绑定方法 `**v-on**:子方法名='自己methods里面的方法'` ```html
// 父组件绑定子组件发射过来的方法
``` ## watch 属性 监听data的数据变化,就不必写`@input=''` - 方法名称必须与要监听的数据名称一致 ```html ``` ## 父子组件的访问方式 1. 父组件访问子组件,使用 $children 或 $refs - $children 返回数组,包含所有子组件 - 常用**$refs**,需要在使用子组件时,给子组件添加一个属性值`ref='特定值'`, ```html ``` 2. 子组件访问父组件,使用$parent,用得非常少,耦合度高 2. $root 访问根组件 ## 插槽 slot 给组件中挖一个坑``,在复用组件时,可以添加进去多样化的东西,提高扩展性。
若组件的模板中没有使用 slot ,那么在使用组件的起止标签之间的任何内容都会被抛弃。
把相同的东西放在原组件中,不同的东西留成插槽 - 一个空的slot,会把组件标签内部的内容全部替换到插槽位置 ```html 斜斜 ``` - 插槽中有内容,当组件标签中无替换元素时,会显示插槽中原有的内容;当组件标签中有内容时,替换掉插槽里的东西 ```html 斜斜 ``` ### 具名插槽 有多个插槽时,给每一个插槽name属性值
使用组件时,给要替换的内容用 `template` 标签包住,并使用`v-slot:名字` 指定要替换哪一个 slot,若要替换的slot没有写name值,则`v-slot=default` .
注意,**v-slot **只能添加在**