Vue is super detailed from entry to mastery courses

Vue2.0

1. Get to know Vue

1. Founder and development history

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-IYmj7NzM-1679370213958)(note picture/image-20230306112147856.png)]

EvanYou

Chinese American

Founder of Vue Technology LLC

High School: High School Affiliated to Fudan University, Shanghai

University: Colgate University, New York

development path

1. February 2014

You Yuxi open sourced a front-end development library Vue.js. Vue.js is a JavaScript library for building web interfaces and a system that provides efficient data binding and flexible components through a concise API.

2. September 2016

At the JSConf in Nanjing, You Yuxi officially announced to join the Alibaba Weex team as a technical consultant to integrate Vue and Weex's JavaScript runtime. The goal is to enable everyone to use Vue's syntax across three terminals.

April 2020

Vue3.0beta version test release.

2. What is Vue?

Vue.js is a lightweight, data-driven , front-end JS framework that provides efficient data binding and flexible component systems through a concise API .

3. What are the technical advantages compared with Jquery

Old: Jquery

Manipulate DOM elements

jQuery uses a selector ($) to select DOM objects, and performs operations such as assignment, value retrieval, and event binding on them. In fact, the difference from native HTML is that DOM objects can be selected and manipulated more conveniently, while data and interfaces are together

Complex pages are expensive to maintain

jquery needs to get the dom element node and add a label to the dom. If the dom structure is particularly complicated, or the added elements are very complicated, the code will become very complicated and the readability is low.

Difficult to achieve componentized pages

Most of the code in the JQuery era is noodle code, and the coupling is serious

performance loss

Consumption of browser resources

New: Vue.js

Data and View Separation

Vue completely separates data and View through Vue objects. It is no longer necessary to refer to the corresponding DOM object to operate on the data. It can be said that the data and the View are separated, and they are bound to each other through the vm of the Vue object. This is the legendary MVVM.

Data two-way binding

This is the biggest advantage of vue.js. The two-way binding of data is realized through the idea of ​​MVVM, so that developers no longer need to operate DOM objects, and have more time to think about business logic.

Flexible componentization

Vue.js splits various modules in a single-page application into individual components through components. We only need to write various component tags in the parent application first, and write the components to be passed in the component tags. Input the parameters of the components, and then write the implementation of various components separately, and then the whole application is finished.

Virtual DOM, run faster

Virtual DOM is a kind of calculation that can be performed through JavaScript in advance to calculate and optimize the final DOM operation. Since this DOM operation is a preprocessing operation and does not actually operate the DOM, it is called virtual DOM.

4. Technical point arrangement

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-TcVq9AEc-1679370213961)(note picture/image-20230306112212557.png)]

5. Learn the knowledge points that need to be mastered

lightweight framework

It can automatically track dependent template expressions and computed properties, provides MVVM data binding and a composable component system, and has a simple and flexible API, making it easier for readers to understand and get started faster.

two-way data binding

Declarative rendering is the main embodiment of two-way data binding, and it is also the core of Vue.js, which allows the integration of data declarative rendering into DOM with a concise template syntax.

client routing

Vue-router is the official routing plugin of Vue.js, which is deeply integrated with Vue.js and used to build single-page applications. Vue single-page applications are based on routing and components. Routing is used to set access paths and map paths and components

instruction

Vue.js interacts with the page mainly through built-in instructions. The function of the instruction is to apply certain behaviors to the DOM accordingly when the value of its expression changes.

Componentization

It can be referenced at any time, and different pages can be realized by passing in parameters, which can be referenced by children and parents.

state management

State management is actually a one-way data flow. The State drives the rendering of the View, and the user operates the View to generate an Action, which causes the State to change, so that the View is re-rendered to form a separate component.

2. Build Vue2.0 project

1. Npm, cnpm node environment to build vue scaffolding

1. Install node.js environment

1. Enter the official website

https://nodejs.org/en/

2. Install msi, install the directory to the C drive

After installation, use cmd to execute node- v npm -v to see if the version number is output

3. Create a nodejsFile folder in addition to the C drive, create two folders node_global and node_cache, and then run the following command

npm config set prefix "D:\Program Files\nodejs\node_global"
npm config set cache "D:\Program Files\nodejs\node_cache"

4. Check whether the path path is called C:\ProgramFiles\nodejs\node_modules in the current system variables

If there is, create a drive letter with the path folder of the same name outside the C drive, if not, don’t worry about it

  1. Configure your C:\Program Files\nodejs\node_modules path in the path variable

2. Install Taobao mirror cnpm

Function: Same as npm, npm is downloaded from overseas mirror warehouse, cnmp is downloaded from Ali Taobao mirror warehouse

npm install -g cnpm --registry=https://registry.npm.taobao.org

After the installation is complete, use: cnpm -v to view the version

3. Install webpack

npm install webpack -g

After the installation is complete, use: npm webpack -v to view the version

4. Download vue scaffolding

1. Download scaffolding resources

cnpm install -g [email protected]

2. Go to your gloab directory to see if there are files starting with vue

insert image description here

  1. Create an empty folder under another folder, press and hold shift + right mouse button in the folder, click here to open the pwershell window
  1. Open the window and enter: vue init webpack

5. Initialize and build vue scaffolding

insert image description here
insert image description here

6. Run the vue project

Press and hold shift + right mouse button in the project root directory, click here to open the pwershell window, and execute npm run dev

3. Use VSCode to build Vue project

Download VsCode

https://code.visualstudio.com/

Component download

insert image description here
insert image description here

Create a vue project

  1. Create an empty project folder
  2. Open this folder with vsCode
  3. Set vsCode language: ctrl+shift+P Input command: Display language, first select English to restart, then select Chinese and then restart.
  4. open terminal
vue init webpack

An error will appear: not promise. . . . The vsCode terminal console does not have system write permissions

Use the cmd window that comes with this machine to start with administrator privileges

Jump the directory to the project path and execute the vue init webpack command

5. Start the project

npm run dev

insert image description here

6. Quit running

ctrl+c

4. Write the first vue file

<!-- Dom页面 -->
<template>
	<!-- 所有的页面元素都要卸载div之内 -->
  <div id='UserIndex'>
    
  </div>
</template>

<!-- 组件js -->
<script>
export default {
    name:'UserIndex',
    data(){

    }
}
</script>

<!-- CSS代码 -->
<style scoped>

</style>

Create a custom code snippet with VSCode

File – "Preferences - "Configure User Code Snippets

{
    
    
	"Print to console": {
    
    
		"prefix": "myvue",// 代码段名称
		"body": [ //代码内容
			"<!-- Dom页面 -->",
			"<template>",
			"<div id=''>",
			"",
			"</div>",
			"</template>",
			"",
			"<!-- 组件js -->",
			"<script>",
			"export default {",
			"name:'',",
				"data(){",
				"",
				"}",
			"}",
			"</script>",
			"",
			"<!-- CSS代码 -->",
			"<style scoped>",
			"",
			"</style>"
		],
		"description": "myvue"
	}
}

