Article Directory
- Vue creates elementUI project
- Two major features of Vue
- Vue directives
-
-
- 1. Content rendering instruction: used to assist developers in rendering the text content of DOM elements
- 2. Attribute binding instructions (note: interpolation expressions can only be used in the content node of the element, not in the attribute node of the element!)
- 3. Event binding
- 4. The v-model directive
- 5. Conditional rendering instructions
- 6. Loop rendering instructions
-
- listener (watch)
- Computed property (computed)
- axios
- Use of vue-cli
- Three steps to use components
- Register global components
- Component props
- scoped and deep
- Component life cycle
- Data Sharing Between Components
- ref reference
- this.$nextTick(cb) method
- Dynamic Component Rendering
- slot
- custom directive
- Mount axios on the Vue prototype
- routing
Vue creates elementUI project
vue create my-app
cd my-app
vue add element-plus
Two major features of Vue
-
Data Driven View
- Data changes will drive the view to automatically update
- Benefits: Programmers only need to maintain the data, then the page structure will be automatically rendered by vue
-
two-way data binding
- In web pages, the form form is responsible for collecting data, and Ajax is responsible for submitting data
- The change of js data will be automatically rendered on the page
- When the data of the financial season in the form on the page changes, it will be automatically obtained by vue and updated to the js data
Note: The underlying principle of data-driven view and data two-way data binding is MVVM (Model data source, View view, ViewModle is an instance of Vue)
Vue directives
1. Content rendering instruction: used to assist developers in rendering the text content of DOM elements
- v-text (hardly used)
- Disadvantage: it will overwrite the original content inside the element
- { {}} Interpolation expression (Mustache) (used more)
- v-html: can render tagged strings into real HTML content
2. Attribute binding instructions (note: interpolation expressions can only be used in the content node of the element, not in the attribute node of the element!)
- v-bind can dynamically bind values for the attributes of elements, abbreviated as colons ( : )
- During binding with the v-bind attribute, if the binding content needs to be spliced dynamically, the string should be wrapped in single quotes
3. Event binding
- v-on: The abbreviation is @
- The syntax format is:
<button @click="add"></button>
methods: {
add() {
this.count += 1
}
}
- Application scenario of event: If the default event object e is overridden, you can manually pass an event Application scenario: If the default event object e is overwritten, you can manually pass oneApplication scenarios of e v e n t:If the default event object e is overridden , _You can manually pass an event
<button @click="add(3, $evnet)"></button>
methods: {
add(n, e) {
this.count += 1
}
}
-
event modifier
- .prevent prevents the default event
<a @click.prevent="xxx">url</a>
- .stop prevents bubbling events
<button @click.stop="xxx">button</button>
- .capture triggers the current time processing function in capture mode
- once The binding time is only triggered once
- self triggers the event handler only when event.target is the current element itself
4. The v-model directive
- input input box
- type=“radio”
- type=“checkbox”
- type=“xxxx”
- textarea
- select
- In order to facilitate the processing of user input, vue provides 3 modifiers for the v-model directive
Modifier | effect | example |
---|---|---|
.number | Automatically convert user input values to numeric types |
5. Conditional rendering instructions
- Conditional rendering instructions are used to assist developers to control the display and hiding of DOM as needed .
- v-if: Dynamically create or remove elements each time to realize the display and hiding of elements ( commonly used in actual development )
- If some elements do not need to be displayed by default when you first enter the page, and this element may not need to be displayed later, at this time v-if performance is better
- Companion instruction for v-if: v-else-if / v-else
- v-show: Dynamically add or remove the display:none style for the element to realize the display and hiding of the element
- If you want to switch the display status of elements frequently, the performance of v-show will be better
6. Loop rendering instructions
- Add v-for to which element to loop
- Official suggestion: As long as the v-for command is used, a :key attribute must be bound, and try to use id as the value of the key
- The official value type of the key is required to be: string or number type
- The value of key cannot be repeated, otherwise the terminal will report an error
<div id="app">
<table class="table table-bordered table-hover">
<thead>
<th>索引</th>
<th>Id</th>
<th>姓名</th>
</thead>
<tbody>
<tr v-for="(item, index) in list" :key="item.id">
<td>{
{ index }}</td>
<td>{
{ item.id }}</td>
<td>{
{ item.name }}</td>
</tr>
</tbody>
</table>
</div>
listener (watch)
- listener in method format
- Disadvantage 1: It can no longer be triggered automatically when entering the page
- Disadvantage 2: If the listener is an object, if the properties in the object change, the listener will not be triggered
- Object format listener
- Benefit 1: The listener can be triggered automatically through the immediate option
- Benefit 2: You can use the deep option to let the listener deeply monitor the changes of each property in the object
Computed property (computed)
- features
- When defining, it must be defined as a method
- When using computed properties, it can be used as ordinary properties
- benefit
- Implemented code reuse
- As long as the data source dependent in the computed property changes, the computed property will automatically re-evaluate!
axios
axios is a library focused on network requests
1. Initiate a get request
axios({
// 请求方式
method: 'GET',
// 请求地址
url: 'http://www.liulongbin.top:3006/api/getbooks',
// url 中的查询参数(一般 get 请求)
params: {
id: 1
},
// 请求体参数(一般 post 请求)
data: {
}
}).then(function (result) {
console.log(result);
});
// Get 请求简化
document.querySelector('#btnGet').addEventListener('click', async () => {
// 解构赋值的时候, 使用 : 进行重命名
// 1. 调用 axios 之后, 使用 async/await 进行简化
// 2. 使用解构赋值, 从 axios 封装的大对象中, 把 data 属性解构出来
// 3. 把解构出来的 data 属性, 使用冒号进行重命名, 一般都重命名为 { data: res}
const {
data: res} = await axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks'
});
console.log(res.data);
});
// Get 请求模板
document.querySelector('#btnGet').addEventListener('click', async () => {
const {
data: res} = await axios.get(
// 请求 url
'',
// 请求参数
{
params: {
}
}
);
console.log(res.data);
});
2. Initiate a post request
document.querySelector('#btnPost').addEventListener('click',
async () => {
// 如果调用某个方法的返回值是 Promise 实例, 则可以前面添加 await
// await 只能用在被 async 修饰的方法中
// 1. 调用 axios 方法得到的返回值是 Promise 对象
const {
data} = await axios({
// 请求方式
method: 'POST',
// 请求地址
url: 'http://www.liulongbin.top:3006/api/post',
// url 中的查询参数(一般 get 请求)
params: {
},
// 请求体参数(一般 post 请求)
data: {
name: 'zs',
age: 20
}
});
console.log(data);
});
// Post 请求模板
document.querySelector('#btnPost').addEventListener('click', async () => {
// axios.post('url',{/*Post 请求体数据*/})
const {
data: res} = await axios.post(
// 请求 url
'',
// 请求体
{
});
console.log(res);
});
3. Using axios in Vue
methods: {
async btnGetBooks() {
const {
data: res } = await axios.get('/api/getbooks')
console.log(res)
}
}
Use of vue-cli
- Run the following command in the terminal to create a project with the specified name
vue create 项目的名称
- The composition of the src directory in the vue project
assets 文件夹: 存放项目中用到的静态资源文件, 例如: css 样式表, 图片资源
components 文件夹: 程序员封装的, 可复用的组件, 都要方法哦 components 目录下
main.js 是项目的入口文件.整个项目的运行, 都要先执行 main.js
App.vue 是项目的根组件
Three steps to use components
- Use the import syntax to import the required components
import Left from '@/components/Left.vue'
- Register components using the components node
export default {
components: {
Left
}
}
- Use the just registered component as a tag
<div class="box">
<Left></Left>
</div>
Register global components
In the main.js entry file of the vue project, the global component can be registered through the Vue.component() method
import Count from '@/components/Count.vue'
Vue.component('MyCount', Count)
// 参数 1:字符串格式, 表示组件的"注册名称"
// 参数 2:需要被全局注册的那个组件
Component props
props is a custom attribute of a component. When encapsulating common components, using props reasonably can greatly improve the reusability of components!
- props is read-only: if you want to modify the value of props, you can dump the value of props into data
export default {
props: ['自定义属性A','自定义属性B','其他自定义属性...']
}
// props 设置 default 值, 设置 type 值类型, 设置 required 必填项
export default {
props: {
init: {
default: 0,
type: Number,
required: true
}
},
}
scoped and deep
- scoped scope style
- deep: Add /deep/ before the style to modify the style of the child component in the parent component (commonly used to modify the default style of third-party components)
Component life cycle
Life Cycle (Life Cycle) refers to the entire stage of a component from creation -> operation -> destruction , emphasizing a time period
- Component Creation Phase
- new Vue() ->
beforeCreate
->created
->breforeMount
->mounted
- new Vue() ->
- component runtime
beforeUpdate
->updated
- Component destruction phase
beforeDestroy
->destroyed
stage | illustrate | features | Is it commonly used |
---|---|---|---|
beforeCreate | The first life cycle function of the creation phase | uncommonly used | |
created | Initiate an Ajax request (call methods in methods, request server data, and transfer the requested data to data for template rendering) | Initialize props/data/methods | very commonly used |
beforeMount | rarely used | ||
mounted | If you want to operate the DOM, you must be in the mounted stage at the earliest | Initialize the DOM | commonly used |
beforeUpdate | generally | ||
updated | When the data changes, in order to be able to operate the latest DOM structure, the code must be written into the updated lifecycle function | commonly used | |
beforeDestroy | generally | ||
destroyed | generally |
Data Sharing Between Components
-
Parent components share data with child components
- You need to use custom properties ( props ) in the child component, and use v-bind to pass the value in the parent component
-
Child components share data with parent components
- Child components share data with parent components using custom events
// 子组件
methods: {
add() {
this.count += 1;
this.$emit('numChange', this.count);
}
}
// 父组件
<h1>{
{
countFromSon }}</h1>
<Right @numChange="getNewCount"></Right>
data() {
return {
// 定义数据项来接收子组件传递过来的值
countFromSon: 0
};
},
methods: {
// 获取子组件传递过来的数据
getNewCount(val) {
console.log('numChange 事件被触发了!', val);
this.countFromSon = val;
}
}
- Data sharing between sibling components
- In vue 2.x, the data sharing scheme between sibling components is EventBus
// eventBus.js
import Vue from 'vue'
export default new Vue()
// 子组件
<template>
<div class="Count">
<button type="button" @click="sub">-</button>
<span class="number-box">{
{ num }}</span>
<button type="button" @click="add">+</button>
</div>
</template>
<script>
import bus from '@/components/eventBus.js';
export default {
name: "Counter",
props: {
id: {
type: Number,
required: true
},
num: {
type: Number,
default: 1
}
},
methods: {
add() {
bus.$emit('share',
{
id: this.id,
value: this.num + 1
});
},
sub() {
bus.$emit('share',
{
id: this.id,
value: this.num - 1
});
}
}
};
</script>
// 兄弟组件
import bus from '@/components/eventBus.js';
created() {
bus.$on('share', val => {
this.list.some(item => {
if (item.id === val.id) {
item.goods_count = val.value;
return true
}
});
});
}
ref reference
- Used to assist developers to obtain references to DOM elements or components without relying on jQuery
- Each vue component instance contains a ** refs object∗ ∗, which stores the reference of the corresponding DOM element or component. By default, the refs object of ∗ ∗ component** stores the reference of the corresponding DOM element or component. By default, **component'sr e f s object∗∗,It stores the reference of the corresponding DOM element or component . By default , _ _ _∗∗The component 's refs point to an empty object**
- You can use ref to share data between components
<h1 ref="myh1">App 根组件</h1>
console.log(this.$refs.myh1);
this.$nextTick(cb) method
- The $nextTick(cb) method of the component will postpone the execution of the cb callback until the next DOM update cycle. The popular understanding is: after the component DOM update is completed, then execute the cb callback function. This ensures that the cb callback function can operate to the latest DOM element
this.$nextTick(() => {
this.$refs.iptRef.focus();
})
Dynamic Component Rendering
- Vue provides a built-in component, which is specially used to realize the rendering of dynamic components
- Dynamic components will be re-destroyed and re-created every time they are switched -- keep-alive solution
<template>
<div class="app-container">
<h1>App 根组件</h1>
<hr/>
<button @click="comName='Left'">展示 Left</button>
<button @click="comName='Right'">展示 Right</button>
<div class="box">
<!-- 渲染 Left 组件和 Right 组件 -->
<!-- 1. component 标签是vue内置的, 作用: 组件的占位符-->
<!-- 2. is 属性的值, 表示要渲染的组件的名字-->
<!-- 3 is 属性的值, 应该是组件要再components节点下的注册名称-->
<!-- keep-alive 可以把内部的组件进行缓存, 而不是销毁组件-->
<keep-alive include="Left, Right">
<component :is="comName"></component>
</keep-alive>
</div>
</div>
</template>
data() {
return {
// comName: 表示要展示的组件的名字
comName: 'Left'
};
}
-
The life cycle function corresponding to keep-alive
- When the component is cached , the component's deactivated lifecycle function is automatically triggered
- When the component is activated , the activated lifecycle function of the component is automatically triggered
-
The include attribute of keep-alive: components with matching names will be cached, and multiple components are separated by English commas
-
The exclude attribute of keep-alive: Exclude the cache of the specified name component (choose one of include and exclude)
slot
- Slot (slot) is the ability provided by vue to the wrapper of the component . Allows developers to define undefined parts that are expected to be specified by users as slots when packaging components .
- If you want to fill the content into the slot with the specified name, you need to use v-slot: this command
- v-slot: followed by the name of the slot
- v-slot: Directives cannot be used directly on elements, they must be used on the template tab ( or directly on components! )
- template This tag, it is a virtual tag, it only plays the role of wrapping, but it will not be rendered as any substantial html element
- The shorthand for v-slot is #
// 子组件
<!-- vue 官方规定, 每一个slot插槽, 都要有一个 name 名称, 省略默认为 default-->
<slot name="default">这是 default 插槽的默认内容</slot>
// 父组件
<Left>
<template #default>
<p>这是在Left组件的内容区域, 声明的p标签</p>
</template>
</Left>
Scoped slots
- When encapsulating a component, provide the reserved slot with the value corresponding to the attribute. This usage is called "scope slot"
// 子组件
<slot name="content" msg="hello vue" :user="userinfo"></slot>
// 父组件:用法 1
<template #content="obj">
<div>
<p>{
{ obj.msg }}</p>
<p>{
{ obj.user}}</p>
</div>
</template>
// 父组件:用法 2
<template #content="{msg, user}">
<div>
<p>{
{ msg }}</p>
<p>{
{ user }}</p>
</div>
</template>
custom directive
1. Private custom directive
<h1 v-color="color">App 根组件</h1>
<h3 v-color="'red'">测试</h3>
data() {
return {
color: 'blue'
};
},
// 私有自定义指令的节点
directives: {
// 定义名为 color 的自定义指令,指向一个配置对象
color: {
// 当指令第一次被绑定到元素上的时候,会立即触发 bind 函数
// 形参中的 el 表示当前指令所绑定的那个 DOM 对象
bind(el, binding) {
console.log('触发了 v-color 的 bind 函数');
el.style.color = binding.value;
},
// 每次 DOM 更新时被调用
update(el, binding) {
console.log('触发了 v-color 的 update 函数');
el.style.color = binding.value;
}
}
}
// 如果 bind 和 update 事件一样,可以简写
directives: {
color(el, binding) {
el.style.color = binding.value;
}
}
2. Global custom directives
// 全局自定义指令
Vue.directive('color', function (el, binding) {
el.style.color = binding.value;
});
Mount axios on the Vue prototype
// main.js
import axios from 'axios'
// 全局配置 axios 的请求根路径
axios.defaults.baseURL = 'http://localhost:8080'
// 把 axios 挂载到 Vue.prototype 上,供每个 .vue 组件的实例直接使用
Vue.prototype.$http = axios
// 今后,在每个 .vue 组件中要发起请求,直接调用 this.$http.xxx
// 但是,把 axios 挂载到 Vue 原型上,有一个缺点:不利于 API 接口的复用!!!
routing
- Routing (router) is the corresponding relationship
- Front-end routing : the correspondence between Hash addresses and components
- How Frontend Routing Works
- The user clicks a route link on the page
- Caused the Hash value in the URL address bar to change
- The front-end routing has monitored the change of the Hash address
- The front-end routing renders the component corresponding to the current Hash address into the browser
- Vue-router installation and configuration steps
- Install the vue-router package
- Create routing module
- Import and mount the routing module
- Declare routing links and placeholders
// src/router/index.js 就是当前项目的路由模块
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '@/components/Home';
import Movie from '@/components/Movie';
import About from '@/components/About';
import Tab1 from '@/components/tabs/Tab1';
import Tab2 from '@/components/tabs/Tab2';
Vue.use(VueRouter);
// 创建路由的实例对象
const router = new VueRouter({
// routes 是一个数组,作用:定义 hash 地址与组件之间的对应关系
routes: [
// 重定向的路由规则
{
path: '/', redirect: '/home'},
// 路由规则
{
path: '/home', component: Home},
{
path: '/movie/:id', component: Movie, props: true},
{
// about 页面的路由规则(父级路由规则)
path: '/about',
component: About,
redirect: '/about/tab1',
children: [
// 子路由规则
// 默认子路由:如果 children 数组中,某个路由规则的 path 值为空,字符串,则这条路由规则,叫做默认子路由
{
path: 'tab1', component: Tab1},
{
path: 'tab2', component: Tab2}
]
}
]
});
export default router;
<!-- 当安装和配置了 vue-router 后,就可以用 router-link 来替代普通的 a 链接了-->
<router-link to="/home">首页</router-link>
<!--只要在项目中安装和配置了 vue-router,就可以使用 router-view 这个组件了-->
<!--作用:占位符-->
<router-view></router-view>
-
Routing redirection: When a user accesses address A, the user is forced to jump to address C to display a specific component page. By specifying a new routing address through the redirect attribute of routing rules, it is very convenient to set routing redirection.
-
Dynamic routing : Define the variable part of the Hash address as a parameter item, thereby improving the reusability of routing rules. Use the English colon (:) in vue-router to define the parameter items of the route.
-
props: true : enable props to pass parameters for routing rules, so as to easily get the value of dynamic parameters
<!-- 当安装和配置了 vue-router 后,就可以用 router-link 来替代普通的 a 链接了-->
<router-link to="/home">首页</router-link>
<!-- 注意:在 hash 地址中,/后面的参数项,叫做"路径参数"-->
<!-- 在路由参数对象中,需要使用 this.$route.params 来访问路径参数-->
<!-- 注意2:在 hash 地址中,?后面的参数项,叫做"查询参数"-->
<!-- 在路由参数对象中,需要使用 this.$route.query 来访问查询参数-->
<!-- 注意3:在 this.$route中,path 只是路径部分,fullPath 是完整的地址-->
<!--例如:-->
<!--fullPath:/movie/2?name=zs&age=20-->
<!--/movie/2 是 path 的值-->
<router-link to="/movie/1">电影1</router-link>
<router-link to="/movie/2?name=zs&age=20">电影2</router-link>
<router-link to="/movie/3">电影3</router-link>
<router-link to="/about">关于</router-link>
Programmatic Navigation API in Vue-router
- this.$router.push('hash address')
- Jump to the specified hash address and add a history record
- this.$router.replace('hash address')
- Jump to the specified hash address and replace the current history
- this.$router.go(number n) (forward and backward)
- Simplified usage of $router.go
- $router.back()
- $router.forward()
route guard
- Global Front Guard
- Every time a routing navigation jump occurs , the global pre-guard will be triggered . Therefore, in the global front guard, programmers can control the access rights of each route.
router.beforeEach((to, from, next) => {
// to 是将要访问的路由信息对象
// from 是将要离开的路由的信息对象
// next 是一个函数,调用 next()表示放行,允许这次路由导航
// 分析:
// 1. 要拿到用户将要访问的 hash 地址
// 2. 判断 hash 地址是否等于 /main
// 2.1 如果等于/main,证明需要登录之后,才能访问成功
// 2.2 如果不等于 /main,则不需要登录,直接放行 next()
// 3. 如果访问的地址是 /main,则需要读取 localStorage 中的 token 值
// 3.1 如果有 token,则放行
// 3.2 如果没有 token,则强制跳转到/login 登录界面
if (to.path === '/main') {
const token = localStorage.getItem('token');
if (token) {
next();
} else {
next('/login');
}
} else {
next();
}
});