• Vue学习笔记(二)


    Vue学习笔记(二)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-35qYV0QC-1659271236045)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220723102127041.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sDQQRx0x-1659271236046)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220723102539229.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-veP2VG1s-1659271236047)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220723102652352.png)]

    非单文件组件:

    三大步骤:

    1. 定义组件(创建组件)

    2. 注册组件

    3. 使用组件(写组件标签)

    4. 定义组件

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

        el 不要写,因为最终所有的组件都要经过一个 vm 的管理,由 vm 中的 el 决定服务哪个容器
        data 必须写成函数,为了避免组件被复用时,数据存在引用关系
      
      • 1
      • 2

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

    5. 注册组件

    • 局部注册:靠 new Vue 的时候传入 components 选项
    • 全局注册:靠 Vue.component(‘组件名’,组件)
    1. 编写组件标签

    <组件名>

    单文件组件代码:

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
        <script src="./js/vue.js">script>
    head>
    <body>
        <div id="root">
            <school>school>
            <hr>
            <student>student>
        div>
        <script>
            Vue.config.productionTip = false
            //创建名为 school 的组件
            const school = Vue.extend({
                template:
                `
                

    学校名称:{{schoolName}}

    学校地址:{{address}}

    `
    , data(){ return { schoolName:'尚硅谷', address:'北京' } } }) //创建名为 student 的组件 const student = Vue.extend({ template: `

    学生姓名:{{studentName}}

    学生年龄:{{age}}

    `
    , data(){ return { studentName:'张三', age: 18 } } }) Vue.component('student',student) //全局指令 new Vue({ el:'#root', components:{ school, //局部指令 } })
    script> body> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    几个注意点:

    1. 关于组件名:

      一个单词组成:

         第一种写法(首字母小写):school
           
         第二种写法(首字母大写):School 
      
      • 1
      • 2
      • 3

      多个单词组成:

         第一种写法(kebab-case命名):my-school
           
         第二种写法(CamelCase命名):MySchool(需要Vue脚手架支持)
      
      • 1
      • 2
      • 3

      备注:

       (1)组件名尽可能回避 HTML 中已有的元素名称,例如:h2、H2 都不行
      
       (2)可以使用 name 配置项指定组件在开发者工具中呈现的名字
      
      • 1
      • 2
      • 3
    2. 关于组件标签:

        第一种写法:<组件名>
      
        第二种写法:<组件名/>
      
        备注:不使用脚手架时,<组件名/> 会导致后续组件不能渲染  
      
      • 1
      • 2
      • 3
      • 4
      • 5
    3. 一个简写方式:

         const school = Vue.extend(options) 可简写为: const school = options 
      
      • 1

    组件的嵌套:

    定义一个 app 组件,用来管理所有的组件,最后 app 被 Vue 实例所管理, app 只管它分支下面的组件,在分支中的组件自有分支自己管理,不用写在 app 中 ,代码:

          DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta http-equiv="X-UA-Compatible" content="IE=edge">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <title>Documenttitle>
              <script src="../js/vue.js">script>
          head>
          <body>
              <div id="root">
              div>
              <script>
                  Vue.config.productionTip = false
                  const student = {
                      template:
                      `
                      

    学生名称:{{studentName}}

    学生年龄:{{age}}

    `
    , data(){ return { studentName:'张三', age: 18 } } } const school = { template: `

    学校名称:{{schoolName}}

    学校地址:{{address}}

    `
    , data(){ return { schoolName:'尚硅谷', address:'北京' } }, components:{ student } } const hello = { template:`

    {{msg}}

    `
    , data(){ return { msg: 'hello' } } } const app = { template: `
    `
    , components:{ school, hello } } new Vue({ el:'#root', template:``, components:{ app } })
    script> body> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    其中我们可以看到在 school 组件中写了 components:{ student },说明 student 组件是嵌套在 school 组件中的,归 school 组件管理,而 app 组件中 components 下有两个组件名,说明它们是平级的,且归 app 管理

    componet函数

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

    2. 我们只需要写 或 ,Vue 解析时会帮我们创建 school 组件的实例对象,即 Vue 帮我们执行的: new VueComponent(options)

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

    4. 关于 this 指向:

    (1)组件配置中:

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

    (2)new Vue() 配置中:

            data 函数、methods 中的函数、watch 中的函数、computed 中的函数   它们的 this 均是【Vue 实例对象】
    
    • 1
    1. VueComponent 的实例对象称之为组件实例对象

    一个重要的内置关系:

    VueComponent.prototype.proto === Vue.prototype
    组件是可复用的Vue实例,data必须写成函数

    为什么要有这个关系: 让组件实例对象可以访问到 Vue 原型上的属性、方法

    可能这么说不理解,配个图!

    img

    单文件组件:

    < v 这两个字符可以自动配置好vue的结构

    
     
    
     
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    vue脚手架:command line interface Cli

    npm config set cache=“D:\Program Files (x86)\nodejs\node_cache”

    原来node.js就是来配置npm的,有了npm之后才可以运行vue的文件

    vue的目录还是很简单的

    分析render函数:

    render 函数 跟 template 一样都是创建 html 模板的,但是有些场景中用 template 实现起来代码冗长繁琐而且有大量重复,这时候就可以用 render 函数。

    官网例子:子组件想要根据父组件传递的 level 值(1-6)来决定渲染标签 h 几。具体代码可以看文档。

    render 函数讲解
    render 函数即渲染函数,它是个函数,它的参数也是个函数——即 createElement,我们重点来说 createElement 参数。

    render 函数的返回值(VNode)
    VNode(即:虚拟节点),也就是我们要渲染的节点。

    render 函数的参数(createElement)
    createElement 是 render 函数 的参数,它本身也是个函数,并且有三个参数。

    createElement 函数的返回值(VNode)
    createElement 函数的返回值是 VNode(即:虚拟节点)。

    createElement 函数的参数(三个)
    一个 HTML 标签字符串,组件选项对象,或者解析上述任何一种的一个 async 异步函数。类型:{String | Object | Function}。必需。
    一个包含模板相关属性的数据对象你可以在 template 中使用这些特性。类型:{Object}。可选。
    子虚拟节点 (VNodes),由 createElement() 构建而成,也可以使用字符串来生成“文本虚拟节点”。类型:{String | Array}。可选。

     /**
      * render: 渲染函数
      * 参数: createElement
      * 参数类型: Function
     */
     render: function (createElement) {
       let _this = this['$options'].parent	// 我这个是在 .vue 文件的 components 中写的,这样写才能访问this
       let _header = _this.$slots.header   	// $slots: vue中所有分发插槽,不具名的都在default里
     
       /**
        * createElement 本身也是一个函数,它有三个参数
        * 返回值: VNode,即虚拟节点
        * 1. 一个 HTML 标签字符串,组件选项对象,或者解析上述任何一种的一个 async 异步函数。必需参数。{String | Object | Function} - 就是你要渲染的最外层标签
        * 2. 一个包含模板相关属性的数据对象你可以在 template 中使用这些特性。可选参数。{Object} - 1中的标签的属性
        * 3. 子虚拟节点 (VNodes),由 `createElement()` 构建而成,也可以使用字符串来生成“文本虚拟节点”。可选参数。{String | Array} - 1的子节点,可以用 createElement() 创建,文本节点直接写就可以
        */
       return createElement(       
         // 1. 要渲染的标签名称:第一个参数【必需】      
         'div',   
         // 2. 1中渲染的标签的属性,详情查看文档:第二个参数【可选】
         {
           style: {
             color: '#333',
             border: '1px solid #ccc'
           }
         },
         // 3. 1中渲染的标签的子元素数组:第三个参数【可选】
         [
           'text',   // 文本节点直接写就可以
           _this.$slots.default,  // 所有不具名插槽,是个数组
           createElement('div', _header)   // createElement()创建的VNodes
         ]
       )
     }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    总的来说就是runtime时候的Vue版本和开发的Vue版本是不一样的,runtime时候的Vue版本不包含模板的渲染,即不包含temp选项

    webpack

    (68条消息) Webpack的基本使用_sut_uestc的博客-CSDN博客

    前端模块化的一些方案:AMD、CMD、CommonJS、ES6(浏览器不能识别它们,但是webpack可以做它们的底层支撑,方可进行模块化开发)
    ES6之前,要想进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发
    并且在通过模块化开发完成了项目后,还需要处理模块化间的各种依赖,并且将其进行整合打包
    此时出现webpack,其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系。
    而不仅仅是JavaScript文件,我们的CSS、图片、json文件等等在webpack中都可以被当做模块来使用

    脚手架文件结构:

    ├── 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:包版本控制文件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    关于不同版本的Vue
    vue.js与vue.runtime.xxx.js的区别:
    vue.js是完整版的Vue,包含:核心功能 + 模板解析器。
    vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。
    因为vue.runtime.xxx.js没有模板解析器,所以不能使用template这个配置项,需要使用render函数接收到的createElement函数去指定具体内容。
    vue.config.js配置文件
    使用vue inspect > output.js可以查看到Vue脚手架的默认配置。
    使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh

    ref标签:

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


    获取:this.$refs.xxx

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jo8E87Za-1659271236047)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220724200137703.png)]

    props配置项:

    1. 功能:让组件接收外部传过来的数据
    2. 传递数据:
    3. 接收数据:
      1. 第一种方式(只接收):props:['name']
      2. 第二种方式(限制类型):props:{name:String}
      3. 第三种方式(限制类型、限制必要性、指定默认值):
    props:{
    	name:{
    	type:String, //类型
    	required:true, //必要性
    	default:'老王' //默认值
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    传进来的props是没有办法去修改的

    都是vc先去准备生成的,然后利用生成的vc去渲染已经有的vm

    Vue代码关闭语法检查:

    const { defineConfig } = require('@vue/cli-service')
    module.exports = defineConfig({
      transpileDependencies: true,
      lintOnSave: false//关闭语法检查
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    export

    在JavaScript ES6中,export与export default均可用于导出常量、函数、文件、模块等,你可以在其它文件或模块中通过import+(常量 | 函数 | 文件 | 模块)名的方式,将其导入,以便能够对其进行使用,但在一个文件或模块中,export、import可以有多个,export default仅有一个。
    具体使用:
    ———————————————

    //demo1.js
    export const str = 'hello world'
    
    export function f(a){
        return a+1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    //导入方式
    //demo2.js
    import { str, f } from 'demo1' //也可以分开写两次,导入的时候带花括号
    
    • 1
    • 2
    • 3
    //demo1.js
    export default const str = 'hello world'
    
    • 1
    • 2
    //demo2.js
    import str from 'demo1' //导入的时候没有花括号
    
    • 1
    • 2

    mixin混入:

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

    2. 使用方式:

      第一步定义混合:

    const mixin = {
        data(){....},
        methods:{....}
        ....
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    第二步使用混入:

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

    混入的时候,如果原来的位置有混入的值的话,以原来的数值为主

    scoped用法:

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