Article directory
- 1. vue command
- 2. Virtual DOM and Diff algorithm
- 3. Calculated properties
- 4. Monitoring attributes
- 5. Components
- 6. ref attribute and $nextTick
- 7. Dynamic components
- 8. Slot
- 9. Life cycle
- 10. Routing
- 11. Vuex
1. vue command
- vue instructions are
封装的 DOM 操作
, all starting with v-
(1) Introduction to vue instructions
vue directive | grammar | abbreviation | effect |
---|---|---|---|
v-bind | v-bind:k=‘Variable name’ | : | Dynamically set html tag attributes |
v-on | v-on:event='A small amount of code' v-on:event='Function name' v-on:event=' Function name (parameter 1, parameter 2...)' |
@ | Registration issue |
v-show | v-show=‘boolean’ | none | restraintcss样式'display:none' ,operation frequency |
v-if | v-if=‘boolean’ v-if=‘条件’ |
none | Dynamic创建或删除元素节点 , the node needs to be deleted when hiding |
v-else-if | v-else-if=‘boolean’ v-else-if=‘条件’ |
none | Tied with v-if |
v-else | v-else=‘boolean’ v-else=‘条件’ |
none | Tied with v-if |
v-mode:value | v-model=‘Variable value’ | v-model | For form elements, two-way data binding is implemented to quickly obtain or set the form. |
v-text | v-text=‘value’ | none | innerText does not parse labels and is not commonly used. Interpolation expressions are generally used. |
v-html | v-html=‘value’ | none | innerHTML parses tags and prohibits using user input directly as value, which can easily cause XSS attacks |
v-for | v-for=‘item in arr’ v-for=‘(item, index) in arr’ |
none | Traverse the array, used to render the structure (important) |
v-for | v-for=‘(val, k) in obj’ | none | Traverse objects, used to render structures (understand) |
v-for | v-for=‘item in number’ | none | Traverse numbers for rendering structures (understand) |
(2) Vue command supplement
1、v-on
- Get event object
- No parameters passed: formal parameter receives e
- There are parameters passed: $event refers to e
- event modifier
- Prevent default behavior: @event.prevent(e.preventDefault())
- Stop bubbling: @event.stop(e.stopPropagation())
- Key modification: @event.key (@keyup.enter)
- Native event: @event.native
2、v-model
(1)v-model
- Essence: The abbreviation of
v-model:value
, usually used for双向数据绑定
on the form, can also realize bidirectional data from child components to parent components动态绑定
- modifier
- .number: Convert to numeric type using parseFloat
- .trim: remove the first whitespace character
- .lazy: triggered when change (enter or lose focus), not triggered by input
// 1、父组件
// 底层
<demo :value='money' @input=money=$event'></demo>
// 简写
<demo v-model='money'></demo>
// 2、子组件
export default{
props:{
value: Number // 必须叫 value
},
methods:{
add(){
this.$emit('input', this.value+1) //必须叫 input,this.value+1 是参数
}
}
}
(2):model
- Essence: Abbreviation of
v-bind:model
,父组件的值传递给子组件
. But if the child component changes引用类型
data, the data of the parent component will also change
(3) Custom instructions
1. Partial registration
// 组件内设置
<input type='text' v-focus>
export default{
directives:{
focus:{
// 定义指令名时无需加 v-
inserted(el){
// 当指令所在的元素节点被插入到页面触发,DOM 解析完成
el.focus() // element,指令所在的元素节点
}
}
}
}
2. Global registration
- Vue.directive(directive name, directive configuration object (element, directive value))
// main.js 内设置
<input type='text' v-focus v-color='color'>
Vue.directive('color', {
inserted(el, binding){
// 当指令所在的元素节点被插入到页面触发,DOM 解析完成
el.style.color = binding.value // 指令的值
}
update(el, binding){
// 当指令绑定的值修改时触发
el.style.color = binding.value // 指令的值
}
})
2. Virtual DOM and Diff algorithm
(1) In-situ reuse
- Definition: Vue compares the virtual DOM locally (at the same level and at the same location) as much as possible, reuses the old DOM structure, and performs differentiated updates.
- Advantages: Reuse old dom structure and update efficiently
(2) Virtual DOM
- Essence: Save node information,
描述真实 DOM 的 JS 对象
- Function: Improve contrast performance
(3) Diff algorithm
- Comparison of root elements at the same level
- Root element changes: regardless of reuse, the entire DOM tree is deleted and rebuilt.
- The root element remains unchanged: compare attribute changes and reuse downward recursively
- Comparison of sibling elements at the same level
- No key: Default
按照下标
Compare - Set key: Prioritize elements with the same key for comparison and reuse
- key characteristic: required
字符串
or数字
, and security唯一性
(general id) - Key function: Improve the comparison and reusability of virtual DOM
- key characteristic: required
- No key: Default
3. Calculated properties
(1) Understanding
- Definition: a special
属性
whose value is dynamically calculated depending on some data - Notice
- Must be defined in the computed node
- Must be a function and must have a return value
- Cannot be called as a method, used as an attribute
- Features
- Cache immediately after calculation and read directly next time
- Dependencies change, function re-executed and re-cached
- Use computed properties multiple times with extremely high performance
(2) Complete writing method
- By default, calculated properties can only be obtained and cannot be modified.
- Assigning a value to a computed property requires complete writing
computed:{
full:{
get(){
},
set(val){
}
}
}
4. Monitoring attributes
watch: {
// 1、监视简单数据类型
'money' (oldVal, newVal) {
console.log(`银行卡余额为${
newVal},原${
oldVal}`)
},
'obj.age' (oldVal, newVal) {
// 监视复杂数据的属性必须用括号包裹
console.log(`长大了,今年${
newVal}岁,之前${
oldVal}岁`)
},
// 2、监视复杂数据类型
person: {
immediate: true, // 立即执行,一进页面立刻执行
deep: true, // 复杂数据深度监视
handler (newVal) {
// handler 执行函数,新旧值一致
console.log(newVal)
}
}
}
5. Components
(1) Vue component
- component: reusable Vue instance, encapsulating
标签
,样式
andJS 代码
- Purpose: reuse, disassembly
- Advantages: independent, easy to reuse, high maintainability
- Component development: Encapsulation idea, encapsulate repeated parts on the page into components to facilitate project development and maintenance
1. Partial registration
- Create: Create .vue (tag/style/JS) in the component
- Introduction: introduced into the component
- Registration: Register in the component
- Tags: used in components
2. Global registration
- Create: Create .vue (tag/style/JS) in the component
- Introduction: introduced in main.js
- Registration: Register in main.js
- Tags: used in components
(2) Component communication
- The data of each component is independent, and the data between components cannot directly access each other. Component communication enables cross-component data access.
1. Pass from father to son
- Add parent component to child component
标签属性
Pass value - The sub-component internally receives data through
props
只读
// 父组件
<MyHome>
v-for='item in list'
:key='item.id'
:title='item.proname'
:price='item.proprice'
:info='item.desc'
:pid='item.id'
</MyHome>
// 子组件
props:['title','price','info','pid']
- props verification: In order to improve the stability of subcomponents when used, whether
验证传递数据
meets the requirements
props: {
// 1、基础类型检查 Number String Boolean Object Array Function...
data:Array,
money:Number,
// 2、多个可能类型 [String, Number,...]
params:[String, Number,Boolean],
// 3、必填项(要求用户必须填写,否则报错)
age:{
type:Number,
required:true
},
// 4、默认值(用户选填,不填则使用默认值)
title:{
type:String,
default:'大标题'
}
}
- One-way data flow: one-way data flow from parent to child, resolved by application initiated from child to parent.
2, child father
- The subcomponent passes
this.$emit('自定义event',参数,this.id)
to trigger the event and pass parameters at the same time - The parent component registers the corresponding custom event for the child component
<Son @自定义event='fn(参数,id)'></Son>
6. ref attribute and $nextTick
(1) ref and $refs
- Function: Get the dom element or component instance
- the difference
- document.querySelector: Search the entire document without distinguishing components, and has a wide range of effects
- ref and $refs: search
当前整个组件
, with search scope
// 1、目标元素添加 ref 属性
<h1 ref='myH1'>ref获取原生DOM</h1>
<MySon ref='son'>ref获取组件实例</MySon>
// 2、通过 this.$refs.xxx 获取元素/组件
console.log(this.$refs.myH1)
console.log(this.$refs.son.属性/方法)
(2) $nextTick
- Background: Vue updates the DOM asynchronously, that is, it updates it together after the current main thread code is executed. It cannot update the DOM immediately after modifying the data.
- Solution principle: After the macro task is completed, check the micro task first,
浏览器完成更新渲染
, and then execute the next macro task
1、setTimeout()
setTimeout(() => {
// setTimeout()为宏任务,执行此代码前浏览器完成更新渲染
}, 0)
2、$nextTick()
this.$nextTick(() => {
// DOM 更新完毕后立即执行此代码
})
7. Dynamic components
- Definition: A component that can be changed to solve the needs of
多组件同一位置切换显示
- grammar
component组件(显示位置)
+is属性(具体组件)
- Modify the is attribute binding value to switch components
<component :is='要显示的组件'/>
- step
- Prepare components to be switched and introduce registration
- Prepare the variable comName to carry the component name to be displayed
- Set the mount point
<component>
, js attribute sets the component to be displayed (component + is) - Click event-modify the component name in the comName variable (modify the value of is)
8. Slot
- props: used
传值
to solve simple scene component customization - Slot: used
传结构
to solve custom scene component customization - basic grammar
- Placeholder within component:
<slot></slot>
- Working with components: writing the actual code structure
- Backup content: content placed in the slot tag, displayed by default when no external structure is passed
- Placeholder within component:
(1) Named slot
- Default slot: undefined name, default name is default
- Named slot: Customize the name through name to achieve targeted distribution
// 1、组件内多处 slot 需要外部传入标签,通过 name 属性进行定制
<slot name='first'></slot>
<slot name='second'></slot>
// 2、template 配合 v-slot:名字/#名字 分发标签
<template v-slot:first>
<p>一个slot结构</p>
</template>
<template #second> // v-slot: 简写为 #
<p>另一个slot结构</p>
</template>
(2) Scope slot
- The slot passes values and carries parameters
添加属性
- Collect all added properties into an object
- Component user receives through
=
, only used within the current template scope
<slot name='first' title='我是标题' desc='我是描述'></slot>
<slot name='second' :change='change' :edit='edit' money='100'></slot>
<template #first='obj'>
<p>{
{
obj.title}}</p>
<p>{
{
obj.desc}}</p>
</template>
<template #second='{change, edit, money}'> // 结构数据
<button>{
{
change}}</button>
<button>{
{
edit}}</button>
<p>{
{
money}}</p>
</template>
9. Life cycle
- Life cycle function: Vue’s built-in function, accompanying the component life cycle
自动按序执行
- Initialization phase: combine data, combine templates, render views
- beforeCreate(): The data data has not been initialized, and the data has not been bound to the vue instance.
created()
:data 数据完成初始化
, data is successfully bound on the vue instance
- Data update phase: data changes, view updates
- beforeMount(): The page structure has not completed parsing and rendering, and the DOM cannot be obtained.
mounted()
:页面结构完成解析渲染
, can get DOM- beforeUpdate(): Since vue updates the DOM asynchronously after the data changes, the DOM has not been updated yet.
- updated(): The DOM is updated after the data changes.
- Component destruction phase
- beforeDestory(): Before instance destruction and resource release (timer, delayer, server resources)
destoryed()
: After the instance is destroyed and resources are released (timer, delayer, server resources)
10. Routing
- Definition: Mapping relationship between paths and components
(1) vue-router
- Definition: vue official routing plug-in
[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-b8WjLauG-1669287358087)(./vue-router.png)]
1. Basic use
- Download the package: Download the vue-router module to the current project, vue2 uses the @3 version
- Introduction: VueRouter is introduced into main.js
- Registration: added to Vue.use(), internal initialization of the plug-in, registration of global components and instructions
- Example: Create routing component
- Mount: Inject the routing object into the new Vue instance
规则
: Correspondence between configuration paths and components in routing instances出口
:Rendering position of router-view in App.vue
2. Operation skills
- @ refers to the src directory. Files can be found directly from src to improve maintainability.
- Encapsulation and extraction: extract the routing module to @/router/index.js to split the module and facilitate maintenance.
(2) Configuration page
1. Route redirection
- Definition: After matching path,
redirect
forces a jump to path path
const routes = [
{
path:'/',
redirect:'/home'
}
]
2. Configuration page 404
- Definition: When no path match is found,
component
provides a page error prompt
const routes = [
...,
{
// 放在路由最后
path:'*', // 匹配任意路径,前面不匹配命中最后规则
component:NotFound
}
]
3. Routing mode
- hash routing
const router = new VueRouter({
mode:'hash', // 默认
routes
})
- history routing (server support is required to go online)
const router = new VueRouter({
mode:'history',
routes
})
(3) Jump method
1. Declarative Navigation
(1) Navigation links
- component
router-link
replaces the a tag, comes with an activation class name, and can be highlighted- Fuzzy match: router-link-active
- Exact match: router-link-exact-active
<router-link to='/home'>首页</router-link>
<router-link to='/my'>我的</router-link>
<router-link to='/part'>朋友</router-link>
(2) Jump parameter transfer
- Goal: Pass values to the corresponding components when jumping routes
- query parameters
- Passing parameters: router-link’s to=‘/path?k=val&k=val’
- Contact:
$route
.query.k
- Dynamic routing parameters
- Routing object configuration path:‘/path/:k/:k’
- Passing parameters: router-link’s to=‘/path/val&val’
- 接收:
$route
.params.k
(3) Jump cache
- Background: The page is destroyed/rebuilt by default when switching routes, and the user's physical examination is not good when switching pages.
- Plan: Use
<keep-alive>
to wrap router-link for caching - Impact: Two hooks are generated
- activated: The cache component is activated
- deactivated: The cache component is hidden
2. Programmatic navigation
(1) Basic jump
- JS code
path 跳转
this.$router.push({
path:'路由路径', // router/index.js 内定义
'路由路径', // 简写形式
})
- JS code
name 跳转
this.$router.push({
name:'路由名', // router/index.js 内定义
})
- JS code go jump
this.$router.go(n) // n 正负数代表前进或后退步数
- Notice
- router: the entire large routing instance, which can be used for routing jumps, equivalent to this.$router
- route: related to routing rules, equivalent to this.$route
(2) Jump parameter transfer
path 仅支持 query 传参
, ignore params
this.$router.push({
path:'路由名', // path 带参数
query:{
'k':val,
'k':val
}
})
this.$router.push({
'路由名?k=val&k=val'}) // path 带参数简写
this.$router.push({
path:'路由名', // path 带参数
query:{
'k':val
},
params:{
// params 即使存在也被忽略
'k':val
}
})
- name supports query and params passing parameters, but params passing parameters will disappear when refreshed
this.$router.push({
path:'路由名', // path 带参数
query:{
// 拼接在地址栏,刷新不会丢失
'k':val,
'k':val
}
})
this.$router.push({
name:'路由名', // path 带参数
params:{
// 地址栏不显示,基于内存刷新会消失,需要配合本地存储进行持久化
'k':val,
'k':val,
}
})
(4) Page routing parameters
1. Dynamic routing parameters (elegant)
- Configure routing:
路径携带参数
{
path:'/user/:k', component:xxx}
- Jump: path only (including parameters)
<router-link to='/user/val'></router-link> // 标签方式跳转
this.$router.push('/user/val') // JS 方式跳转,简洁版
this.$router.push({
// JS 方式跳转,复杂版
path:'/user/val'
})
- Get parameters
this.$route.params.k
2. Query parameter passing (multiple parameters)
- Routing: No special configuration required
{
path:'/user', component:xxx} // 忽略
- Jump to:
携带查询参数
<router-link to='/user/?k=val'></router-link> // 标签方式跳转
this.$router.push('/user/?k=val') // JS 方式跳转,简洁版
this.$router.push({
// JS 方式跳转,复杂版
path:'/user',
query:{
k:val},
params:{
k:val} // params 被忽略
})
- Parameter acquisition
this.$route.query.id
3. params passing parameters (understanding)
- Routing: extra
配置 name
{
path:'/user', name:'user', component:xxx} // 配置 name
- Jump: Jump by name
this.$router.push({
name:'user',
query:{
k:val},
params:{
k:val}
})
- Parameter acquisition: parameter transfer based on memory, refresh is lost
this.$route.params.k // 刷新会丢失,不显示在地址栏,基于内存
11. Vuex
(I. Overview
- vuex: vue’s status (data) management tool, centrally manages the data in vue
通用
- Effect: Solution
多组件状态共享
Question - advantage
- Responsive changes
- Operation is simpler
(2) Basic use
1. Create a warehouse
- Install
yarn add vuex@3.x.x
- Create a new store/index.js to store vuex
- Create a warehouse store/index.js
// 导入 vue
import Vue from 'vue'
// 导入 vuex
import Vuex from 'vuex'
// vuex也是vue的插件, 需要use一下, 进行插件的安装初始化
Vue.use(Vuex)
// 创建仓库 store,基于Vuex里的Store构造函数创建仓库实例
const store = new Vuex.Store()
// 导出仓库
export default store
- Import and mount it to the Vue instance in main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store
}).$mount('#app')
From now on, an empty warehouse has been successfully created !!
2. state state
(1) Basic use
- Definition: A warehouse that stores data
- Features: State provides uniqueness
公共数据源
, and all shared data is unified into the State storage in the Store- data: data within the component
- state: vue project public data
- provide data
// 创建仓库 store
const store = new Vuex.Store({
state: {
count: 101
}
})
(2) Native syntax - interpolation expression
- retrieve data:
this.$store.state.属性
<h1>state 的数据 - {
{
$store.state.count }}</h1> // 原始复杂写法
- Define the state attribute in the calculated attribute to simplify the interpolation syntax
<h1>state 的数据 - {
{
count }}</h1> // 简化后的插值语法
computed: {
count () {
// 可以使用 mapState 辅助函数简化
return this.$store.state.count
}
}
(3) Auxiliary function - mapState
- Get data: The mapState helper function maps data in the store to the component's computed properties.
- Import mapState
import {
mapState } from 'vuex'
<h1>state 的数据 - {
{
count }}</h1> // 简化后的插值语法
computed: {
...mapState(['count']) // 利用展开运算符将导出的状态映射给计算属性,
// 防止 mapState 辅助函数独占计算属性
}
3、mutations
(1) Basic use
- Definition: A method of storing operation data
- Background: Vuex follows a one-way data flow, state data modification can only be through mutations, and mutations must be synchronous
- Provide method
// 提供 mutations 函数
const store = new Vuex.Store({
state: {
count: 0
},
// 定义mutations
mutations: {
// 第一个参数是当前store的state属性(固定)
addOne (state {
state.count ++ // 通过形参 state 拿到仓库 store 数据
}
},
})
// 调用方法
this.$store.commit('addOne')
(2) Carrying parameters
- Provide mutations method
const store = new Vuex.Store({
state: {
count: 0
},
// 定义mutations
mutations: {
// 第一个参数是当前store的state属性(固定)
addOne (state {
state.count ++ // 通过形参 state 拿到仓库 store 数据
}
// 第二个参数payload额外参数,调用mutaiions的时候传参(一次提交仅限携带一个参数,但参数类型不限,支持数组、对象等)
addNth (state, payload) {
state.count += payload
}
},
})
- Registration issue
<input type="text" :value="count" @input="fn">
- call method
fn(e){
this.$store.commit('addNth', +e.target.value) // 请求参数
}
(3) Auxiliary function - mapMutations
- Original code
methods: {
subOne () {
this.$store.commit('subOne')
},
subNth (n) {
this.$store.commit('subOne', n) // commit(方法名, 载荷参数)
}
}
- import mapMutations
import {
mapMutations } from 'vuex'
methods: {
...mapMutations(['subOne', 'subNth'])
}
- transfer
<button @click="subOne">值+1</button> // 无参数
<button @click="subNth(n)">值+1</button> // 携带参数
4、actions
(1) Basic use
- Definition: A method for storing asynchronous operations. Data cannot be modified directly.
actions: {
setAsyncCount (context, num) {
// 一秒后, 给一个数, 去修改 num
setTimeout(() => {
context.commit('inputCount', num)
}, 1000)
}
},
(2) Original call
- $store (supports parameter passing)
setAsyncCount () {
this.$store.dispatch('setAsyncCount', 200)
}
(3) Auxiliary function - mapActions
import {
mapActions } from 'vuex'
<button @click="setAsyncCount(200)">+异步</button>
methods: {
...mapActions(['setAsyncCount'])
}
5、getters
(1) Basic use
- Definition: Store some calculated properties based on state
state: {
list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
},
getters: {
// getters函数的第一个参数是 state
// 必须要有返回值
filterList: state => state.list.filter(item => item > 5)
}
(2) Original way - $store
<div>{
{ $store.getters.filterList }}</div>
(3) Auxiliary function - mapGetters
<div>{
{
filterList }}</div>
computed: {
...mapGetters(['filterList'])
}
6. Modules modules (important)
- Definition: In order to solve the problem of bloated store objects, @/store/module/xx.js is established to modularize Vuex
(1) Module definition
- Prepare state and define two modules user and setting
- Manage the user's information status in user userInfo
modules/user.js
const state = {
userInfo: {
name: 'zs',
age: 18
}
}
const mutations = {
}
const actions = {
}
const getters = {
}
export default {
state,
mutations,
actions,
getters
}
- The name of the management project application in setting title, desc
modules/setting.js
const state = {
title: '这是大标题',
desc: '描述真呀真不错'
}
const mutations = {
}
const actions = {
}
const getters = {
}
export default {
state,
mutations,
actions,
getters
}
- Use data from modules
- Can be accessed directly through the module name
$store.state.模块名.xxx
=>$store.state.setting.title
- Can be mapped through mapState
- Can be accessed directly through the module name
(2) Namespace namespaced
- By default, the actions, mutations and getters inside the module are registered in
全局命名空间
and configurednamespaced
to ensure the high closure of the internal module
const state = {
userInfo: {
name: 'zs',
age: 18
},
myMsg: '我的数据'
}
const mutations = {
updateMsg (state, msg) {
state.myMsg = msg
}
}
const actions = {
}
const getters = {
}
export default {
namespaced: true, // 配置命名空间
state,
mutations,
actions,
getters
}
- Commit mutations in modules
全局: this.$store.commit('mutation函数名', 参数)
模块: this.$store.commit('模块名/mutation函数名', 参数)
- After namespaced: true, you can add the module name to add mapping and find the state/mutations/actions/getters of the corresponding module.
computed: {
// 全局的
...mapState(['count']),
// 模块中的
...mapState('user', ['myMsg']),
},
methods: {
// 全局的
...mapMutations(['addCount'])
// 模块中的
...mapMutations('user', ['updateMsg'])
}