Vue 脚手架是 Vue 官方提供的标准化开发工具(开发平台)
官方文档
npm install -g @vue/cli
npm config set registry https://registry.npm.taobao.org
npm run server
启动后:
访问效果:
目录结构:
. |-- App.vue |-- assets # 经常放静态资源,比如logo 图 | `-- logo.png |-- components # 放组件,除了App.Vue ,因为他是最有组件的最终管理者 | |-- School.vue | `-- Student.vue `-- main.js
组件:
School.vue
<template> <div class="demo"> <h2>学校名称:{{name}}</h2> <h2>学校地址:{{address}}</h2> <button @click="showName">点我提示学校名</button> </div> </template> <script> export default { name:'School', data(){ return { name:'尚硅谷', address:'北京昌平' } }, methods: { showName(){ alert(this.name) } }, } </script> <style> .demo{ background-color: orange; } </style>
Student.vue
<template> <div> <h2>学生姓名:{{name}}</h2> <h2>学生年龄:{{age}}</h2> </div> </template> <script> export default { name:'Student', data(){ return { name:'张三', age:18 } } } </script>
App.vue
<template> <div> <img src="./assets/logo.png" alt="logo"> <School></School> <Student></Student> </div> </template> <script> //引入组件 import School from './components/School' import Student from './components/Student' export default { name:'App', components:{ School, Student } } </script>
main.js
/* 该文件是整个项目的入口文件 */ //引入Vue import Vue from 'vue' //引入App组件,它是所有组件的父组件 import App from './App.vue' //关闭vue的生产提示 Vue.config.productionTip = false /* 关于不同版本的Vue: 1.vue.js与vue.runtime.xxx.js的区别: (1).vue.js是完整版的Vue,包含:核心功能+模板解析器。 (2).vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。 2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用 render函数接收到的createElement函数去指定具体内容。 */ //创建Vue实例对象---vm new Vue({ el:'#app', //render函数完成了这个功能:将App组件放入容器中 render: h => h(App), // render:q=> q('h1','你好啊') // template:`<h1>你好啊</h1>`, // components:{App}, })
html 静态资源:
在 min.js 中我们引入了Vue:
其实这里的Vue 其实是vue.runtime.esm.js。他是残缺版的Vue(少了模板解析器)。所以我们在 min.js 中引入模板是无法解析的。.
如何解决的?这里就要引入 render。(当引入组件时,则只需传一个参数,组件名称)
测试效果,发现可以解析了:
为什么要用这些精简版的Vue呢?
因为模板解析器就占了整个Vue 约 1/3 。在Vue 打包的时候,就不需要在打包 模板解析器了,节省了空间。而且,模板解析器本就不应该出现在打包文件中。
官方文档地址
创建 vue.config.js 文件。在改文件中配置我们需要修改的配置
module.exports = { pages: { index: { // page 的入口 entry: 'src/index/main.js', // 模板来源 template: 'public/index.html', // 在 dist/index.html 的输出 filename: 'index.html', // 当使用 title 选项时, // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title> title: 'Index Page', // 在这个页面中包含的块,默认情况下会包含 // 提取出来的通用 chunk 和 vendor chunk。 chunks: ['chunk-vendors', 'chunk-common', 'index'] }, // 当使用只有入口的字符串格式时, // 模板会被推导为 `public/subpage.html` // 并且如果找不到的话,就回退到 `public/index.html`。 // 输出文件名会被推导为 `subpage.html`。 subpage: 'src/subpage/main.js' } }
这里就不一一展示,具体可以查看下文档。
1: 打标识:<h1 ref="xxx">.....</h1> 或 <School ref="xxx"></School> 2: 获取:this.$refs.xxx
<template> <div> <h1 v-text="msg" ref="title"></h1> <button ref="btn" @click="showDOM">点我输出上方的DOM元素</button> <School ref="sch"/> </div> </template> <script> //引入School组件 import School from './components/School' export default { name:'App', components:{School}, data() { return { msg:'欢迎学习Vue!' } }, methods: { showDOM(){ console.log(this.$refs.title) //真实DOM元素 console.log(this.$refs.btn) //真实DOM元素 console.log(this.$refs.sch) //School组件的实例对象(vc) } }, } </script>
控制台输出结果:
功能: 让组件接收外部传过来的数据
传递数据: <Demo name="xxx"/>
接收数据:
props:{ name:{ type:String, //类型 required:true, //必要性 default:'老王' //默认值 } }
注意:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。props中接收的数据会被绑定到组件实例对象vc上,且优先级高于data中的数据,data中的数据属性名字不能与接收的props属性名一致
App.vue:
<template> <div> <Student name="李四" sex="女" :age="18" /> <!-- 在组件标签中声明传入属性 :即v-bind 将字符串18变为js表达式(数字18),使其可以接受加法运算 另外,属性名不能为一些常用属性,比如:key,ref等 --> </div> </template> <script> import Student from "./components/Student"; export default { name: "App", components: { Student }, }; </script>
Student.vue
<template> <div> <h1>{{ msg }}</h1> <h2>学生姓名:{{ name }}</h2> <h2>学生性别:{{ sex }}</h2> <h2>学生年龄:{{ myAge + 1 }}</h2> <button @click="updateAge">尝试修改收到的年龄</button> </div> </template> <script> export default { name: "Student", data() { console.log(this); return { msg: "我是一个尚硅谷的学生", myAge: this.age, // props的数据不允许修改,想要改动得到propo的数据放入data中 // props的优先级高,data中的this.age是props中接收的数据 }; }, methods: { updateAge() { this.myAge++; }, }, //方法一:简单声明接收,放在组件实例对象vc上 // props:['name','age','sex'] //方法二:接收的同时对数据进行类型限制,类型如果不符合报错 /* props:{ name:String, age:Number, sex:String } */ //方法三:接收的同时对数据:进行类型限制+默认值的指定+必要性的限制 props: { name: { type: String, //name的类型是字符串 required: true, //name是必要的,有此属性一般不需要加默认值 }, age: { type: Number, default: 99, //默认值,即如果不传此属性则使用默认值 }, sex: { type: String, required: true, }, }, }; </script>
程序运行截图:页面中学生年龄点击增加,控制台中data中的属性myAge改变,props中age属性不变
功能: 可以把多个组件共用的配置提取成一个混入对象
使用方式:
{ data(){....}, methods:{....} .... }
- 使用前需要import导入 - 全局混入:Vue.mixin(xxx)放在main.js文件中,所有vm,vc都能得到混入的属性 - 局部混入:mixins:['xxx']放在需要的文件中,在此文件中得到混入的属性(原属性+混入属性) - 替换型策略有`props`、`methods`、`inject`、`computed`,就是将新的同名参数替代旧的参数 - 合并型策略是`data`, 通过`set`方法进行合并和重新赋值, 如果混入与自身(vc)有同名属性,自身属性优先级高,会覆盖掉混入属性 - 队列型策略有生命周期函数和`watch`,原理是将函数存入一个数组,然后正序遍历依次执行,自身(vc)的钩子在混合之后运行 - 叠加型有`component`、`directives`、`filters`,通过原型链进行层层的叠加 - 如果前后两个混合有同名属性,以后面的为主,
School.vue
<template> <div> <h2 @click="showName">学校名称:{{ name }}</h2> <h2>学校地址:{{ address }}</h2> </div> </template> <script> //引入一个hunhe // import {hunhe,hunhe2} from '../mixin' export default { name: "School", data() { return { name: "尚硅谷", address: "北京", x: 666, // 如果混入与自身有同名属性。自身属性优先级高 }; }, // mixins:[hunhe,hunhe2], }; </script>
Student.vue
<template> <div> <h2 @click="showName">学生姓名:{{ name }}</h2> <h2>学生性别:{{ sex }}</h2> </div> </template> <script> //局部混合: // import {hunhe,hunhe2} from '../mixin' export default { name: "Student", data() { return { name: "张三", sex: "男", }; }, // mixins:[hunhe,hunhe2] }; </script>
App.vue
<template> <div> <School/> <hr> <Student/> </div> </template> <script> import School from './components/School' import Student from './components/Student' export default { name:'App', components:{School,Student} } </script>
main.js
//引入Vue import Vue from 'vue' //引入App import App from './App.vue' //关闭Vue的生产提示 Vue.config.productionTip = false // 全局混合,给所有的vm和vc得到混合 import { hunhe, hunhe2 } from './mixin' Vue.mixin(hunhe) Vue.mixin(hunhe2) //创建vm new Vue({ el: '#app', render: h => h(App) })
mixin.js
export const hunhe = { methods: { showName(){ alert(this.name) } }, mounted() { console.log('你好啊!') }, } export const hunhe2 = { data() { return { x:100, y:200 } }, }
功能: 用于增强Vue
本质: 包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
定义插件:
对象.install = function (Vue, options) { // 1. 添加全局过滤器 Vue.filter(....) // 2. 添加全局指令 Vue.directive(....) // 3. 配置全局混入(合) Vue.mixin(....) // 4. 添加实例方法 Vue.prototype.$myMethod = function () {...} Vue.prototype.$myProperty = xxxx }
使用插件: Vue.use()
plugins.js
export default { install(Vue, x, y, z) { // 接收参数 console.log(x, y, z) //全局过滤器,从第一位开始,找到前四个 Vue.filter('mySlice', function (value) { return value.slice(0, 4) }) //定义全局指令,自动获取焦点 Vue.directive('fbind', { //指令与元素成功绑定时(一上来) bind(element, binding) { element.value = binding.value }, //指令所在元素被插入页面时 inserted(element, binding) { element.focus() }, //指令所在的模板被重新解析时 update(element, binding) { element.value = binding.value } }) //定义混入 Vue.mixin({ data() { return { x: 100, y: 200 } }, }) //给Vue原型上添加一个方法(vm和vc就都能用了) Vue.prototype.hello = () => { alert('你好啊') } } }
main.js
//引入Vue import Vue from 'vue' //引入App import App from './App.vue' //关闭Vue的生产提示 Vue.config.productionTip = false //引入插件 import plugins from './plugins' //应用(使用)插件 Vue.use(plugins, 1, 2, 3) // 传入参数 //创建vm new Vue({ el: '#app', render: h => h(App) })
School.vue
<template> <div> <h2>学校名称:{{name | mySlice}}</h2> <h2>学校地址:{{address}}</h2> <button @click="test">点我测试一个hello方法</button> </div> </template> <script> export default { name:'School', data() { return { name:'尚硅谷atguigu', address:'北京', } }, methods: { test(){ this.hello() } }, } </script>
Student.vue
<template> <div> <h2>学生姓名:{{name}}</h2> <h2>学生性别:{{sex}}</h2> <input type="text" v-fbind:value="name"> </div> </template> <script> export default { name:'Student', data() { return { name:'张三', sex:'男' } }, } </script>
App.vue
<template> <div> <School/> <hr> <Student/> </div> </template> <script> import School from './components/School' import Student from './components/Student' export default { name:'App', components:{School,Student} } </script>
如果不同组件起了相同的样式名,会造成样式冲突,在App.vue中后import导入的组件样式会覆盖前面一个组件的同名样式,所以用scoped解决。最好不要再App.vue的style中加入scoped,因为他是汇总组件,写在其中的样式为公共样式。
作用: 让样式在局部生效,防止冲突。
写法:
<style lang="less" scoped> //lang =''规定了用什么来写style,不写默认为css .demo{ background-color: pink; } </style>
代码
实现效果:
组件化编码流程:
props适用于:
1. 在父组件定义函数 methods: { addTodo(todoObj) { this.todos.unshift(todoObj); }, }, 2.将父组件函数传递给子组件 <MyHeader :addTodo="addTodo"></MyHeader> 3.子组件接收父组件传递的函数 props: ["addTodo"], 4.调用这个函数,通知App组件去添加一个todo对象 this.addTodo(todoObj);
使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!
props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。
相关API:
1. ```xxxxxStorage.setItem('key', 'value');``` 该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。 值为字符串,如果存入的值为对象,则将其转换为字符串后存入 2. ```xxxxxStorage.getItem('person');``` 该方法接受一个键名作为参数,返回键名对应的值。对象转字符串后存入,取出后需将其重新转化为对象 3. ```xxxxxStorage.removeItem('key');``` 该方法接受一个键名作为参数,并把该键名从存储中删除。 4. ```xxxxxStorage.clear()``` 该方法会清空存储中的所有数据。
备注:
xxxxxStorage.getItem(xxx)
如果xxx对应的value获取不到,那么getItem的返回值是null。JSON.parse(null)
的结果依然是null。localStorage.html文件:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>localStorage</title> </head> <body> <h2>localStorage</h2> <button onclick="saveData()">点我保存一个数据</button> <button onclick="readData()">点我读取一个数据</button> <button onclick="deleteData()">点我删除一个数据</button> <button onclick="deleteAllData()">点我清空一个数据</button> <script type="text/javascript"> let p = { name: '张三', age: 18 } function saveData() { localStorage.setItem('msg', 'hello!!!') localStorage.setItem('msg2', 666) localStorage.setItem('person', JSON.stringify(p)) } function readData() { console.log(localStorage.getItem('msg')) console.log(localStorage.getItem('msg2')) const result = localStorage.getItem('person') JSON.parse(result) // console.log(localStorage.getItem('msg3')) } function deleteData() { localStorage.removeItem('msg2') } function deleteAllData() { localStorage.clear() } </script> </body> </html>
sessionStorage.html文件
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>sessionStorage</title> </head> <body> <h2>sessionStorage</h2> <button onclick="saveData()">点我保存一个数据</button> <button onclick="readData()">点我读取一个数据</button> <button onclick="deleteData()">点我删除一个数据</button> <button onclick="deleteAllData()">点我清空一个数据</button> <script type="text/javascript" > let p = {name:'张三',age:18} function saveData(){ sessionStorage.setItem('msg','hello!!!') sessionStorage.setItem('msg2',666) sessionStorage.setItem('person',JSON.stringify(p)) } function readData(){ console.log(sessionStorage.getItem('msg')) console.log(sessionStorage.getItem('msg2')) const result = sessionStorage.getItem('person') console.log(JSON.parse(result)) // console.log(sessionStorage.getItem('msg3')) } function deleteData(){ sessionStorage.removeItem('msg2') } function deleteAllData(){ sessionStorage.clear() } </script> </body> </html>
一种组件间通信的方式,适用于:子组件 ===> 父组件
使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。
绑定自定义事件:
第一种方式,在父组件中:<Demo @atguigu=“test”/> 或 <Demo v -on:atguigu=“test”/>
第二种方式,在父组件中:
若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。
触发自定义事件:this.$emit(‘atguigu’,数据)
解绑自定义事件this.$off(‘atguigu’)
组件上也可以绑定原生DOM事件,需要使用native修饰符,否则会被当成自定义事件。
注意:通过this. r e f s . x x x . refs.xxx. refs.xxx.on(‘atguigu’,回调)绑定自定义事件时,回调要么配置在methods中,使用this调用回调名,要么用箭头函数在mounted中书写函数体,否则this指向会出问题!
App.vue
<template> <div class="app"> <h1>{{ msg }},学生姓名是:{{ studentName }}</h1> <!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 --> <School :getSchoolName="getSchoolName" /> <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(方法一,使用@或v-on) --> <!-- <Student @atguigu="getStudentName" @demo="m1" /> --> <!-- 方法一:2.给student组件的实例对象vc绑定一个事件 --> <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(方法二,使用ref) --> <Student ref="student" @click.native="show" /> <!-- 方法二:2.给student绑定ref获取组件实例对象 --> </div> </template> <script> import Student from "./components/Student"; import School from "./components/School"; export default { name: "App", components: { School, Student }, data() { return { msg: "你好啊!", studentName: "", }; }, methods: { getSchoolName(name) { console.log("App收到了学校名:", name); }, getStudentName(name, ...params) { //方法一/二:1.定义一个方法 console.log("App收到了学生名:", name, params); // 接收name和一个数组对象,数组内存储着其余参数 this.studentName = name; }, m1() { console.log("demo事件被触发了!"); }, show() { alert(123); }, }, mounted() { // 方法二:3.App.vue挂载完毕,获取student的组件实例对象,绑定自定义事件 this.$refs.student.$on("atguigu", this.getStudentName); //绑定自定义事件 // this.$refs.student.$once('atguigu',this.getStudentName) //绑定自定义事件(一次性) }, }; </script> <style scoped> .app { background-color: gray; padding: 5px; } </style>
student.vue
<template> <div class="student"> <h2>学生姓名:{{ name }}</h2> <h2>学生性别:{{ sex }}</h2> <h2>当前求和为:{{ number }}</h2> <button @click="add">点我number++</button>、 <!-- 方法一:3.定义 sendStudentlName点击事件--> <!-- 方法二:4.定义 sendStudentlName点击事件--> <button @click="sendStudentlName">把学生名给App</button> <button @click="unbind">解绑atguigu事件</button> <button @click="death">销毁当前Student组件的实例(vc)</button> </div> </template> <script> export default { name: "Student", data() { return { name: "张三", sex: "男", number: 0, }; }, methods: { add() { console.log("add回调被调用了"); this.number++; }, sendStudentlName() { //方法一:4.触发Student组件实例身上的atguigu事件 //方法二:5.触发Student组件实例身上的atguigu事件 this.$emit("atguigu", this.name, 666, 888, 900); // this.$emit("demo"); // 触发Student组件实例身上的demo事件 // this.$emit('click') }, unbind() { this.$off("atguigu"); //解绑一个自定义事件 // this.$off(['atguigu','demo']) //解绑多个自定义事件 // this.$off() //解绑所有的自定义事件 }, death() { this.$destroy(); //销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效, // 原生DOM事件不受影响,但页面响应式丢了。 }, }, }; </script> <style scoped> .student { background-color: pink; padding: 5px; margin-top: 30px; } </style>
school.vue
<template> <div class="school"> <h2>学校名称:{{name}}</h2> <h2>学校地址:{{address}}</h2> <button @click="sendSchoolName">把学校名给App</button> </div> </template> <script> export default { name:'School', props:['getSchoolName'], data() { return { name:'尚硅谷', address:'北京', } }, methods: { sendSchoolName(){ this.getSchoolName(this.name) } }, } </script> <style scoped> .school{ background-color: skyblue; padding: 5px; } </style>
1.Vue原型对象上包含事件处理的方法 1)$on(eventName,listener):绑定自定义事件监听 2)$emit(eventName,data):分发自定义事件 3)$off(eventName):解绑自定义事件监听 4)$once(eventName,listener):绑定事件监听,但只能处理一次 2.所有组件实例对象的原型对象的原型对象就是Vue的原型对象 1)所有组件对象都能看到Vue原型对象上的属性和方法 2)Vue.prototype.$bus=new Vue(),所有的组件对象都能看到$bus这个属性对象 3.全局事件总线 1)包含事件处理相关方法的对象(只有一个) 2)所有的组件都可以得到
main.js
//引入Vue import Vue from 'vue' //引入App import App from './App.vue' //关闭Vue的生产提示 Vue.config.productionTip = false //创建vm new Vue({ el:'#app', render: h => h(App), beforeCreate() { Vue.prototype.$bus = this //安装全局事件总线 }, })
App.vue
<template> <div class="app"> <h1>{{msg}}</h1> <School/> <Student/> </div> </template> <script> import Student from './components/Student' import School from './components/School' export default { name:'App', components:{School,Student}, data() { return { msg:'你好啊!', } } } </script> <style scoped> .app{ background-color: gray; padding: 5px; } </style>
Student.vue
<template> <div class="student"> <h2>学生姓名:{{ name }}</h2> <h2>学生性别:{{ sex }}</h2> <button @click="sendStudentName">把学生名给School组件</button> </div> </template> <script> export default { name: "Student", data() { return { name: "张三", sex: "男", }; }, mounted() { // console.log('Student',this.x) }, methods: { sendStudentName() { this.$bus.$emit("hello", this.name); //提供数据,将student组件中的数据传递给school }, }, }; </script> <style scoped> .student { background-color: pink; padding: 5px; margin-top: 30px; } </style>
School.vue
<template> <div class="school"> <h2>学校名称:{{ name }}</h2> <h2>学校地址:{{ address }}</h2> </div> </template> <script> export default { name: "School", data() { return { name: "尚硅谷", address: "北京", }; }, mounted() { // console.log('School',this) this.$bus.$on("hello", (data) => { console.log("我是School组件,收到了数据", data); }); }, beforeDestroy() { this.$bus.$off("hello"); // 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件,一定要写解绑的事件名,否则就全部解绑了 }, }; </script> <style scoped> .school { background-color: skyblue; padding: 5px; } </style>
下载 Spubsub-js:npm install-Spubsub-js
相关语法:
(1)import PubSub from 'pubsub-js'//引入 (2)PubSub.subscribe(‘msgName’,functon(msgName,data){})订阅消息 (3)PubSub.publish(‘msgName’,data):发布消息,触发订阅的回调函数调用 (4)PubSub.unsubscribe(token):取消消息的订阅
使用步骤:
methods: { demo(msgName, data) { console.log( "有人发布了hello消息,hello消息的回调执行了", msgName, data, this ); }, }, ...... this.pubId = pubsub.subscribe("hello", this.demo);
提供数据:B组件传递数据,则在B组件中发布消息
methods: { sendStudentName() { // 发布消息:pubsub.publish(事件名,参数), pubsub.publish("hello", 666); }, },
最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid)去取消订阅。
Student.vue
<template> <div class="student"> <h2>学生姓名:{{ name }}</h2> <h2>学生性别:{{ sex }}</h2> <button @click="sendStudentName">把学生名给School组件</button> </div> </template> <script> import pubsub from "pubsub-js"; // 引入pubsub-js,pubsub是一个对象 export default { name: "Student", data() { return { name: "张三", sex: "男", }; }, methods: { sendStudentName() { // 发布消息:pubsub.publish(事件名,参数), pubsub.publish("hello", 666); }, }, }; </script> <style scoped> .student { background-color: pink; padding: 5px; margin-top: 30px; } </style>
School.vue
<template> <div class="school"> <h2>学校名称:{{ name }}</h2> <h2>学校地址:{{ address }}</h2> </div> </template> <script> import pubsub from "pubsub-js"; // 引入pubsub-js,pubsub是一个对象 export default { name: "School", data() { return { name: "尚硅谷", address: "北京", }; }, methods: { demo(msgName, data) { console.log( "有人发布了hello消息,hello消息的回调执行了", msgName, data, this ); }, }, mounted() { /*订阅消息:pubsub.subscribe(消息名,回调函数function(消息名,传入的参数){ console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data) console.log(this); 这里this为undefined,想要避免有如下两种方法 }) */ // 方法一:this调用methods方法 // this.pubId = pubsub.subscribe("hello", this.demo); // 方法二:使用箭头函数 this.pubId = pubsub.subscribe("hello", (msgName, data) => { console.log("有人发布了hello消息,hello消息的回调执行了", msgName, data); console.log(this); }); }, beforeDestroy() { // 取消订阅 pubsub.unsubscribe(this.pubId); }, }; </script> <style scoped> .school { background-color: skyblue; padding: 5px; } </style>
语法:this.$nextTick(回调函数)
作用:在下一次 DOM 更新结束后执行其指定的回调。
什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。
例如:我们界面总的编辑按钮,该输入框是否可编辑是通过某个值来控制的,当值改变后,DOM更新完成之后,我们需要鼠标重新指向我们输入框的位置,就需要该函数在DOM重新解析后在调用来达到进入编辑页面后,鼠标就自动汇聚到该输入框的功能。
点编辑后效果: