QX-AI
GPT-4
QX-AI初始化中...
暂无预设简介,请点击下方生成AI简介按钮。
介绍自己
生成预设简介
推荐相关文章
生成AI简介
生命周期 {#生命周期}
Vue会在一些特殊时刻去调用一些特殊的函数
这些要经过的特殊时刻就是生命周期 ,要调用的特殊函数就是生命周期函数(生命周期钩子,生命周期回调函数)
**为什么叫钩子:**vm在某个步骤上已经写了执行该名称的函数,但函数内容未定义,得程序员来定义。即生命周期函数的名字不可更改,但函数的具体内容需要程序员根据业务需求编写
Vue实例的生命周期:
1、初始化显示
beforeCreate()
=> 初始化:生命周期、事件,但数据代理还未开始create()
=> 初始化:数据监测、数据代理beforeMount()
=> 模板解析完毕,虚拟DOM建立,但还未挂载mounted()
=> 挂载完毕,虚拟DOM转为真实DOM
2、更新状态: this.xxx = value
beforeUpdate()
=> 数据已更新,但页面还未更新,新旧虚拟dom还未对比updated()
=> 数据和页面都是新的
3、销毁 vue 实例: vm.$destroy()
触发下面两个钩子
beforeDestroy()
=> 此时vm上所有东西都是可用的,但不再解析模板更新页面destroyed()
=> vm彻底被销毁
还有三个钩子不在图中,和路由相关
常用钩子:
- mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】
- beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】
关于销毁Vue实例:
- 在大多数场景中不应该调用 vm.$destroy() 。最好使用 v-if 和 v-for 指令以数据驱动的方式控制子组件的生命周期。
- 销毁后借助Vue开发者工具看不到任何信息
- 销毁后自定义事件会失效,但原生D0M事件依然有效
- 在beforeDestroy中做好善后工作
组件 {#组件}
组件: 应用中局部 功能代码 和资源 的集合
在 Vue 中,组件是可复用 的 Vue实例
组件体现了封装的思想,组件也可以嵌套封装
组件化: 编写一套组件,在所需的页面引入组件,当应用中的功能都是多组件的方式来编写的, 这个应用就是一个组件化的应用
**为什么要组件化:**传统的三件套可以只能做到拆分css、js模块化,而html结构不复用,且文件依赖关系(N-1-N)复杂,组件化后,页面的每个部分都对应一个组件,组件中的小功能部分也能对应更多组件,组件逐层嵌套,最终由一个Vue实例管理,依赖关系清晰,通过引入组件构建页面,代码复用率高,后续维护也能针对性找到组件进行操作
非单文件组件 {#非单文件组件}
非单文件组件: 一个文件中包含n个组件,实际开发几乎不用这种写法
使用组件流程:
-
定义组件:
Vue.extend()
- 配置项中不能写el属性 ,因为最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器
- 组件中的data必须用函数式 ,避免组件被复用时,数据存在引用关系。
- 使用 template 配置组件模板结构,必须有一个根元素包裹|------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|const school = Vue.extend({ // 模板,template中的模板必须有一个根元素包裹 template: ` <div> <h3>{{name}}</h3> <h3>{{city}}</h3> </div> `, // 组件中的data必须用函数式 // 因为对象是引用类型数据,函数式返回一个新对象才能保证多次引用组件的data互不影响 data() { return { name: '五道口', city: '京海' } } })
| -
注册组件:
-Vue.component()
全局注册
- 局部注册,在vm配置项的 components 属性中|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|// 全局注册组件,多个vue实例都能使用该组件 Vue.component('school', school) // 组件由vm管理 new Vue({ el: '#root', data: { msg: '信息' }, // 局部注册组件 components: { // 组件名 student } })
| -
使用组件: 在容器中写组件标签
案例: 非单文件组件案例
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 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
| <div id="root"> <h2>{{msg}}</h2> <!-- 引用组件,组件标签 --> <school></school> <hr /> <!-- 多次引用组件,且数据独立互不影响 --> <student></student> <student></student> </div> <script> // 使用Vue.extend定义一个组件,传入一个配置项 const school = Vue.extend({ // 模板,template中的模板必须有一个根元素包裹 template: ` <div> <h3>{{name}}</h3> <h3>{{city}}</h3> </div> `, // 组件中的data必须用函数式 // 因为对象是引用类型数据,函数式返回一个新对象才能保证多次引用组件的data互不影响 data() { return { name: '五道口', city: '京海' } } }) const student = Vue.extend({ template: ` <div> <h3>{{name}}</h3> <h3>{{age}}</h3> <button @click="age++">年龄加一</button> </div> `, data() { return { name: 'chuckle', age: '19' } } }) // 全局注册组件,多个vue实例都能使用该组件 Vue.component('school', school) // 组件由vm管理 new Vue({ el: '#root', data: { msg: '信息' }, // 局部注册组件 components: { // 组件名 student } }) </script>
|
注意事项 {#注意事项}
关于组件名:
-
组件名只有一个单词 时,引用组建时写小写
<student>
或大写<Student>
Vue只会去找小写的组件名,即组件名只有一个单词时 需使用小写 -
组件名由多个单词 组成时,有两种写法:横杠写法 、双驼峰写法 (只能在脚手架环境中使用)
|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
1 2 3 4 5 6 7 8 9 10 11
|<!-- 横杠写法 --> <my-school></my-school> <script> Vue.component('my-school', MySchool) </script> <!-- 双驼峰写法(只能在脚手架环境中使用) --> <MySchool></MySchool> <script> Vue.component('MySchool', MySchool)o[] </script>
| -
不能使用html已有标签名作为组件名
-
在定义组件时添加 name 配置,无论注册使用时是什么名,在开发者工具中显示的都是该 name(首字母同样会自动显示大写)
|---------------------------|--------------------------------------------------------------------------------------------------------| |
1 2 3 4 5 6 7 8 9
|const school = Vue.extend({ // 设置 name name: 'MySchool', template: ``, data() { return {} } })
|
在脚手架环境 下,可以使用组件时可以写双标签 <school></school>
或自闭合标签 <school/>
,不用使用脚手架时,<school/>
会导致后续组件不能渲染。
定义组件可以简写:
注册组件时底层有判断,若是一个对象,Vue会帮我们调用Vue.extend,并将对象作为配置项传入
|---------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| // 简写,实际上也调用了Vue.extend const school = { template: ``, data() { return {} } } // 写上 Vue.extend 不简写 const school = Vue.extend({ template: ``, data() { return {} } })
|
组件嵌套 {#组件嵌套}
组件嵌套: 一个组件也会用到其它多个组件,组件关系逐层嵌套,形成父子组件关系
使用方式: 在父组件中 components 配置项注册其子组件,组件在哪注册就要在哪使用
开发中的技巧: 定义一个名为 app 的组件,用于管理页面中最上层的所有组件,而 vm 本身只管理 app 组件
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 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
| <div id="root"></div> <script> // 子组件的定义要放到父组件前 const student = { template: ` <div> <h3>学生姓名:{{name}}</h3> <h3>学生年龄:{{age}}</h3> </div> `, data() { return { name: 'chuckle', age: '19' } } } // 定义父组件 const school = { // 在父组件中使用子组件 template: ` <div> <h2>学校名:{{name}}</h2> <hr /> <student></student> </div> `, data() { return { name: '五道口' } }, // 注册子组件 components: { student, } } // 定义一个欢迎语组件,和school组件同级 const hello = { template: ` <div> <h3>{{welcome}}</h3> <hr/> </div> `, data() { return{ welcome: '欢迎!' } } } // 定义app组件,管理所有组件 const app = { template: ` <div> <hello></hello> <school></school> </div> `, // 管理下一层的父级组件 components: { school, hello } } new Vue({ el: '#root', // 应用app组件,替换掉root容器 template:`<app></app>`, components: { // vm只管理app组件 app } }) </script>
|
VueComponent构造函数 {#VueComponent构造函数}
每个组件的本质 都是一个 VueComponent()
构造函数,它由 Vue.extend()
生成并返回
每次调用 Vue.extend()
,返回的都是一个全新的 VueComponent()
构造函数
打印app组件:
|-------------------|-----------------------------------------------------------------------------------|
| 1 2 3 4 5
| const app = Vue.extend({ template: ``, components: {} }) console.log(app)
|
输出
|---------------|----------------------------------------------------------|
| 1 2 3
| ƒ VueComponent(options) { this._init(options); }
|
既然是构造函数,使用它就需要 new 创建实例
只需要在合适的位置写 <school></school>
,Vue 在解析模板时 会自动去创建对应的VueComponent 构造函数的实例
即Vue会在解析模板 时自动执行 :new VueComponent(options)
1、this的指向:
(1) Vue.extend(options)
组件配置中,this 指向 VueComponent 实例对象
(2) new Vue(options)
配置中,this 指向 vm 实例对象
2、Vue对组件的关系设计:
- 每种 组件定义时都需要调用
Vue.extend()
,它返回一个新的VueComponent()
构造函数,即不同种类的组件,其对应的 VueComponent 构造函数不同,以此来区分组件的种类 - Vue在解析模板时 ,会对每个组件标签 都调用一次对应的构造函数,返回的实例 都是互不影响的,以此来区分同种组件 的不同实例(同种组件在出现在页面不同位置,展示不同内容)
vm与vc {#vm与vc}
VueComponent()
的实例对象,简称vc (也可称之为:组件实例对象)
Vue()
的实例对象,简称vm。
对vm和vc的理解:
1、 vm 和 vc 长得差不多(属性和方法都一样的),因为 Vue(options)
和 VueComponent(options)
两个构造函数,在源码中都是调用了其原型上 的 _init(options)
2、 vm 或 vc 的 $children
属性以数组 形式保存着 vm 或 vc 所管理的组件 或子组件 的实例对象
3、 组件是可复用 的 Vue 实例(vm),所以它们与 new Vue()
接收相同的配置选项 options ,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。
**4、**vc 由 vm 管理,vc 没有 el 配置,只有 vm 能通过 el 配置来指定为谁服务
重要内置关系 {#重要内置关系}
VueComponent.prototype.proto = Vue.prototype
复习原型与原型链 :JavaScript基础笔记(3)---原型与原型链
$mount、$watch 等属性和方法都在 Vue.prototype 上,也就是 Vue 的原型上
作用: 这个重要的内置关系将组件的原型 与Vue的原型 通过 proto 相连,使 VueComponent 继承 Vue原型,让组件实例顺着原型链也能使用$mount、$watch 等属性和方法,
目的: 让组件实例对象 (vc)可以访问到Vue原型上的属性、方法
单文件组件 {#单文件组件}
单文件组件: 一个文件中仅包含一个组件,文件后缀为 .vue
浏览器并不认识.vue文件,需要通过 webpack 或脚手架 ,将其加工为JS文件
文件名推荐规则: 单个单词大写 ,多个单词双驼峰
.vue文件中代码分为三个标签:
<template>
=> 组件的结构<script>
=> 组件交互相关代码,包含组件所用的数据、方法<style>
=> 组件的样式
主要的文件: 需放入脚手架中才能运行
1、xxx.vue 各种组件
2、App.vue 汇总所有组件
3、main.js 入口文件,创建Vue实例,注册App组件并应用
4、index.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
| <template> <!-- 组件的结构 --> <div class="student"> <h2>{{ name }}}</h2> <h3>{{ age }}}</h3> </div> </template> <script> // 组件交互相关代码 // 省略Vue.extend,直接暴露组件的配置对象 export default { name: 'Student', //最好与文件名保持一致 data() { return { name: 'chuckle', age: '19' } } } </script> <style> /* 组件的样式 */ .student { background: #ccc; border-radius: 8px; } </style>
|
必须有 App.vue 汇总所有组件
|------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <template> <div> <School></School> </div> </template> <script> // 引入Student组件 import School from "./Student.vue" export default { name: "App", components: { School } } </script> <style></style>
|
main.js 入口文件,创建Vue实例,注册App组件并应用
|------------------------------|-----------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10
| import App from "./App.vue" // 引入App组件 new Vue({ el: '#root', template: '<App></App>', components: { App } })
|
index.html 页面
|------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <!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> </head> <body> <!-- 准备一个容器 --> <div id="root"></div> <!-- 引入vue文件 --> <script src="../../js/vue.js"></script> <!-- 引入入口文件 --> <script src="./main.js"></script> </body> </html>
|
脚手架Vue-cli {#脚手架Vue-cli}
Vue 脚手架是 Vue 官方提供的标准化开发工具(开发平台)
Vue 有多种脚手架,Vue-cli 是其中一种
起步 {#起步}
安装: 该全局模块会暴露一个全局命令vue
|-----------|---------------------------------|
| 1
| npm install -g @vue/cli
|
创建一个项目
|-----------|--------------------------|
| 1
| vue create <项目名>
|
选择项目的vue版本,babel用于ES6转ES5,eslint语法检查
|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5
| Vue CLI v5.0.8 ? Please pick a preset: Default ([Vue 3] babel, eslint) > Default ([Vue 2] babel, eslint) Manually select features
|
等待安装完毕,运行项目
|-----------|-----------------------|
| 1
| npm run serve
|
项目文件结构 {#项目文件结构}
默认 HelloWord 项目结构:
|---------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| ├─ public │ ├─ favicon.ico │ └─ index.html │ ├─ src │ ├─ assets │ │ └─ logo.png │ ├─ components │ │ └─ HelloWorld.vue │ ├─ App.vue │ └─ main.js │ ├─ .gitignore ├─ vue.config.js ├─ babel.config.js ├─ jsconfig.json ├─ package-lock.json ├─ package.json
|
文件解释:
1、 根目录中的一些配置文件:
- babel.config.js babel控制文件,脚手架已写好,无需再动
- package.json 定义了当前项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等)
- package-lock.json 锁定所有模块的版本号,包括主模块和所有依赖子模块
- .gitignore git忽略文件配置
- jsconfig.json 指定根文件和JavaScript语言服务提供的功能选项,明确项目的文件范围
- vue.config.js 一个可选的脚手架配置文件,进行vue项目本地运行和构建相关配置,若根目录中存在这个文件,它会被 @vue/cli-service 自动加载
2、src文件夹: 有些熟悉的文件,main.js入口文件、app.vue组件等
- assets文件夹: 存放静态资源
- **components:**存放组件,除了App组件
main.js有一些变化
|---------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| // 整个项目的入口文件 // 引入Vue import Vue from 'vue' // 引入App组件,是所有组件的父组件 import App from './App.vue' // 关闭Vue的生产环境提示 Vue.config.productionTip = false // 创建Vue实例对象 new Vue({ // 将App组件放入容器中 render: h => h(App), }).$mount('#app') // 绑定容器
|
**3、public文件夹:**页面的根目录,存放了index.html和ico图标
**应该知道:**main.js之所以是入口文件,而且它能找到public中的index.html去绑定容器,是脚手架配置、规定的
render函数 {#render函数}
在 main.js 中,render: h => h(App)
作用是将App组件放入容器中
若使用之前的模板写法,控制台会报错 模板写法
|---------------------------|-----------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9
| import App from "./App.vue" // 引入App组件 new Vue({ el: '#root', template: '<App></App>', components: { App } })
|
报错内容: [vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
**意思是:**正在使用Vue的仅运行时版本(runtime模式),其中模板编译器不可用。将模板预编译为render函数,或者使用包含编译器的内部版本。
问题原因:
Vue包含两个部分,核心部分 与模板解析器 ,核心部分是生命周期与各种属性与函数,模板解析器用于解析模板,当通过cdn引入来使用Vue时,应该将两者都引入,但如果使用脚手架、webpack将.vue文件都翻译为.js文件,且模板都已经解析为html ,模板解析器在生产环境就没有用了
因为Vue中不是所有部分都在生产环境中用到,且模板解析器占Vue体积的三分之一,所以Vue除了完整版,还有许多精简版,带模板解析器的称为 compiler(模板)模式 ,反之称为 runtime(运行时)模式
(1) vue.js 是完整版Vue,包含:核心功能+模板解析器
(2) vue.runtime.xxx.js 是运行版Vue,只包含核心功能,没有模板解析器
通过 import Vue from 'vue'
引入的就是不带模板解析器的精简版,vue模块的package.json的main/model字段默认为runtime模式,指向了"dist/vue.runtime.common.js"。
解决办法一:引入完整版Vue,不推荐
|-----------|-------------------------------------------|
| 1
| import Vue from 'vue/dist/vue.js'
|
解决办法二 :使用渲染函数 render()
代替模板写法
render 配置项是一个函数,传入 createElement 参数也是一个函数
createElement()
可以创建具体的元素,可以传入一个组件 或是 ('标签名','标签内容')
的形式 ,返回创建好的元素
Vue会调用 render()
并接收其返回值,将 createElement()
的返回值(创建好的元素)返回即可
|---------------------|-----------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6
| // 完整写法 render(createElement) { return createElement('h1', '你好啊') } // 箭头函数简写 render: h => h(App)
|
注意: 在开发环境中有 vue-cli 自带有 vue-template-compiler 插件,能解析 .vue 文件中的 <template></template>
模板,但写在配置对象 template 属性中的模板没有插件能解析,所以要使用 render()
以后一般也只有在创建vm时配置项里会用到render
自定义脚手架配置 {#自定义脚手架配置}
脚手架默认使用main.js作为入口文件等默认配置都在一个文件中,该文件被隐藏了起来
使用命令导出、查看脚手架配置文件的拷贝
|-----------|---------------------------------|
| 1
| vue inspect > output.js
|
在vue-cli配置参考项中查看可配置项
在 vue.config.js 文件中进行自定义配置
|-------------------|--------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5
| // vue.config.js const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ // 配置选项 })
|
ref标签属性 {#ref标签属性}
替代 id 属性给元素或子组件 注册引用信息(打标识)
给元素标签 或组件标签 添加 ref 属性,就能在组件实例对象的 $refs 上获取dom元素 或子组件实例对象
|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7
| <!-- 打标识 --> <h1 v-text="msg" ref="xxx"></h1> <School ref="xxx"></School> <!-- 获取dom元素或子组件vc --> <script> this.$refs.xxx </script>
|
|---------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 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
| <template> <div> <h1 v-text="msg" ref="title"></h1> <button @click="showTitle">显示/隐藏标题</button> <School></School> </div> </template> <script> import School from "./components/school.vue"; export default { name: "App", components: { School, }, data() { return { msg: "学校信息", }; }, methods: { showTitle() { this.$refs.title.classList.toggle('hide'); }, }, }; </script> <style> .hide { opacity: 0; } </style>
|
props配置项 {#props配置项}
子组件的 props 配置项接收父组件通过组件标签传入的数据
**作用:**实现父组件与子组件的通信
通过标签属性给子组件传数据:
注意:
- 普通属性传的是字符串 ,要传入其它数据类型 的属性,需要 v-bind 绑定属性,传入表达式的值
- 传入引用数据类型时,传的是引用,浅拷贝
|-----------|--------------------------------------------------------------|
| 1
| <Student name="chuckle" sex="男" :age="18"></Student>
|
子组件接收数据,三种写法
|------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| // 简单接收,不对数据类型进行限制 props: ['name', 'age', 'sex'] // 接收同时限制数据类型 props: { name: String, age: Number, sex: String } // 更多配置,必须的、默认值等 props: { name: { type: String, required: true // 必须的 }, age: { type: Number, required: true // 必须的 }, sex: { type: String, default: "男" } }
|
props 接收到的数据会代理到 vc 身上,但不允许修改 只能读取(直接修改也有效果,但控制台会发出警告),所以也不能使用 v-model 绑定
若需修改,应先将数据拷贝到data中,用一个新属性接收
|-------------------|-----------------------------------------------------|
| 1 2 3 4 5
| data() { return { myAge: this.age + 1 }; },
|
mixins混入 {#mixins混入}
多个相似组件中通常会有重复的配置项,可以将这些配置项提取成一个混入对象,给这些组件引入复用(混入)
将相同的配置项提取至 mixin.js mixin.js
|---------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| export const mixin1 = { data(){ return { x: 100, y: 200 } } } export const mixin2 = { data() { return { name: '', } }, methods: { showName(){ console.log(this.name); } }, }
|
组件通过 mixins 配置项引入 mixin.js 中的配置
Vue会将这些外部的配置混入 组件的同名配置中(混合合并),配置中重复的属性保留组件中的
mixins: []
局部混入
局部组件混入
|---------------------|----------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6
| // 引入混入对象文件 import {mixin1, mixin2} from '../mixin.js'; export default { // 局部混入 mixins: [mixin1,mixin2], };
|
Vue.mixin()
全局混入
在main.js中全局混入,给所有组件
|---------------|-----------------------------------------------------------------------------------------|
| 1 2 3
| import {mixin1, mixin2} from '../mixin.js'; Vue.mixin(mixin1) Vue.mixin(mixin2)
|
插件 {#插件}
Vue中插件本质是一个对象,对象中必须有一个 install()
方法
在 plugins.js 或其它名字的独立js文件中定义插件
|-------------------|----------------------------------------------------------------|
| 1 2 3 4 5
| export default { install(){ console.log('这是一个插件'); } }
|
在 main.js 中导入并使用 Vue.use()
应用插件
|-----------------|----------------------------------------------------------------------------|
| 1 2 3 4
| // 导入插件 import plugins from "./plugins"; // 使用插件 Vue.use(plugins);
|
插件对象的 install()
方法默认第一个参数 接收 Vue构造函数 作为参数,在插件中可以进行各种全局配置以及在原型上添加属性和方法
plugins.js
|------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 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
| import {mixin1, mixin2} from './mixin.js'; export default { // 第一个参数接收Vue构造函数作为参数 install(Vue){ // 配置全局过滤器 Vue.filter('interceptStr',(value, num=4)=>{ return value.slice(0,num) }) // 注册全局自定义指令 Vue.directive('inHtml', function(el, binding){ el.innerHTML = binding.value }) // 应用全局混入 Vue.mixin(mixin1) Vue.mixin(mixin2) // 在Vue原型上添加属性和方法 Vue.prototype.hello = function(){ console.log('Hello') } } }
|
自定义参数:
Vue.use()
使用插件时也可以传入其它参数,会被 install()
方法接收,第一个参数仍然是 Vue构造函数
|-------------------|-----------------------------------------------------------------------------------------------------|
| 1 2 3 4 5
| // 传入三个自定义参数,三个数字 Vue.use(plugins,1,2,3); install(Vue,a,b,c){ console.log(a,b,c);// 1 2 3 }
|
scoped样式 {#scoped样式}
多个组件有多个 style 标签,所有组件样式都会汇总到一个 CSS 文件中
当组件中有相同类名时,样式就会冲突,可以给组件的 style 标签加上 scoped 属性解决冲突
**作用:**让样式仅在当前组件中生效,防止样式冲突
原理: 当style标签加上 scoped 属性后,Vue会给该组件所有标签元素都加上一个随机的 data-v 属性,css选择器也会自动选择 data-v
|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6
| <div data-v-22321ebb="" class="demo"> <h2 data-v-22321ebb="">学生姓名:chuckle</h2> <h2 data-v-22321ebb="">学生性别:男</h2> <h2 data-v-22321ebb="">学生年龄:19</h2> <hr data-v-22321ebb=""> </div>
|
|---------------|-------------------------------------------------------------------|
| 1 2 3
| .demo[data-v-22321ebb] { background: rgb(78, 180, 220); }
|
注意: 一般在 App.vue 的 style 标签中写全局共用样式,所以 App 不适合加 scoped
更多: style 标签的 lang 属性可以指定 CSS 预处理语言,常用 less ,使用 less 前需要安装 less-loader 用于解析 less
|-------------|---------------------------------------------|
| 1 2
| <style lang="less" scoped> </style>
|