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 必须写成函数,为了避免组件被复用时,数据存在引用关系
    

    备注:使用 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>Document</title>
    <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:
            `
            <div>
                <h2>学校名称:{{schoolName}}</h2>
                <h2>学校地址:{{address}}</h2>
            </div>
            `,
            data(){
                return {
                    schoolName:'尚硅谷',
                    address:'北京'
                }
            }
        })
        //创建名为 student 的组件
        const student = Vue.extend({
            template: 
            `
            <div>
                <h2>学生姓名:{{studentName}}</h2>
                <h2>学生年龄:{{age}}</h2>
            </div>
            `,
            data(){
                return {
                    studentName:'张三',
                    age: 18
                }
            }
        })
        Vue.component('student',student)   //全局指令
        new Vue({
            el:'#root',
            components:{
                school,   //局部指令
            }
        })
    </script>
</body>
</html>

几个注意点:

  1. 关于组件名:

    一个单词组成:

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

    多个单词组成:

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

    备注:

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

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

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

组件的嵌套:

定义一个 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>Document</title>
          <script src="../js/vue.js"></script>
      </head>
      <body>
          <div id="root">
          </div>
          <script>
              Vue.config.productionTip = false
              const student = {
                  template:
                  `
                  <div>
                      <h2>学生名称:{{studentName}}</h2>
                      <h2>学生年龄:{{age}}</h2>
                  </div>
                  `,
                  data(){
                      return {
                          studentName:'张三',
                          age: 18
                      }
                  }
              }
              const school = {
                  template: 
                  `
                  <div>
                      <h2>学校名称:{{schoolName}}</h2>
                      <h2>学校地址:{{address}}</h2>
                      <student></student>
                  </div>
                  `,
                  data(){
                      return {
                          schoolName:'尚硅谷',
                          address:'北京'
                      }
                  },
                  components:{
                      student
                  }
              }
              const hello = {
                  template:`<h2>{{msg}}</h2>`,
                  data(){
                      return {
                          msg: 'hello'
                      }
                  }
              }
              const app = {
                  template: 
                  `
                  <div>
                  <school></school>
                  <hello></hello>
                  </div>
                  `,
                  components:{
                      school,
                      hello
                  }
              }
              new Vue({
                  el:'#root',
                  template:`<app></app>`,
                  components:{
                      app
                  }
       
              })
          </script>
      </body>
      </html>

其中我们可以看到在 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 实例对象】

(2)new Vue() 配置中:

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

一个重要的内置关系:

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

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

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

img

单文件组件:

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

<template>
	<div class="demo">
		<h2>姓名:{{name}}</h2>
		<h2>家庭地址:{{address}}</h2>
		<button @click="showName">点我提示当前名称</button>	
	</div>
</template>
 
<script>
	 export default {
		name:'School',
		data(){
			return {
				name:'张三',
				address:'北京'
			}
		},
		methods: {
			showName(){
				alert(this.name)
			}
		},
	}
</script>
 
<style>
	.demo{
		background-color: orange;
	}
</style>

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
     ]
   )
 }

总的来说就是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:包版本控制文件

关于不同版本的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. 传递数据:<Demo name="xxx"/>
  3. 接收数据:
    1. 第一种方式(只接收):props:['name']
    2. 第二种方式(限制类型):props:{name:String}
    3. 第三种方式(限制类型、限制必要性、指定默认值):
props:{
	name:{
	type:String, //类型
	required:true, //必要性
	default:'老王' //默认值
	}
}

备注: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//关闭语法检查
})

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
}
//导入方式
//demo2.js
import { str, f } from 'demo1' //也可以分开写两次,导入的时候带花括号
//demo1.js
export default const str = 'hello world'
//demo2.js
import str from 'demo1' //导入的时候没有花括号

mixin混入:

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

  2. 使用方式:

    第一步定义混合:

const mixin = {
    data(){....},
    methods:{....}
    ....
}

第二步使用混入:

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

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

scoped用法:

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

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

APP里面去写样式,一般不会使用scoped修饰

这个lan表示的是language,不写的话默认的是CSS

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

ToDoList案例(未完成)

浏览器本地存储 localstorage和sessionStorage:

1.存储内容大小一般支持5MB左右(不同浏览器可能还不-样)
2.浏览器端通过Window.sessionStorage和Window.localStorage属性来实现本地存储机制。
3.相关API:

  1. xxxxxStorage . setItem(‘key’, ‘value’);
    该访法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。
  2. xxxxxStorage. getItem(’ person’);
    该访法接受一个键名作为参数,返回键名对应的值。
  3. xxxxxStorage. removeItem(‘key’ );
    该方法接受一个键名作为参数, 并把该键名从存储中删除。
  4. xxxStorage. clear()
    该方法会清空存储中的所有数据。
    4.备注:
  5. SessionStorage存储的内容会随着浏览器窗口关闭而消失。
  6. LocalStorage存储的内容,需要手动清除才会消失。
  7. xxxxStorage. getItem(xx)如果xxx对应的value获取不到,那么gettem的返回值是null。
  8. JSON. parse(null)的结果依然是null.

(70条消息) cookie、sessionStorage,localStorage区别_年轻即出发的博客-CSDN博客

(70条消息) cookie、sessionStorage和localStorage的区别_浮生离梦的博客-CSDN博客_localstorage和sessionstorage和cookie

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

组件的自定义事件

(71条消息) vue中组件的自定义事件(详)_suoh’s Blog的博客-CSDN博客_vue 组件事件

解绑事件:

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

组件的自定义事件
1.种组件间通信的方式,适用于:子组件= =>父组件
2.使用场景: A是父组件, B是子组件, B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。
3.绑定自定义事件:
1.第一种方式,在父组件中:

<Demo @atguigu="test"/> <Demo v-on:atguigu="test"/>

2.第二种方式,在父组件中:

<Demo ref=" demo"/>
mounted( ){
this . $refs . x $on('atguigu' ,this.test)

3.若想让自定义事件只能触发- -次, 可以使用once修饰符,或$once方法。
4.触发自定义事件: this. $emit(’ atguigu’ ,数据)
5.解绑自定义事件this. $off( ’ atguigu’)
6.组件上也可以绑定原生DOM事件,需要使用native修饰符。
7.注意:通过this. $refs . xx. $on( ‘atguigu’,回调)绑定自定义事件时,回调要么配置在methods中, 要么用箭头函数,否则this指向会出问题!

全局事件总线:

任意事件之间的通信:

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

安装全局事件总线:

Vue组件当中:

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

其他组件的代码:

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

总结:

全局事件总线 (GlobalEventBus)

1.一种组件间通信的方式,适用于任意组件间通信。

2.安装全局事件总线:

new Vue({
beforeCreate() {
Vue. prototype.$bus = this //安装全局事件总线,$bus就是当 前应用的vm
})

3.使用事件总线:
1.接收数据: A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。

methods(){
		demo(data){......}
		}
		mounted() {
		this . $bus . $on( ' xxxx' ,this . demo)
		}

​ 2.提供数据: this . $bus. e m i t ( ′ x x x x ′ , 数据 ) 4. 最好在 b e f o r e D e s t r o y 钩子中,用 emit( 'xxxx' ,数据) 4.最好在beforeDestroy钩子中,用 emit(xxxx,数据)4.最好在beforeDestroy钩子中,用off去解绑当前组件所用到的事件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值