5.App.vue file

Function: the home page of the vue project, you can write the public style in the global project

Note: Generally, if the project integrates the routing function, app.vue will only write a routing label

<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>
#app {
  
}
</style>

6.main.js- main entry file

Role: configure the introduction of common components, vue general configuration

import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

/* eslint-disable no-new */
// 创建vue,绑定主视图
// 脚手架项目中vue实例只会有一个,存在main.js中
new Vue({
    
    
  el: '#app',
  router,
  components: {
    
     App },
  template: '<App/>'
})

vue instance

Every Vue.js application is started by creating a root instance of Vue through the constructor Vue

insert image description here

7. The life cycle of Vue components (vue2.0)

1. Component creation phase -create

insert image description here

  1. instantiated component
    1. beforeCreate before creation
  2. Enable data monitoring
  3. Initialize the internal method of vue
    1. created created

Use hook function in vue

<template>
  <div class="hello">
    123
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
      
    }
  },
  //创建前的钩子
  beforeCreate(){
     console.dir("beforeCreate");
  },
  //创建后
  created(){
    console.dir("created");
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

2. Component rendering phase - mount

insert image description here

  1. Vue chooses to render the template, whether to use the vue component to render or just render part of the html

    ​ 1.beforeMount - before the dom element is rendered

  2. start rendering

    1. mounted - dom mount completed
<template>
  <div class="hello">
    123
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
      
    }
  },
  //创建前的钩子
  beforeCreate(){
     console.dir("beforeCreate");
  },
  //创建后
  created(){
    console.dir("created");
  },
  //Dom挂载之前
  beforeMount(){
    console.dir("beforeMount");
    
  },
  //dom挂载完成
  mounted(){
    console.dir("mounted");
  }

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

3. Component running phase - data update - update

insert image description here

  1. The listener will monitor all data value changes

    ​ 1.beforUpdate - before data update

  2. Use VDom to dynamically render html

    1. updated - data rendering is complete
<template>
  <div class="hello">
    {
   
   { name }}
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
       name:"蔡徐坤"
    }
  },
  //创建前的钩子
  beforeCreate(){
     console.dir("beforeCreate");
  },
  //创建后
  created(){
    console.dir("created");
  },
  //Dom挂载之前
  beforeMount(){
    console.dir("beforeMount");
    
  },
  //dom挂载完成
  mounted(){
    console.dir("mounted");
  },
  //数据更新之前
  beforeUpdate(){
    console.dir("beforeUpdate");
  },
  //数据更新完成
  updated(){
    console.dir("updated");
  }

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

4. Component destruction phase -destroy

Note: By default, the component will not be actively destroyed. It needs to use the v-if instruction or Vue.$destroy() to trigger the vue destruction process

insert image description here

  1. Whether the component enters the destruction process (v-if instruction or, Vue.$destroy())
    1. beforeDestroy - before destroying
  2. Destroy - all data value caches in the component will disappear, and the vdom cache will also be cleared
    1. destroyed - destroyed

8.main.js for global configuration

#取消 Vue 所有的日志与警告 - 开发不要配,生产环境配
Vue.config.silent = true


#配置是否允许 vue-devtools 检查代码 - 开发不要配,生产环境配
Vue.config.devtools = true 

#指定组件的渲染和观察期间未捕获错误的处理函数-全局异常处理回调
Vue.config.errorHandler = function (err, vm, info){
    
    } 

#设置为 false 以阻止 vue 在启动时生成生产提示 - 开发不要配true,生产环境配
Vue.config.productionTip = false


9. Vue syntax

1. Interpolation expression-text type (number, boolean, string, character, text type in object)

Syntax: { { data variable name }}

It is to render the data bound by vue to the view to generate an association and realize two-way binding

<template>
  <div class="hello">
    <h1>大家好我叫:{
   
   { name }}</h1>
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
       name:"蔡徐坤456"
    }
  }

}
</script>

v-once directive

Writing position: In the start tag where the interpolation expression exists

Function: The value in the interpolation expression will not be rendered according to the change of data, and the value loaded for the first time will always be kept

<template>
  <div class="hello">
    <h2>{
   
   { name }}</h2>// 蔡徐坤123
    <h2 v-once>大家好我叫:{
   
   { name }}</h2> // 蔡徐坤
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
       name:"蔡徐坤" // 蔡徐坤123
    }
  }

}
</script>

2. Dynamically insert HTML text

Note: The process of { { XXX }} parsing will only be parsed in plain text. If you want to parse the html code segment and load it into the dom, you need to use the v-html command

v-html directive

<template>
  <div class="hello">
    <!-- 加载html是以纯文本的方式加载 -->
    <!-- <h2>{
   
   { person.myhtml }}</h2> -->
    <!-- 将person.myhtml中的html代码加载到当前标签的子标签中 -->
    <h2 v-html="person.myhtml"></h2> // XXX.html("xxx")
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
       person:{
         name:"蔡徐坤",
         myhtml:"<span>123</span>"
       }
    }
  }

}
</script>

3. Dynamic binding of tag attribute values ​​(emphasis often used)

Note: title={ { xxxx }} does not work, interpolation expressions cannot be used on attribute values ​​and attribute names, and interpolation expressions cannot be used on label positions

So what if you need to dynamically bind a data to the attribute value of the label? To use the v-bind command

v-bind directive

<template>
  <div class="hello">
    <h1 v-bind:title="person.title" >欢迎访问网站</h1>
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
       person:{
         name:"蔡徐坤",
         title:"点击给我充值50块!"
       }
    }
  }

}
</script>

The v-bind command can be abbreviated as ":"

 <h1 :title="person.title" >欢迎访问网站</h1>

4. Dynamic binding expressions

Dynamically bind a piece of js code when clicked

With the help of v-bind to achieve

<template>
  <div class="hello">
    <h1 :οnclick="person.text" >欢迎访问网站</h1>
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
       person:{
          //表达式字符串
          text:"javascript:var c=0;alert(c)"
       }
    }
  }

}
</script>

5. vue command

Written position: write in the attribute position of the tag in the start tag

1. v-once (not renewable)

2.v-bind (dynamic binding attribute value)

3.v-html (dynamically add sub-elements to parse html)

4.v-on (event binding)

Complicated writing:

<template>
  <div class="hello">
    <!-- 点击h1标签跳转到百度首页 -->
    <h1 v-on:click.prevent="toBaidu(1)" >欢迎访问网站</h1>
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
       person:{
          //表达式字符串
          text:"color:red"
       }
    }
  },
  //当前组件的所有方法
  methods:{
    //跳转到百度
    toBaidu(a){ // toBaidu:function(){}
      console.dir(a);
      location.href = "https://www.baidu.com"
    }
  }

}
</script>

