![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-35qYV0QC-1659271236045)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220723102127041.png)]](https://1000bd.com/contentImg/2022/08/03/123147545.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sDQQRx0x-1659271236046)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220723102539229.png)]](https://1000bd.com/contentImg/2022/08/03/123147748.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-veP2VG1s-1659271236047)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220723102652352.png)]](https://1000bd.com/contentImg/2022/08/03/123147915.png)
三大步骤:
定义组件(创建组件)
注册组件
使用组件(写组件标签)
定义组件
使用 Vue.extend(options) 创建,其中 options 和 new Vue(options) 时传入的那个 options 几乎一样,但也有点区别:
el 不要写,因为最终所有的组件都要经过一个 vm 的管理,由 vm 中的 el 决定服务哪个容器
data 必须写成函数,为了避免组件被复用时,数据存在引用关系
备注:使用 template 可以配置组件结构
注册组件
<组件名>组件名>
单文件组件代码:
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>
几个注意点:
关于组件名:
一个单词组成:
第一种写法(首字母小写):school
第二种写法(首字母大写):School
多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool(需要Vue脚手架支持)
备注:
(1)组件名尽可能回避 HTML 中已有的元素名称,例如:h2、H2 都不行
(2)可以使用 name 配置项指定组件在开发者工具中呈现的名字
关于组件标签:
第一种写法:<组件名>组件名>
第二种写法:<组件名/>
备注:不使用脚手架时,<组件名/> 会导致后续组件不能渲染
一个简写方式:
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>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>
其中我们可以看到在 school 组件中写了 components:{ student },说明 student 组件是嵌套在 school 组件中的,归 school 组件管理,而 app 组件中 components 下有两个组件名,说明它们是平级的,且归 app 管理
componet函数
school 组件本质是一个名为 VueComponent 的构造函数,且不是程序员定义的,是 Vue.extend 生成的
我们只需要写 或 ,Vue 解析时会帮我们创建 school 组件的实例对象,即 Vue 帮我们执行的: new VueComponent(options)
特别注意:每次调用 Vue.extend 返回的都是一个全新的 VueComponent
关于 this 指向:
(1)组件配置中:
data 函数、methods 中的函数、watch 中的函数、computed 中的函数 它们的 this 均是【VueComponent 实例对象】
(2)new Vue() 配置中:
data 函数、methods 中的函数、watch 中的函数、computed 中的函数 它们的 this 均是【Vue 实例对象】
一个重要的内置关系:
VueComponent.prototype.proto === Vue.prototype
组件是可复用的Vue实例,data必须写成函数
为什么要有这个关系: 让组件实例对象可以访问到 Vue 原型上的属性、方法
可能这么说不理解,配个图!

< v 这两个字符可以自动配置好vue的结构
姓名:{{name}}
家庭地址:{{address}}
vue脚手架:command line interface Cli
npm config set cache=“D:\Program Files (x86)\nodejs\node_cache”
原来node.js就是来配置npm的,有了npm之后才可以运行vue的文件
vue的目录还是很简单的
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)
使用方式:
打标识:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jo8E87Za-1659271236047)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220724200137703.png)]](https://1000bd.com/contentImg/2022/08/03/123148385.png)
props:['name']props:{name:String}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' //导入的时候没有花括号
功能:可以把多个组件共用的配置提取成一个混入对象
使用方式:
第一步定义混合:
const mixin = {
data(){....},
methods:{....}
....
}
第二步使用混入:
全局混入:Vue.mixin(xxx)
局部混入:mixins:['xxx']
混入的时候,如果原来的位置有混入的值的话,以原来的数值为主
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QIPOWa3d-1659271236048)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220725105006742.png)]](https://1000bd.com/contentImg/2022/08/03/123148622.png)
APP里面去写样式,一般不会使用scoped修饰
这个lan表示的是language,不写的话默认的是CSS
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xkWJ9mYJ-1659271236049)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220725105623026.png)]](https://1000bd.com/contentImg/2022/08/03/123148799.png)
1.存储内容大小一般支持5MB左右(不同浏览器可能还不-样)
2.浏览器端通过Window.sessionStorage和Window.localStorage属性来实现本地存储机制。
3.相关API:
(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)]](https://1000bd.com/contentImg/2022/08/03/123149101.png)
(71条消息) vue中组件的自定义事件(详)_suoh’s Blog的博客-CSDN博客_vue 组件事件
解绑事件:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z91Ni1Wi-1659271236050)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220727100301333.png)]](https://1000bd.com/contentImg/2022/08/03/123149424.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)]](https://1000bd.com/contentImg/2022/08/03/123150033.png)
安装全局事件总线:
Vue组件当中:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hsQXZGYt-1659271236051)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220727105501080.png)]](https://1000bd.com/contentImg/2022/08/03/123150174.png)
其他组件的代码:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Opqg6dT-1659271236051)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220727105732925.png)]](https://1000bd.com/contentImg/2022/08/03/123150362.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去解绑当前组件所用到的事件。