Simple writing: v-on is replaced by @

Such as: trigger function @click="function" when clicked

<template>
  <div class="hello">
    <!-- 点击h1标签跳转到百度首页 -->
    <h1 @dblclick="toBaidu(1)" >欢迎访问网站</h1>
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
       person:{
          //表达式字符串
          text:"color:red"
       }
    }
  },
  //当前组件的所有方法
  methods:{
    //跳转到百度
    toBaidu(a){ // toBaidu:function(){}
      console.dir(a);
      //location.href = "https://www.baidu.com"
    },
      ...
    aa(){
       this.toBaidu();// this调用别的方法
       this.person.text = "123"; // this访问data值
	}
  }

}
</script>

Keyboard input - implement event triggering

Hit Enter to realize the method call

<template>
  <div class="hello">
    <!-- 键盘键入回车就跳转到百度首页 -->
    <h1>欢迎访问网站</h1>
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
       person:{
          //表达式字符串
          text:"color:red"
       }
    }
  },
  mounted(){//dom渲染完成
    //添加一个监听键盘操作的监听器
    window.addEventListener('keydown', this.mykey);
  },
  //当前组件的所有方法
  methods:{
    //绑定到监听键盘输入的回调方法
    mykey(param){
      if(param.keyCode == 13){// 13 代表敲击回车
        this.toBaidu();
      }
    },
    //跳转到百度
    toBaidu(){ // toBaidu:function(){}
      location.href = "https://www.baidu.com"
    }
  }

}
</script>

List of all keycodes in js

https://blog.csdn.net/fghyibib/article/details/120670221?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-1-120670221-blog-122497397.pc_relevant_multi_platform_whitelistv3&spm=1001.2101.3001.4242.2&utm_relevant_index=4

5.v-if 、v-show

v-if:
true: label or component is mounted
false: label or component is deleted or destroyed

v-show: control the display and hiding of components through the display style
true: label or component - display status
false: label or component - hidden

<template>
  <div class="hello">
    <!-- 
      v-if: 
        true: 标签或者组件被挂载
        false:标签或者组件删除或销毁
     -->
    <h1 v-if="isOk">欢迎访问网站</h1>
     <!-- 
      v-show: 通过display样式控制组件显示隐藏
        true: 标签或者组件 - 显示状态
        false:标签或者组件 - 被隐藏
     -->
    <h1 v-show="isOk">欢迎访问网站2</h1>
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
       isOk:true
    }
  },
  mounted(){//dom渲染完成
   
  },
  //当前组件的所有方法
  methods:{
    
  }

}
</script>

v-if mount process

When the v-if value is true: the component will enter the creation phase-rendering phase

​ If the parent component loads the child component and the child component is described by v-if="false", the child component will not be loaded

When the v-if value is false: the component will enter the destruction phase

v-show mount process

When v-show is true: the component is shown - no lifecycle hooks will be called

​ If the parent component loads the child component, when the child component is described by v-show="false", the child component will be loaded but not displayed

When the v-show value is false: the component is hidden - the lifecycle hook will not be called

v-if is loaded according to the boolean control component, and v-show is loaded in advance regardless of whether the value is true or false according to the boolean control component.

6.v-else\v-else-if

Multi-condition judgment instruction

Note: v-if v-els-if v-else should pay attention to the order and quantity of writing, v-else can only have one, v-else-if can have multiple

Pay attention to the order between the tags, there should be no gaps

<Test1 v-if="isOk"></Test1> // 独立的判断
<h1 v-if="name=='鸡仔'">123</h1> //2 行 一组判断逻辑
<Test2 v-else></Test2>

7.v-for-ordered list traversal loop instruction

v-for="(each object in the loop, the subscript of the loop traversal) in the collection array to loop"

​ Shorthand - only take out the objects in the collection: v-for="Each object in the loop in the collection array to be looped"

Required parameters in the loop

​ key: The label describing the cycle is unique, as long as a unique value attribute is bound, it can be provided to the VDom to update the element

<template>
  <div class="hello">
    
    <table>
      <tr>
        <th>编号</th>
        <th>姓名</th>
        <th>年龄</th>
      </tr>
      <!-- 
        v-for="(循环中的每个对象,循环遍历的下标) in 要循环的集合数组"
      -->
      <tr v-for="(item,index) in userList" :key="index">
        <!-- 循环中插入的数据就使用item对象访问属性值用插值表达式输出 -->
        <td>{
   
   {item.id}}</td>
        <td>{
   
   {item.name}}</td>
        <td>{
   
   {item.age}}</td>
      </tr>
    </table>

  </div>
</template>

<script>
//引入组件
import Test1 from './Test.vue';
import Test2 from './Test2.vue';

export default {
  name: 'HelloWorld',
  //注册组件
  components:{Test1,Test2},
  data () {
    return {
       isOk:false,
       name:"鸡仔",
       userList:[
        {
          name:"蔡徐坤",
          age:18,
          id:101
        },
        {
          name:"小鸡仔",
          age:19,
          id:102
        }
       ]
    }
  },
  mounted(){//dom渲染完成
   
  },
  //当前组件的所有方法
  methods:{
    
  }

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

8.v-for - traverse map\object

v-for="(object's attribute value, object's attribute name, attribute's serial number) in to iterate object" :key="unique value"

<template>
  <div class="hello">
    <!-- v-for="(对象的属性值,对象的属性名称,属性的序号) in 要迭代对象" :key="唯一值" -->
    <h1 v-for="(value,key,index) in userData" :key="index">
      [{
   
   {index}}]{
   
   {key}}====={
   
   {value}}
    </h1>
    

  </div>
</template>

<script>
//引入组件
import Test1 from './Test.vue';
import Test2 from './Test2.vue';

export default {
  name: 'HelloWorld',
  //注册组件
  components:{Test1,Test2},
  data () {
    return {
       isOk:false,
       name:"鸡仔",
       userData:{
         name:"ikun",
         age:0,
         id:101
       }
    }
  },
  mounted(){//dom渲染完成
   
  },
  //当前组件的所有方法
  methods:{
    
  }

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

9. v-model form data binding

In the traditional H5 development method, the value of the form is generally controlled by the value attribute, but after testing, the value attribute of the dynamically bound form tag cannot realize the change of the form value. At this time, we need to use the v-model instruction to realize the form data. dynamic binding

1. How to use v-model in the text field

<template>
  <div class="hello">
      <input v-model="name"/>
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data(){
    return {
      name:null
    }
  }

}
</script>
<style scoped>
</style>

Note: After using vue, form element binding data must use v-model instead of value attribute

1.v-model.lazy

Effect: When the filling is completed, the data will not be updated until the selected effect is removed

<input v-model.lazy="name"/>

2. v-model.number

Effect: When filling in the text, only numbers can be filled in

Note: It is only useful if the text starts with a number, and the characters are intercepted from the beginning of the number until the first non-number appears, such as: 1a2b ===> 1

<input v-model.number="name"/>

It is recommended to use type="number" for pure digital verification

<input type="number" v-model.number="name"/>

v-model.trim

How to remove leading and trailing spaces

<input v-model.trim="name"/>

2. How to use v-model in the selector

<!-- 如果需要回填自动选中选项,只要改变v-model绑定的数据值就ok -->
      <select v-model="name">
        <!-- 描述属性是数值类型时,需要添加v-bind -->
        <option :value="1">昆明</option>
        <!-- 描述属性是boolean类型时,需要添加v-bind -->
        <option :value="true">临沧</option>
        <option value="3">蒙自</option>
      </select>

3. How to use v-model in radio and check box

Single box

<template>
  <div class="hello">
      <input type="radio" name="sex" :value="1" v-model="sexCode"/>男
      <input type="radio" name="sex" :value="2" v-model="sexCode"/>女
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data(){
    return {
      sexCode:null
    }
  }

}
</script>
<style scoped>
</style>

check box

<template>
  <div class="hello">
      <input type="checkbox" name="like" :value="1" v-model="likeCode"/>吃鸡
      <input type="checkbox" name="like" :value="2" v-model="likeCode"/>lol
      <input type="checkbox" name="like" :value="3" v-model="likeCode"/>王者别嚣张
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data(){
    return {
      likeCode:[]// checkbox情况下,初始化值一定是要一个空数组
    }
  }

}
</script>
<style scoped>
</style>

4. v-model is used in the text field

<template>
  <div class="hello">
      <textarea v-model="name"></textarea>
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data(){
    return {
      name:null
    }
  }

}
</script>
<style scoped>
</style>

10. Filter

Purpose: to rewrite the display content of the interpolation expression

<template>
  <div class="hello">
    <!-- userData.name值nameFilter过滤器中 -->
    <!-- 过滤器可以改写插值表达式的内容 -->
    <h1>{
   
   { userData.name | nameFilter | nameFilter2 }}</h1>
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
       isOk:false,
       name:"鸡仔",
       userData:{
         name:"ikun",
         age:0,
         id:101
       }
    }
  },
  //过滤器
  filters:{
      //自定义过滤器
      nameFilter:function(value){
          console.dir(value);

          //要定义返回值
          return "欢迎管理员:"+value+",登录系统";
      },
      nameFilter2:function(value){
        console.dir(value);
        return value+"!!!!!!"
      }
  }

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

The v-bind directive can also be used with filters

<h1 :title="userData.name | nameFilter">点击查看用户信息</h1>

Vue3.0 has deprecated filters

11. Computed Properties

Computed property usage scenarios:

Compare with filter:

​ Filter: The parameter can only be in the interpolation expression | the previous value is injected into the parameter of the filter, and the filter cannot access the data bound by data

Computed property: The parameter can be the actual parameter when the calculated property is called, or it can access the data bound by data (this access)

Use computed properties - no-argument method

<h1>{
   
   { nameComputed }}</h1>
//计算属性
  computed:{
    
    
      //自定义计算属性
      nameComputed:function(){
    
    
          return this.userData.name.split('').reverse().join('');
      }
  }

Use computed properties - methods that can pass parameters

<h1>{
   
   { nameComputed("1",1,3) }}</h1>
//计算属性
  computed:{
    
    
      //自定义计算属性
      nameComputed(){
    
    
         return function(value,value2,value3){
    
    
            console.dir(value);
            return this.userData.name.split('').reverse().join('');
         }
      }
  }

Can the method method be used in interpolation expressions?

Yes, but it is recommended to use computed properties to complete

The difference between method and computed

Computed property:

Computed properties use browser cache for data storage and calculation

Computed properties can distinguish between two method modes: get and set according to whether the behavior is reading or parameter assignment

mycomputed:{
    
    
        get:function(){
    
    // 无参调用计算属性时触发
          console.dir("get");
          return "get";
        },
        set:function(){
    
    // 有参调用计算属性触发
          console.dir("set");
          return "set";
        }
      }

However, each call of the method needs to be read and written by the function execution, without any cache implementation, so the performance is poor. When the development purpose is only to change the value content of the interpolation expression, it is recommended to use the computed property to complete

12. Listener

Function: monitor the change of data binding data

Note: If the data to be monitored is stored in the object, the writing method is different

<template>
  <div class="hello">
     <h2>{
   
   { userData.age }}</h2>
     <button @click="userData.age +=1">点击我+1!</button>
     <button @click="userData.age -=1">点击我-1!</button>

     <h2>{
   
   { aa }}</h2>
     <button @click="aa +=1">点击我+1!</button>
     <button @click="aa -=1">点击我-1!</button>
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
  data () {
    return {
       isOk:false,
       name:"鸡仔",
       aa:0,
       userData:{
         name:"ikun",
         age:0,
         id:101
       }
    }
  },
  methods:{// 普通方法就像js中的函数 function
    say(){
      return "123456";
    }
  },
  watch:{//监听器- 可以监听data绑定数据的变化
    // data绑定数据的名称(新变化的值,变化之前的值)
    aa(newValue,oldValue){
        console.dir(newValue+"-----"+oldValue);
    },
    //要监听的数据是存在对象中的
    "userData.age"(newVal,oldVal){
        console.dir(newVal+"-----"+oldVal);
    }

  }

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

deep monitoring

It will be used when multiple components share data values

"userData.data.data.age":{
      immediate:true,// 深度监听立即执行
      deep: true,//  开启深度监听
      handler(newVal,oldVal){
        console.dir(newVal+"-----"+oldVal);
      }
}

Realize the front-end under yesterday's student information list function: add and edit functions

  1. Add function:
    1. Above the table there will be an add button
    2. Click the Add button to pop up a div, which contains a form for adding student information and buttons for saving and resetting the form
    3. After filling in the data, click Save, the pop-up window is closed, and the form data is refreshed
  2. edit function
    1. One more operation column in the table
    2. The operation column corresponds to an edit button in each row
    3. Click Edit to pop up the edit div, which contains a form for editing student information and saving edits
    4. After filling in the data, click Save, the pop-up window is closed, and the form data is refreshed
  3. Realize that adding form and editing form share a div and form content, realized by judgment

13. Dynamic style binding method

The method of dynamically modifying class attributes to achieve style changes

1. Object syntax

<template>
  <div class="hello">
    <!-- isUse为true则class属性值为class="div1" 为false class=""  -->
    <div :class="{ div1: isUse , hide : isUse2}"></div>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      isUse: false,
      isUse2:false
    };
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.div1 {
  width: 100px;
  height: 100px;
  background-color: red;
}

.div2 {
  width: 100px;
  height: 100px;
  background-color: yellow;
}

.hide{
    display: none;
}

</style>


2. Data binding implements class attribute changes

<template>
  <div class="hello">
    <div :class="myDivClass"></div>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      myDivClass:{
        div1:true,// 需要添加div1 值
        hide:false// hide值不添加
      }
    };
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.div1 {
  width: 100px;
  height: 100px;
  background-color: red;
}

.div2 {
  width: 100px;
  height: 100px;
  background-color: yellow;
}

.hide{
    display: none;
}

</style>

3. Control the content of the class attribute value through an array

<template>
  <div class="hello">
    <div :class="[activeDiv1,activeHid]"></div>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      activeDiv1:'div1', //属性值是样式名称
      activeHid:'hide'
    };
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.div1 {
  width: 100px;
  height: 100px;
  background-color: red;
}

.div2 {
  width: 100px;
  height: 100px;
  background-color: yellow;
}

.hide{
    display: none;
}

</style>

Expressions can be used in the array to complete the style selection

<template>
  <div class="hello">
    <!-- 数组中可以使用表达式完成样式的选择 -->
    <div :class="[isUser==true?activeDiv1:'xx',activeHid]"></div>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      activeDiv1:'div1', //属性值是样式名称
      activeHid:'hide',
      isUser:false
    };
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.div1 {
  width: 100px;
  height: 100px;
  background-color: red;
}

.div2 {
  width: 100px;
  height: 100px;
  background-color: yellow;
}

.hide{
    display: none;
}

</style>

The method of dynamically modifying the style attribute of the inline style

1. Methods of embedding objects

<template>
  <div class="hello">
    <!-- 样式值实现动态绑定 -->
    <div :style="{color:fontColor,backgroundColor:bgColor,with:'100px',height:'100px'}"></div>
    <input v-model="bgColor" />
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
        fontColor:'red',
        bgColor:'yellow'
    };
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

2. Data binding style attribute method

<template>
  <div class="hello">
    <!-- 样式值实现动态绑定 -->
    <div :style="myStyle"></div>

    <input v-model="myStyle.backgroundColor" />
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
        myStyle:{// 需要绑定到style属性中的对象要求:属性名称是样式名称,属性值是样式值
            color:'red',
            backgroundColor:'yellow',
            width:'100px',
            height:'100px'
        }
    };
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

14. Component development method

1. Introduce the use of component methods

subcomponent code

<!-- Dom页面 -->
<template>
  <div id="TestIndex">
    测试页面1
  </div>
</template>

<!-- 组件js -->
<script>
export default {
  name: "TestIndex",
  data() {
    return{

    }
  },
};
</script>

<!-- CSS代码 -->
<style scoped></style>

parent component code

<template>
  <div class="hello">
    <!-- 3.通过标签的方式引入组件,标签名称就是组件名称 -->
    <Test />
  </div>
</template>

<script>
//1. 导入要使用的组件  @代表的就是src目录路径,有点像classpath
import Test from '@/components/Test.vue';

export default {
  name: "HelloWorld",
  components:{Test},// 2.注册声明组件使用
  data() {
    return {
        
    };
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

2. The child component receives data from the parent component

The subcomponent should define what data it can receive (component parameters)

props attribute definition

Note: The value transfer of the child-parent component is a copy of the value, and the address will not be passed

Subcomponent writing

<!-- Dom页面 -->
<template>
  <div id="TestIndex">
    测试页面1{
   
   { name }}
    <input v-model="name">
  </div>
</template>

<!-- 组件js -->
<script>
export default {
  name: "TestIndex",
  props:{//组件接收参数定义 使用props参数值的方式和使用data绑定数据的方法一样
    // 注意不要和data中的数据名称重复
     name:{
       type:String,// String:字符串字符类型 Number:数值类型 Array:集合数组类型 Object:对象、map类型
       default:'只因你太美' //默认值
     },
     age:{
       type:Number,
       default:18
     }
  },
  watch:{
    name:function(newV,oldV){
      console.dir("监听:"+newV+"---"+oldV);
    }
  },
  data() {
    return{
        sonName:this.name //访问props参数方法和访问data值方法一致
    }
  },
  methods:{
    aa(){
      console.dir(this.name);//访问props参数方法和访问data值方法一致
    }
  }
};
</script>

<!-- CSS代码 -->
<style scoped></style>

Parent component transfer method

<template>
  <div class="hello">
    <!-- 3.通过标签的方式引入组件,标签名称就是组件名称 -->
    <!-- 给子组件props参数传值是通过标签属性传递的 -->
    <Test :name="fatherName" :age="12" />
  </div>
</template>

<script>
//1. 导入要使用的组件  @代表的就是src目录路径,有点像classpath
import Test from '@/components/Test.vue';

export default {
  name: "HelloWorld",
  components:{Test},// 2.注册声明组件使用
  data() {
    return {
        fatherName:"蔡徐坤"
    };
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

When the child component clicks the close button, the parent component needs to receive the callback of the close event

The child component needs to notify the parent component that something happens so that the parent component can receive the message

3. Child component and parent component callback method

It can realize the child component to pass data to the parent component

Case: Click the close button of the child component to hide the div of the parent component

subcomponent code

<!-- Dom页面 -->
<template>
  <div id="TestIndex">
      <button @click="sonClose">关闭</button>
  </div>
</template>

<!-- 组件js -->
<script>
export default {
  name: "TestIndex",
  data() {
    return{
        
    }
  },
  methods:{
    sonClose(){//子组件点击了关闭按钮
      //让父组件接收到我的这个信息
      // 如果需要传递参数,接收时一定要按照传递时的顺序取参数
      this.$emit("sClose","cxk",123);// 封装了一个方法名叫sClose的回调函数通知父组件
    }
  }
};
</script>

<!-- CSS代码 -->
<style scoped></style>

parent component code

<template>
  <div class="hello">
      
        <div class="myDiv" v-if="isShow">
            <!-- 回调函数接收的方法不要定义参数列表 -->
            <Test @sClose="fatherFunction"/>
        </div>

  </div>
</template>

<script>
//1. 导入要使用的组件  @代表的就是src目录路径,有点像classpath
import Test from '@/components/Test.vue';

export default {
  name: "HelloWorld",
  components:{Test},// 2.注册声明组件使用
  data() {
    return {
        isShow:true
    };
  },
  methods:{
    //父组件接收子组件回调的方法
    fatherFunction(param,param2){
        console.dir(param);
        console.dir(param2);
        this.isShow = false;
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.myDiv{
    width: 200px;
    height: 200px;
    background-color: aqua;
}
</style>

  1. Define a child component, the function is: implement a dynamic drop-down box through the list data passed by the parent component
  2. When the data is selected in the drop-down box, it is necessary to call back a time to the parent component (change\selected)
  3. Realize the function of clearing the drop-down box, click Clear to clear the selected content, and then call back an event to the parent component (clear\qingkong)

insert image description here

4. After the child component is defined, the parent component introduces the component, whether the trial is normal

15. Routing

1. What is routing

2. Three objects of routing

route: First of all, it is a singular number, translated as a route, that is, we can understand it as a single route or a certain route; (single route information)

routes: It is a plural number, which means that multiple sets can be plural; that is, we can understand it as a set of multiple routes. In JS, there are only two forms of sets that represent multiple different states: arrays and objects. In fact, the official definition of routes is An array; so we remember that routes represent a collection of multiple arrays; (all routing information in the entire project)

router: translated as a router, the above are routes, this is a router, we can understand it as a container containing the above two or it is a manager responsible for managing the above two; give an example of a common scenario: when the user is in When the button is clicked on the page, the router will go to the routes to find the route at this time, that is to say, the router will go to the route collection to find the corresponding route; (the object can realize multiple function jumps of the route)

3. How to configure routing

What address can access which component, describe the routing information

  1. Write component pages

2. Open the routing configuration file

insert image description here

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
//1. 导入需要配置路由的组件
import Test2 from '@/components/Test2.vue';

Vue.use(Router)

export default new Router({
    
    
  // 所有路由信息-集合
  routes: [// 第一个路由记录就是欢迎页
    {
    
    
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld,
      meta:{
    
    
        index:0,
        name:"首页"
      }
    },
    {
    
    // 2.编写路由
      path: '/test2',// 访问路径
      name: 'Test2', //路由组件名称
      component: Test2, //关联组件
      meta:{
    
    
        index:1, // 组件顺序-按照组件关系写
        name:"测试页面2" // 路由组件名称-中文描述-提供面包屑使用
      }
    }
  ]
})

How to change routing access

export default new Router({
    
    
  mode: 'history',// 路由地址前面就不会有/#/

4. Routing jump method

1. router-link tag

<!-- 效果类似a标签 -->
        <!-- <a href="/test2">XXXX</a> -->
        <router-link to="/test2">跳转到test2页面</router-link>

2. $router object

push method - it will add the record of route jump to the browser's cache record, and you can use the browser's forward and backward functions

replace method - then the accessed data will not be added to the record

1.push method - directly pass the routing address string

<template>
  <div class="hello">
        <button @click="doRouter">点击跳转</button>
  </div>
</template>

<script>

export default {
  name: "HelloWorld",
  data() {
    return {
        
    };
  },
  methods:{
    //路由跳转方法
    doRouter(){
       this.$router.push('/test2');
    }
  }
};
</script>

2.push method - pass a routing information object

<template>
  <div class="hello">
        <button @click="doRouter">点击跳转</button>
  </div>
</template>

<script>

export default {
  name: "HelloWorld",
  data() {
    return {
        routeData:{
          path:'/test2'
        }
    };
  },
  methods:{
    //路由跳转方法
    doRouter(){
       this.$router.push(this.routeData);
    }
  }
};
</script>

3.push-passed routing information object-the redirected page is determined by name

<template>
  <div class="hello">
        <button @click="doRouter">点击跳转</button>
  </div>
</template>

<script>

export default {
  name: "HelloWorld",
  data() {
    return {
        routeData:{
          name:"Test2" // 路由定义的index.js中定义路由的name值
        }
    };
  },
  methods:{
    //路由跳转方法
    doRouter(){
       this.$router.push(this.routeData);
    }
  }
};
</script>

4.replcae method

Same usage as push

// 字符串
this.$router.replace('/home/first')
// 对象
this.$router.replace({ path: '/home/first' })
// 命名的路由
this.$router.replace({ name: 'home', params: { userId: wise }})

5. go method

//前进一步 相当于history.forward()
this.$router.go(1) 
、
//后退一步 相当于history.back()
this.$router.go(-1) 

this.$router.go(10) 

3. Nested sub-routes

Usage scenario: the backend of the enterprise management system, the interface refreshed by the components on the right side of the menu on the left

Home page:

<!-- Dom页面 -->
<template>
  <div id="Main">

        <h1>主页</h1>
        <router-link to="/user">用户管理</router-link>
        <router-link to="/role">角色管理</router-link>
        <!-- 路由切换视图标签 -->
        <router-view />    
  </div>
</template>

<!-- 组件js -->
<script>
export default {
  name: "Main",
  data() {
    return {};
  }
};
</script>

<!-- CSS代码 -->
<style scoped></style>

routing configuration

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Main from '@/components/main'
//1. 引入组件
import User from '@/components/user'
import Role from '@/components/role'

Vue.use(Router)

export default new Router({
    
    
  mode: 'history',// 路由地址前面就不会有/#/
  // 所有路由信息-集合
  routes: [// 第一个路由记录就是欢迎页
    {
    
    
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld,
      meta:{
    
    
        index:0,
        name:"登录页面"
      }
    },
    {
    
    
      path: '/main',
      name: 'Main',
      component: Main,
      meta:{
    
    
        index:1,
        name:"首页"
      },
      children:[// 子路由!!!!!!!
        {
    
    
          path: '/user',
          name: 'User',
          component: User,
          meta:{
    
    
            index:1-1,
            name:"用户管理"
          }
        },
        {
    
    
          path: '/role',
          name: 'Role',
          component: Role,
          meta:{
    
    
            index:1-2,
            name:"角色管理"
          }
        }
      ]
    }
    
  ]
})

5. Routing parameters

1. Splicing parameters on the routing path - the parameters will not be lost when the page is refreshed

In the routing configuration file, declare the location where the parameter will appear on the path attribute

{
    
    
      path: '/:id', // 在/ 路径之后 会传递一个 名字叫id的参数
      name: 'HelloWorld',
      component: HelloWorld,
      meta:{
    
    
        index:0,
        name:"登录页面"
      }
    },

Call routing jump is to pass parameters

Note: Only simple strings and values, boolean types can be passed, objects cannot be passed

this.$router.push({ path:`/main/${this.param}`});

Obtain parameters in the target routing component

<!-- Dom页面 -->
<template>
  <div id="Main">

        <h1>主页</h1>
        <h1>{
    
    {
    
     $route.params.id }}</h1>
  </div>
</template>

2. When calling the routing method, add the params attribute to pass parameters - refresh page parameters will be lost

The routing configuration file does not need to be modified

Call the routing jump method

This method supports object passing

// 想要使用params传递参数,路由跳转的方法必须使用name指定路由页面才行
       this.$router.push({
    
     name:"Main",params:this.param});

3. When calling the routing method, add the query attribute to pass the parameters - refreshing the page will not lose the parameters

The routing configuration file does not need to be modified

Call the routing jump method

This method supports object passing

this.$router.push({
    
     path:"/main",query:this.param});

The routing target page takes parameters, which must be obtained through query parameters

this.loginUser = this.$route.query.name;

Summarize the three methods of routing parameters:

1. Path splicing method: If there are scenes that must be initialized or parameters must be passed before use

​ 2.params method: encrypt the passed parameters, but the data transmission is one-time

​ 3.query method: the parameters are not encrypted, and are directly exposed in the url

routes object access

this.$router.options.routes

Ability to access all routing information for the current project

6. Vue routing jump loading progress bar

1. Use Nprogress

Execute in the project's window

cnpm install nprogress

2. Introduce components and styles into main.js

import NProgress from 'nprogress' 
import 'nprogress/nprogress.css'// nprogress样式文件

3. Routing component hook function configuration

Two hooks: before the route jump and after the jump

// 路由的钩子函数是main.js中配置的

// 路由跳转之前
router.beforeEach((to, from , next) => {
    
    
    // 开启进度条
    NProgress.start();
    // 这个一定要加,没有next()页面不会跳转的。这部分还不清楚的去翻一下官网就明白了
    next();
});


//当路由跳转结束后
router.afterEach(() => {
    
      
    // 关闭进度条
    NProgress.done()
})


  1. It is necessary to implement a table component for adding, deleting, modifying and paginating

16. axios component

Function: Same as ajax, the underlying implementation is js-ajax, and the writing method is simpler than the JQuery and js ajax learned before

installation steps

//1. 在项目窗口中执行
cnpm install axios


Configure axios content in main.js

import axios from 'axios'
Vue.prototype.$axios = axios //全局属性

How to define global properties

在main.js中定义

// 定义全局属性的方法
// Vue.prototype.自定义属性名 = 组件对象
// 属性命名规则:$+属性名
// 在组件中使用全局属性: this.$axios   
Vue.prototype.$axios = axios //全局属性

Cross-domain problem handling, request service address configuration

What is cross domain?

Due to the browser's same-origin policy restrictions. The same origin policy (Same origin policy) is a convention, which is the core and most basic security function of the browser. If the same origin policy is missing, the normal functions of the browser may be affected. It can be said that the Web is built on the basis of the same-origin policy, and the browser is only an implementation of the same-origin policy. The same-origin policy prevents javascript scripts from one domain from interacting with content from another domain. The so-called same origin (that is, in the same domain) means that two pages have the same protocol (protocol), host (host) and port number (port)

Note: If one of the protocol + host + port is different, there will be cross-domain problems

1. Configure BaseUrl in the main.js file

axios.defaults.baseURL = '/api'  //关键代码,/api之后替换的就是 http://localhost:8090

2. Configure the proxy, the proxyTable field in the index.js file under the config folder

module.exports = {
    
    
  dev: {
    
    

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
    
     // 配置到这里!!!!
      '/api': {
    
    // 配置了一个静态地址代理
        target:'http://localhost:8090', // 后端服务地址以及端口号
        changeOrigin:true,  // 可以跨域
        pathRewrite:{
    
    
          '^/api': ''
        }
      }
    },
  1. main.js modifies the creation method of axios global attributes
Vue.prototype.$axios = axios.create({
    
    
	baseURL:'/api',
	timeout:30000
})

  1. Stop the project, execute cnpm install, and then start the project
  1. Test Case
getData() {
    
    
      console.dir(this);
      // 在axios代码中要使用this关键字访问data或者方法等等vue组件内容的话需要定一个别名变量
      let _this = this;
      this.$axios
        .get("goods/goods/getGoodsByID?id=101")
        .then(function(res) {
    
    
          _this.resData = res.data;
        })
        .catch(function(error) {
    
    
          // 请求失败处理
          console.log(error);
        });
    }

4 requests

GET request

  1. The parameters are spliced ​​after the url
// 直接在 URL 上添加参数 ID=12345
axios.get('/user?ID=12345')
  .then(function (response) {
    
    
    console.log(response);
  })
  .catch(function (error) {
    
    
    console.log(error);
  });

  1. Pass in a parameter with the params attribute
 this.$axios
        .get("goods/goods/getGoodsByID",{
    
    
          params:{
    
    // 写键值对参数内容
            id:101
          }
        })

POST request

The request has already encapsulated the data as json data to send the backend, so when writing the controller method at the backend, remember to use the @RequestBody annotation to receive parameters

The put\delete request is written in the same way as the post

this.$axios
        .post("goods/goods/testpost",{
    
      // 参数传递的方法和GET不同
          name:"张三",
          price:18.9
        })

Batch submit request method

What needs to be used is the all method of the axios component object, and the $axios object used in the above case is an instance created by the component object.create

So we need to redefine a global axios component object

main.js中定义组件对象全局属性

Vue.prototype.$VueAxios = axios;  // all 再用该对象    新配置的组件对象

Vue.prototype.$axios = axios.create({
    
    // get post delete put
	baseURL:'/api',
	timeout:30000
})

Batch interface call method

getData1() {
    
    
       return  this.$axios
        .post("goods/goods/testpost",{
    
    
          name:"张三",
          price:18.9
        });
    },
    getData2() {
    
    
       return  this.$axios.get("goods/goods/getGoodsByID?id=101");
    },
    //合并提交方法
    getAllData(){
    
    
      let _this = this;
      console.dir(this.$axios);
      this.$VueAxios.all([_this.getData1(),_this.getData2()]) // 按照数组顺序调用
      .then(_this.$VueAxios.spread(function (res1, res2) {
    
     // 根据调用方法的数量定义接收对应方法返回的数据参数
        // 当所有的方法执行完成且都有返回值之后
          console.dir("请求完成");
          console.dir(acct);
          console.dir(perms);
       }));

    }

request interceptor

The role of the request interceptor

Intercept before axios sends the request to the backend, you can modify the parameters of the request, etc.

写在main.js中

// http request 请求拦截器
axios.interceptors.request.use(config => {
    
    
	// 在发送请求之前做些什么
	return config;
}, error => {
    
    
	// 对请求错误做些什么
	return Promise.reject(error);
});

response interceptor

effect:

​ All requests will enter the modified interceptor when returning a response

// 响应拦截器
Vue.prototype.$axios.interceptors.response.use(response => {
    
    

  console.dir(response);
  if(response.data.code == "9999"){
    
    //系统异常
    // 统一错误提示弹窗
  }else if(response.data.code == "-1"){
    
     // 登录会话失效
    // 使用路由返回到登录页面
  }

  return response;
},error => {
    
    
  if (error.response) {
    
    
   // 返回接口返回的错误信息
   return Promise.reject(error.response.data);
 }
});

17. Subcomponent custom v-model

v-model: can only appear on form functions

Case: The child component implements gender radio selection, the v-model realizes the code value of binding gender, and the child-parent data bound by the v-model will change when the child-parent component is modified

Subcomponent writing

<template>
  <div id="Test1">
    <!-- 子组件:性别的单选框 怎么设计和实现v-model -->
    <input type="radio" :value="1" :checked="isManChecked" name="sex" @change="sexChange(1)" />男
    <input type="radio" :value="2" :checked="isWoManChecked" name="sex" @change="sexChange(2)"/>女
  </div>
</template>


<script>
export default {
  name: "Test1",
  props:{
    sexCode:{
        type:Number
    }
  },
  //v-model绑定数据
  model:{
        prop:'sexCode',  // v-model绑定的参数是sexCode字段
        event:'onchange' // v-model数据更新的回调事件叫什么(v-model更改过程是依赖事件)
  },
  watch:{
    sexCode:function(newV,oldV){
        if(newV==1){//男选中
            this.isManChecked = true;
            this.isWoManChecked = false;
        }else{//选中女
            this.isManChecked = false;
            this.isWoManChecked = true;
        }
    }
  },
  data() {
    return {
        isManChecked:false,
        isWoManChecked:false
    };
  },
  methods:{
    sexChange(param){
        this.$emit("onchange",param); // 第二个参数,就是更新父组件v-model绑定数据的值
    }
  }
};
</script>

<!-- CSS代码 -->
<style scoped></style>

parent component

<Test1 v-model="data" />

18. Slot

Function: It is possible to place the specified label in the slot container of the component, which can standardize the component content composition and flexibly configure the component content

slot label

<slot>。。</slot>

slot - default slot

Also called unnamed slot, it is generally used when the parent component quickly replaces the default content of the child component in batches

subcomponent definition

<template>
  <div id="Test1">
    <div class="div1">
        <!-- 默认插槽写法:<slot> -->
        <slot>默认插槽的文字1</slot> 
    </div>
    <div class="div2">
        <slot>默认插槽的文字2</slot>
    </div>
  </div>
</template>

Parent component changes default slot method

<Test1 v-model="sexCode" >
   <!-- 在子组件中添加html代码段就会替换默认插槽信息 -->
   <h1>XXX</h1>
   <h1>XXX222</h1>
</Test1>

insert image description here

named slot

subcomponent definition

<template>
  <div id="Test1">
    <div class="div1">
        <slot name="one">插槽的文字1</slot>
    </div>
    <div class="div2">
        <slot name="two">插槽的文字2</slot>
    </div>
  </div>
</template>

parent component

<Test1 v-model="sexCode" >
        <!-- 具名插槽赋值方法:template标签 v-slot:插槽的name值 -->
        <template v-slot:one>
         <h1>XXX</h1>
        </template>
      </Test1>

slot attribute assignment named slot method

<!-- 具名插槽赋值方法:可以使用在标签上  slot="插槽名称" -->
        <div slot="one">
          <h1>XXX</h1>
        </div>

Object scoped slots

Subassembly

<template>
  <div id="Test1">
    <div class="div1">
        <!-- 绑定了一个叫obj的属性在插槽上 -->
        <slot :obj2="objData" :obj="objData">插槽的文字1</slot>
    </div>
  </div>
</template>

<script>
export default {
      
      
  name: "Test1",
  data() {
      
      
    return {
      
      
        objData:{
      
      
            name:"张三",
            age:18
        }
    };
  },
  methods:{
      
      
  }
};
</script>

parent component

<Test1 v-model="sexCode" >
        <!-- template标签声明v-slot="定义一个变量接收子组件插槽中定义的对象" -->
        <template v-slot="objData">
          <!-- 对象.插槽属性名.插槽属性对象的属性值 -->
          <h1>{
   
   { objData.obj2.name }}</h1>
        </template>
      </Test1>

19. Vuex state management

1. Installation method

Execute in the project cmd window

cnpm install vuex

Create a store.js file,

Create a vuex folder in the src directory, and create a store.js file in the folder

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
    
    
    state:{
    
    

    },
    getters:{
    
    

    },
    mutations:{
    
    

    },
    actions:{
    
    
        
    }
});

Import the component in main.js

//导入vuex组件内容
import Vuex from 'vuex';
import store from './vuex/store'
Vue.use(Vuex);
Vue.prototype.$store = store;


// 修改原有的new Vue构造器
new Vue({
    
    
  el: '#app',
  router,
  store, // 添加到全局组件
  components: {
    
     App },
  template: '<App/>'
})

Instructions

1. Set save data

在state对象中描述要保存的数据

export default new Vuex.Store({
    
    
    state:{
    
    // 共享的数据
        count:0
    },

2. Modify data

1.action - call method without parameters

actions:{
    
    // 操作state里的数据方法
        addCount(){
    
    // 每次调用让count数据+1
            this.state.count++;
        },

call method

// 调用了vuex中action中的addCount方法,无参调用
        this.$store.dispatch("addCount"); // 字符串的action方法名

2.action - call method with parameters

// 形参1: vuex对象
// 形参2: 传入的数据(如果要传递多个参数,就封装到对象中---map、集合)
addCount2(obj,param){
    
    
    this.state.count += param;
}

method called

this.$store.dispatch("addCount2",123);

3. mutations - call without arguments

mutations:{
    
    
        m_addCount(){
    
    
            this.state.count++;
        }
    },

call method

this.$store.commit("m_addCount");

4.mutations - call with parameters

// 形参1:  state对象 
// 形参2: 传入的数据(如果要传递多个参数,就封装到对象中---map、集合)
m_addCount2(obj,param){
    
    
            console.log(obj); // state对象 
            this.state.count += param;
        }

call method

this.$store.commit("m_addCount2",123);

3. Get the value

getters

getters:{
    
    // 获取值的操作
        getCount(obj){
    
    // 参数注入了当前vuex的state对象
            console.dir(obj.count); 
            return obj.count; // $store.getters.getCount
        }
    },

call method

this.$store.getters.getCount

mutations and action methods use selection

If you need asynchronous and fast execution, use the action method. If you need to ensure data read and write security by waiting, use the mutations method

The action method returns a promise function, and then and catch can be used to describe the success or failure of the method call

The mutations method does not, it is just a simple function call

The mutations method is recommended because of synchronization safety

20. ElementUI

1. Installation

Project cmd window execution

cnpm install element-ui

Import el component content in main.js

//导入elementui
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI);

Test whether the el component can be used


Guess you like

Origin blog.csdn.net/gjb760662328/article/details/129685305