Vue.js-----vue组件

  • 能够说出vue生命周期
  • 能够掌握axios的使用
  • 能够了解$refs, $nextTick作用
  • 能够完成购物车案例

Vue 生命周期讲解

1.钩子函数

目标:Vue 框架内置函数,随着组件的生命周期阶段,自动执行

  • 作用: 特定的时间点,执行特定的操作
  • 场景: 组件创建完毕后,可以在created 生命周期函数中发起Ajax 请求,从而初始化 data 数据
  • 分类: 4大阶段8个方法

如何知道Vue生命周期到达了什么阶段? 使用钩子函数

钩子函数有哪些?初始化 / 挂载 / 更新 / 销毁

2.初始化  

  • 1. new Vue() – Vue实例化(组件也是一个小的Vue实例)
  • 2. Init Events & Lifecycle – 初始化事件和生命周期函数
  • 3. beforeCreate – 生命周期钩子函数被执行
  • 4. Init injections&reactivity – Vue内部添加data和methods等
  • 5. created – 生命周期钩子函数被执行, 实例创建
  • 6. 接下来是编译模板阶段 –开始分析
  • 7. Has el option? – 是否有el选项 – 检查要挂到哪里
  • 没有. 调用$mount()方法
  • 有, 继续检查template选项

在App.vue中引入vue实例化文件

<template>
  <div>
    <h1>1. 生命周期</h1>
    <LifeCycle v-if="show"></LifeCycle>
  </div>
</template>

<script>
import LifeCycle from './components/LifeCycle.vue'
export default {
  data() {
    return {
      show: true
    }
  },
  components: {
    LifeCycle,
  }
}
</script>

<style></style>

在vue实例化文件中初始化事件和周期函数

<template>
  <div>
      <p>学习生命周期 - 看控制台打印</p>
      <p id="myP">{{ msg }}</p>
      <ul id="myUL">
          <li v-for="(val, index) in arr" :key="index">
              {{ val }}
          </li>
      </ul>
      <!-- <button @click="arr.push(1000)">点击末尾加值</button> -->
  </div>
</template>

<script>
export default {
    data(){
        return {
            msg: "hello, Vue",
            // arr: [5, 8, 2, 1],
            // timer: null // 保存计时器
        }
    },
    // 一. 初始化
    // new Vue()以后, vue内部给实例对象添加了一些属性和方法, data和methods初始化"之前"
    beforeCreate(){
        console.log("beforeCreate -- 执行");
        console.log(this.msg); // undefined
    },
    // data和methods初始化以后
    // 场景: 网络请求, 注册全局事件
    created(){
        console.log("created -- 执行");
        console.log(this.msg); // hello, Vue

        
    },


}
</script>

<style>

</style>

运行启动该项目

 

遇到以下问题是因为Vue 组件中存在一个 ESLint 错误,指出组件名 “Life” 不符合命名规范。根据 ESLint 的建议,组件名应该是多个单词组成的 

如果修改之后还是报同样的错误,可以直接把终端关掉重新启动该项目

Vue实例从创建到编译模板执行了哪些钩子函数? beforeCreate / created

created函数触发能获取data? 能获取data, 不能获取真实DOM

3.挂载  

1. template选项检查

          有 - 编译template返回render渲染函数

          无 – 编译el选项对应标签作为template(要渲染的模板)

  • 2. 虚拟DOM挂载成真实DOM之前
  • 3. beforeMount – 生命周期钩子函数被执行
  • 4. Create … – 把虚拟DOM和渲染的数据一并挂到真实DOM上
  • 5. 真实DOM挂载完毕
  • 6. mounted – 生命周期钩子函数被执行

在App.vue中引入vue实例化文件

<template>
  <div>
    <h1>1. 生命周期</h1>
    <LifeCycle v-if="show"></LifeCycle>
  </div>
</template>

<script>
import LifeCycle from './components/LifeCycle.vue'
export default {
  data() {
    return {
      show: true
    }
  },
  components: {
    LifeCycle,
  }
}
</script>

<style></style>

 在vue实例化文件中挂载钩子函数

<template>
  <div>
      <p>学习生命周期 - 看控制台打印</p>
      <p id="myP">{{ msg }}</p>
      <!-- <ul id="myUL">
          <li v-for="(val, index) in arr" :key="index">
              {{ val }}
          </li>
      </ul> -->
      <!-- <button @click="arr.push(1000)">点击末尾加值</button> -->
  </div>
</template>

<script>
export default {
    data(){
        return {
            msg: "hello, Vue",
            // arr: [5, 8, 2, 1],
            // timer: null // 保存计时器
        }
    },
    // 一. 初始化
    // new Vue()以后, vue内部给实例对象添加了一些属性和方法, data和methods初始化"之前"
    beforeCreate(){
        console.log("beforeCreate -- 执行");
        console.log(this.msg); // undefined
    },
    // data和methods初始化以后
    // 场景: 网络请求, 注册全局事件
    created(){
        console.log("created -- 执行");
        console.log(this.msg); // hello, Vue

        
    },

    // 二.挂载
    // 真实DOM挂载之前
    // 场景:预处理data,不会触发updated钩子函数
    beforeMount(){
        console.log("beforeMount -- 执行");
        console.log(document.getElementById("myP")) //null
    },
    // 真实挂载之后
    // 场景:挂载后真实的DOM
    mounted(){
        console.log("mounted --执行")
        console.log(document.getElementById("myP")) //标签p里面的内容
    }

}
</script>

<style>

</style>

运行此项目 

Vue实例从创建到显示都经历了哪些钩子函数?

beforeCreate / created / beforeMount / mounted

created函数里, 能获取真实DOM吗? 不能获取真实DOM

在什么钩子函数里可以获取真实DOM?mounted

4.更新  

  • 1. 当data里数据改变, 更新DOM之前
  • 2. beforeUpdate – 生命周期钩子函数被执行
  • 3. Virtual DOM…… – 虚拟DOM重新渲染, 打补丁到真实DOM
  • 4. updated – 生命周期钩子函数被执行
  • 5. 当有data数据改变 – 重复这个循环

App.vue

<template>
  <div>
    <h1>1. 生命周期</h1>
    <LifeCycle v-if="show"></LifeCycle>
  </div>
</template>

<script>
import LifeCycle from './components/LifeCycle.vue'
export default {
  data() {
    return {
      show: true
    }
  },
  components: {
    LifeCycle,
  }
}
</script>

<style></style>

 LifeCycle.vue

<template>
  <div>
      <p>学习生命周期 - 看控制台打印</p>
      <p id="myP">{{ msg }}</p>
      <ul id="myUL">
          <li v-for="(val, index) in arr" :key="index">
              {{ val }}
          </li>
      </ul>
      <button @click="arr.push(1000)">点击末尾加值</button>
  </div>
</template>

<script>
export default {
    data(){
        return {
            msg: "hello, Vue",
            arr: [5, 8, 2, 1],
            // timer: null // 保存计时器
        }
    },
    // 一. 初始化
    // new Vue()以后, vue内部给实例对象添加了一些属性和方法, data和methods初始化"之前"
    beforeCreate(){
        console.log("beforeCreate -- 执行");
        console.log(this.msg); // undefined
    },
    // data和methods初始化以后
    // 场景: 网络请求, 注册全局事件
    created(){
        console.log("created -- 执行");
        console.log(this.msg); // hello, Vue

        
    },

    // 二.挂载
    // 真实DOM挂载之前
    // 场景:预处理data,不会触发updated钩子函数
    beforeMount(){
        console.log("beforeMount -- 执行");
        console.log(document.getElementById("myP")) //null
    },
    // 真实挂载之后
    // 场景:挂载后真实的DOM
    mounted(){
        console.log("mounted --执行")
        console.log(document.getElementById("myP")) //标签p里面的内容
    },


    // 三.更新
    // 前提:data数据改变才执行
    // 更新之前
    beforeUpdate(){
        console.log("beforeUpdate -- 执行")
        console.log(document.querySelectorAll("#myUL>li")[4]);
    },

    // 更新之后
    // 获取更新后的真实DOM
    updated(){
        console.log("updated --- 执行")
        console.log(document.querySelectorAll("#myUL>li")[4])
    }

}
</script>

<style>

</style>

运行此项目 

什么时候执行updated钩子函数 当数据发生变化并更新页面后

在哪可以获取更新后的DOM 在updated钩子函数里

5.销毁  

  • 1. 当$destroy()被调用 – 比如组件DOM被移除(例v-if)
  • 2. beforeDestroy – 生命周期钩子函数被执行
  • 3. 拆卸数据监视器、子组件和事件侦听器
  • 4. 实例销毁后, 最后触发一个钩子函数
  • 5. destroyed – 生命周期钩子函数被执行

App.vue

<template>
  <div>
    <h1>1. 生命周期</h1>
    <LifeCycle v-if="show"></LifeCycle>
     <button @click="show = false">销毁组件</button>
  </div>
</template>

<script>
import LifeCycle from './components/LifeCycle.vue'
export default {
  data() {
    return {
      show: true
    }
  },
  components: {
    LifeCycle,
  }
}
</script>

<style></style>

 LifeCycle.vue

<template>
  <div>
      <p>学习生命周期 - 看控制台打印</p>
      <p id="myP">{{ msg }}</p>
      <ul id="myUL">
          <li v-for="(val, index) in arr" :key="index">
              {{ val }}
          </li>
      </ul>
      <button @click="arr.push(1000)">点击末尾加值</button>
  </div>
</template>

<script>
export default {
    data(){
        return {
            msg: "hello, Vue",
            arr: [5, 8, 2, 1],
            timer: null // 保存计时器
        }
    },
    // 一. 初始化
    // new Vue()以后, vue内部给实例对象添加了一些属性和方法, data和methods初始化"之前"
    beforeCreate(){
        console.log("beforeCreate -- 执行");
        console.log(this.msg); // undefined
    },
    // data和methods初始化以后
    // 场景: 网络请求, 注册全局事件
    created(){
        console.log("created -- 执行");
        console.log(this.msg); // hello, Vue

        this.timer = setInterval(() => {
            console.log("哈哈哈")
        },1000)
        
    },

    // 二.挂载
    // 真实DOM挂载之前
    // 场景:预处理data,不会触发updated钩子函数
    beforeMount(){
        console.log("beforeMount -- 执行");
        console.log(document.getElementById("myP")) //null
    },
    // 真实挂载之后
    // 场景:挂载后真实的DOM
    mounted(){
        console.log("mounted --执行")
        console.log(document.getElementById("myP")) //标签p里面的内容
    },


    // 三.更新
    // 前提:data数据改变才执行
    // 更新之前
    beforeUpdate(){
        console.log("beforeUpdate -- 执行")
        console.log(document.querySelectorAll("#myUL>li")[4]);
    },

    // 更新之后
    // 获取更新后的真实DOM
    updated(){
        console.log("updated --- 执行")
        console.log(document.querySelectorAll("#myUL>li")[4])
    },

    // 四.销毁
    // 前提:v-if = 'false' 销毁Vue实例
    // 场景:移除全局事件,移除当前组件,计时器,定时器,eventsBus移除事件$off方法
    // 移除当前组件的占用的全局变量资源,移除掉可以减轻资源
    beforeDestroy(){
        console.log('beforeDestroy --- 执行')
        clearInterval(this.timer)
    },
    destroyed(){
        console.log('destoryed --- 执行')
    }

}
</script>

<style>

运行此项目 

一般在beforeDestroy/destroyed里做什么?

手动消除计时器/定时器/全局事件

axios 使用

1.axios使用

目标:axios 是一个专门用于发送ajax请求的库

官网: http://www.axios-js.com/

特点

  • 支持客户端发送Ajax请求
  • 支持服务端Node.js发送请求
  • 支持Promise相关用法
  • 支持请求和响应的拦截器功能
  • 自动转换JSON数据

axios 底层还是原生js实现, 内部通过Promise封装的

什么是ajax? 一种前端异步请求后端的技术

ajax原理? 浏览器window接口的XMLHttpRequest

axios是什么?基于原生ajax+Promise技术封装通用于前后端的请求库

2.axios使用_获取数据  

目标:获取所有图书信息

  • 功能: 点击调用后台接口, 拿到所有数据 – 打印到控制台
  • 接口: 参考预习资料.md – 接口文档
  • 引入: 下载axios, 引入后才能使用

首先在终端里面下载axios

App.vue

<template>
  <div>
    <h1>1. 生命周期</h1>
    <LifeCycle v-if="show"></LifeCycle>
     <button @click="show = false">销毁组件</button>

     <hr>
    <h1>2.axios的使用</h1>
    <UseAxios></UseAxios>
  </div>
  
</template>

<script>
import LifeCycle from './components/LifeCycle.vue'
import UseAxios from './components/UseAxios.vue';
export default {
  data() {
    return {
      show: true
    }
  },
  components: {
    LifeCycle,
    UseAxios
  }
}
</script>

<style></style>

components/UseAxios.vue  

<template>
    <div>
        <p>1. 获取所有图书信息</p>
        <button @click="getAllFn">点击-查看控制台</button>
    </div>
</template>

<script>
// 目标1: 获取所有图书信息
// 1. 下载axios
// 2. 引入axios
// 3. 发起axios请求
import axios from "axios";
export default {
    methods: {
        getAllFn() {
            axios({
                url: "http://123.57.109.30:3006/api/getbooks",
                method: "GET", // 默认就是GET方式请求, 可以省略不写
            }).then((res) => {
                console.log(res);
            });
            // axios()-原地得到Promise对象
        },
    }
};
</script>

axios如何发起一次get请求? 在method选项配置为true / 也可以默认不写

axios函数调用原地结果是什么? 是一个Promise对象

如何拿到Promise里ajax的成功或失败的结果?then() / catch()

3.axios使用_传参  

目标:查询图书信息

  • 功能: 点击调用后台接口, 查询用户想要的书籍信息 – 打印到控制台
  • 接口: 参考预习资料.md – 接口文档

components/UseAxios.vue  

<template>
    <div>
        <p>1. 获取所有图书信息</p>
        <button @click="getAllFn">点击-查看控制台</button>

        <p>2. 查询某本书籍信息</p>
        <input type="text" placeholder="请输入要查询 的书名" v-model="bName" />
        <button @click="findFn">查询</button>
    </div>
</template>

<script>
// 目标1: 获取所有图书信息
// 1. 下载axios
// 2. 引入axios
// 3. 发起axios请求
import axios from "axios";
export default {
    data(){
        return{
            bName:""
        };
    },
    methods: {
        getAllFn() {
            axios({
                url: "http://123.57.109.30:3006/api/getbooks",
                method: "GET", // 默认就是GET方式请求, 可以省略不写
            }).then((res) => {
                console.log(res);
            });
            // axios()-原地得到Promise对象
        },
        findFn() {
            axios({
                url: "/api/getbooks",
                method: "GET",
                params: { // 都会axios最终拼接到url?后面
                    bookname: this.bName
                }
            }).then(res => {
                console.log(res);
            })
        }
    }
};
</script>

ajax如何给后台传参?

在url?拼接 – 查询字符串

在url路径上 – 需要后端特殊处理

在请求体 / 请求头 传参给后台

axios哪个配置项会把参数自动写到url?后面params

4.axios使用-发布书籍  

目标:新增图书信息

  • 功能: 点击新增按钮, 把用户输入的书籍信息, 传递给后台 – 把结果打印在控制台
  • 接口: 参考预习资料.md – 接口文档

<template>
    <div>
        <p>1. 获取所有图书信息</p>
        <button @click="getAllFn">点击-查看控制台</button>
        <p>2. 查询某本书籍信息</p>
        <input type="text" placeholder="请输入要查询 的书名" v-model="bName" />
        <button @click="findFn">查询</button>
        <p>3. 新增图书信息</p>
        <div>
            <input type="text" placeholder="书名" v-model="bookObj.bookname">
        </div>
        <div>
            <input type="text" placeholder="作者" v-model="bookObj.author">
        </div>
        <div>
            <input type="text" placeholder="出版社" v-model="bookObj.publisher">
        </div>
        <button @click="sendFn">发布</button>
    </div>
</template>

<script>
// 目标1: 获取所有图书信息
// 1. 下载axios
// 2. 引入axios
// 3. 发起axios请求
import axios from "axios";
// 4. 全局配置
export default {
    data() {
        return {
            bName: "",
            bookObj: { // 参数名提前和后台的参数名对上-发送请求就不用再次对接了
                bookname: "",
                author: "",
                publisher: ""
            }
        };
    },
    methods: {
        getAllFn() {
            axios({
                url: "http://123.57.109.30:3006/api/getbooks",
                method: "GET", // 默认就是GET方式请求, 可以省略不写
            }).then((res) => {
                console.log(res);
            });
            // axios()-原地得到Promise对象
        },
        findFn() {
            axios({
                url: "http://123.57.109.30:3006/api/getbooks",
                method: "GET",
                params: { // 都会axios最终拼接到url?后面
                    bookname: this.bName
                }
            }).then(res => {
                console.log(res);
            })
        },
        sendFn() {
            axios({
                url: "http://123.57.109.30:3006/api/addbook",
                method: "POST",
                data: {
                    appkey: "7250d3eb-18e1-41bc-8bb2-11483665535a",
                    ...this.bookObj
                    //等同于下面
                    //    bookname: this.bookObj.bookname,
                    //    author: this.bookObj.author,
                    //    publisher: this.bookObj.publisher
                }
            })
        }
    },
};
</script>

<style></style>

post请求方式, 一般在哪里传递数据给后台? 请求体中

axios哪个选项, 可以把参数自动装入到请求体中? data选项

axios默认发给后台请求体数据格式是?json字符串格式

5.axios全局配置  

目标:配置基础地址, 统一管理

  • 可以在官网看到axios的很多默认配置
  • 修改请求url / 以后的请求都不用带前缀基地址了 – 运行时, axios的baseURL会自动拼在前

components/UseAxios.vue

<template>
    <div>
        <p>1. 获取所有图书信息</p>
        <button @click="getAllFn">点击-查看控制台</button>
        <p>2. 查询某本书籍信息</p>
        <input type="text" placeholder="请输入要查询 的书名" v-model="bName" />
        <button @click="findFn">查询</button>
        <p>3. 新增图书信息</p>
        <div>
            <input type="text" placeholder="书名" v-model="bookObj.bookname">
        </div>
        <div>
            <input type="text" placeholder="作者" v-model="bookObj.author">
        </div>
        <div>
            <input type="text" placeholder="出版社" v-model="bookObj.publisher">
        </div>
        <button @click="sendFn">发布</button>
    </div>
</template>

<script>
// 目标1: 获取所有图书信息
// 1. 下载axios
// 2. 引入axios
// 3. 发起axios请求
import axios from "axios";
// 4. 全局配置
axios.defaults.baseURL = "http://123.57.109.30:3006"
export default {
    data() {
        return {
            bName: "",
            bookObj: { // 参数名提前和后台的参数名对上-发送请求就不用再次对接了
                bookname: "",
                author: "",
                publisher: ""
            }
        };
    },
    methods: {
        getAllFn() {
            axios({
                url: "/api/getbooks",
                method: "GET", // 默认就是GET方式请求, 可以省略不写
            }).then((res) => {
                console.log(res);
            });
            // axios()-原地得到Promise对象
        },
        findFn() {
            axios({
                url: "/api/getbooks",
                method: "GET",
                params: { // 都会axios最终拼接到url?后面
                    bookname: this.bName
                }
            }).then(res => {
                console.log(res);
            })
        },
        sendFn() {
            axios({
                url: "/api/addbook",
                method: "POST",
                data: {
                    appkey: "7250d3eb-18e1-41bc-8bb2-11483665535a",
                    ...this.bookObj
                    //等同于下面
                    //    bookname: this.bookObj.bookname,
                    //    author: this.bookObj.author,
                    //    publisher: this.bookObj.publisher
                }
            })
        }
    },
};
</script>

<style></style>

想学习axios更多的知识应该去哪里? 官网多阅读, 多看多总结, 任何库和插件都是

axios如何配置基地址? axios.defaults.baseURL

 $refs 和 $nextTick 使用

1.获取DOM

目标:通过id或ref属性获取原生DOM

在mounted生命周期 – 2种方式获取原生DOM标签

  • 目标标签 – 添加id / ref
  • 恰当时机, 通过id / 通过ref属性 获取目标标签

App.vue

<template>
  <div>
    <h1>1. 生命周期</h1>
    <LifeCycle v-if="show"></LifeCycle>
     <button @click="show = false">销毁组件</button>

     <!-- <hr>
    <h1>2.axios的使用</h1>
    <UseAxios></UseAxios> -->

    <hr>
    <h1>3.$refs的使用</h1>
    <MoreRef></MoreRef>
  </div>
  
</template>

<script>
import LifeCycle from './components/LifeCycle.vue';
// import UseAxios from './components/UseAxios.vue';
import MoreRef from './components/MoreRef.vue';
export default {
  data() {
    return {
      show: true
    }
  },
  components: {
    LifeCycle,
    // UseAxios,
    MoreRef
  }
}
</script>

<style></style>

 components/MoreRef.vue

<template>
    <div>
        <p>1.获取原生DOM元素</p>
        <h1 id="h" ref="myH">我是一个孤独可怜又能吃的h1</h1>
    </div>
</template>

<script>
    export default {
        mounted(){
            console.log(document.getElementById("h"))  //h1
            console.log(this.$refs.myH)  //h1
        }
    }
</script>

<style>

</style>

运行此项目 

2.获取组件对象

目标:通过ref属性获取组件对象

  • 1.创建Demo组件, 写一个方法
  • 2. App.vue使用Demo组件, 给ref属性-名字随意
  • 3. 恰当时机, 通过ref属性 获取组件对象, 可调用组件对象里方法等

App.vue

<template>
  <div>
    <h1>1. 生命周期</h1>
    <LifeCycle v-if="show"></LifeCycle>
     <button @click="show = false">销毁组件</button>

     <!-- <hr>
    <h1>2.axios的使用</h1>
    <UseAxios></UseAxios> -->

    <hr>
    <h1>3.$refs的使用</h1>
    <MoreRef></MoreRef>
  </div>
  
</template>

<script>
import LifeCycle from './components/LifeCycle.vue';
// import UseAxios from './components/UseAxios.vue';
import MoreRef from './components/MoreRef.vue';
export default {
  data() {
    return {
      show: true
    }
  },
  components: {
    LifeCycle,
    // UseAxios,
    MoreRef
  }
}
</script>

<style></style>

MoreRef.vue 

<template>
    <div>
        <p>1. 获取原生DOM元素</p>
        <h1 id="h" ref="myH">我是一个孤独可怜又能吃的h1</h1>
        <p>2. 获取组件对象 - 可调用组件内一切</p>
        <DemoRef ref="de"></DemoRef>
        <!-- <p>3. vue更新DOM是异步的</p>
        <p ref="myP">{{ count }}</p>
        <button @click="btn">点击count+1, 马上提取p标签内容</button> -->
    </div>
</template>

<script>
// 目标: 获取组件对象
// 1. 创建组件/引入组件/注册组件/使用组件
// 2. 组件起别名ref
// 3. 恰当时机, 获取组件对象
import DemoRef from './Child/DemoRef.vue';
export default {
    mounted() {
        console.log(document.getElementById("h")); // h1
        console.log(this.$refs.myH); // h1

        let demoObj = this.$refs.de;
        demoObj.fn()
    },
    components: {
        DemoRef
    },
    // data() {
    //     return {
    //         count: 0
    //     }
    // }
}
</script>

<style></style>

components/Child/DemoRef.vue

<template>
    <div>
        <p>我是Demo组件</p>
    </div>
</template>

<script>
    export default {
        data(){
            return {
                
            }
        },
        methods: {
            fn(){
                console.log("demo组件内的方法被调用了")
            }
        }
    }
</script>

<style>

</style>

运行此代码 

 

如何获取组件对象呢? 目标组件添加ref属性 this.$refs.名字 获取组件对象

拿到组件对象能做什么? 调用组件里的属性/方法

3.Vue-异步更新DOM  

目标:点击改data, 获取原生DOM内容

1. 创建标签显示数据

2. 点击+1, 马上获取原生DOM内容

原因: Vue更新DOM是异步的

 MoreRef.vue

<template>
    <div>
        <p>1. 获取原生DOM元素</p>
        <h1 id="h" ref="myH">我是一个孤独可怜又能吃的h1</h1>
        <p>2. 获取组件对象 - 可调用组件内一切</p>
        <DemoRef ref="de"></DemoRef>
        <p>3. vue更新DOM是异步的</p>
        <p ref="myP">{{ count }}</p>
        <button @click="btn">点击count+1, 马上提取p标签内容</button>
    </div>
</template>

<script>
// 目标: 获取组件对象
// 1. 创建组件/引入组件/注册组件/使用组件
// 2. 组件起别名ref
// 3. 恰当时机, 获取组件对象
import DemoRef from './Child/DemoRef.vue';
export default {
    mounted() {
        console.log(document.getElementById("h")); // h1
        console.log(this.$refs.myH); // h1

        let demoObj = this.$refs.de;
        demoObj.fn()
    },
    components: {
        DemoRef
    },
    data() {
        return {
            count: 0
        }
    },
    methods:{
        btn(){
            this.count++;//vue监测数据更新,开启一个Dom更新队列(异步任务)
            // console.log(this.$refs.myP.innerHTML);  //0
        }
    }
}
</script>

<style></style>

4.$nextTick使用

目标:等DOM更新后, 触发此方法里函数体执行

语法: this.$nextTick(函数体)

 MoreRef.vue

<template>
    <div>
        <p>1. 获取原生DOM元素</p>
        <h1 id="h" ref="myH">我是一个孤独可怜又能吃的h1</h1>
        <p>2. 获取组件对象 - 可调用组件内一切</p>
        <DemoRef ref="de"></DemoRef>
        <p>3. vue更新DOM是异步的</p>
        <p ref="myP">{{ count }}</p>
        <button @click="btn">点击count+1, 马上提取p标签内容</button>
    </div>
</template>

<script>
// 目标: 获取组件对象
// 1. 创建组件/引入组件/注册组件/使用组件
// 2. 组件起别名ref
// 3. 恰当时机, 获取组件对象
import DemoRef from './Child/DemoRef.vue';
export default {
    mounted() {
        console.log(document.getElementById("h")); // h1
        console.log(this.$refs.myH); // h1

        let demoObj = this.$refs.de;
        demoObj.fn()
    },
    components: {
        DemoRef
    },
    data() {
        return {
            count: 0
        }
    },
    methods:{
        btn(){
            this.count++;//vue监测数据更新,开启一个Dom更新队列(异步任务)
            // console.log(this.$refs.myP.innerHTML);  //0

            // 原因:vue更新DOM异步
            // 解决:this.$nextTick()
            // 过程:DOM更新完全会挨个触发$nextTick里面的函数体
            this.$nextTick(() => {
                console.log(this.$refs.myP.innerHTML); // 1
            })
        }
    }
}
</script>

<style></style>

 

data改变更新DOM是同步还是异步的? 异步

我们可以在哪里访问到更新后的DOM呢?

this.$nextTick里的函数体 updated生命周期钩子函数 

5.例子-输入框聚焦  

目标:点击按钮自身隐藏, 出现输入框并马上处于激活状态

注意: 一定要用v-if来写 (保证DOM异步更新前获取不到输入框, 体现$nextTick价值)

优化: $nextTick()返回Promise 配合await使用

 App.vue

<template>
  <div>
    <!-- <h1>1. 生命周期</h1>
    <LifeCycle v-if="show"></LifeCycle>
     <button @click="show = false">销毁组件</button> -->

     <!-- <hr>
    <h1>2.axios的使用</h1>
    <UseAxios></UseAxios> -->

    <!-- <hr>
    <h1>3.$refs的使用</h1>
    <MoreRef></MoreRef> -->

    <hr>
    <h1>4.$nextTick的使用场景</h1>
    <NextTick></NextTick>
  </div>
  
</template>

<script>
// import LifeCycle from './components/LifeCycle.vue';
// import UseAxios from './components/UseAxios.vue';
// import MoreRef from './components/MoreRef.vue';
import NextTick from './components/NextTick.vue';
export default {
  data() {
    return {
      show: true
    }
  },
  components: {
    // LifeCycle,
    // UseAxios,
    // MoreRef,
    NextTick
  }
}
</script>

<style></style>

 NextTick.vue

<template>
    <div>
        <input ref="myInp" type="text" placeholder="这是一个输入框" v-if="isShow">
        <button v-else @click="btn">点击我进行搜索</button>
    </div>
</template>

<script>
// 目标: 点按钮(消失) - 输入框出现并聚焦
// 1. 获取到输入框
// 2. 输入框调用事件方法focus()达到聚焦行为
export default {
    data() {
        return {
            isShow: false
        }
    },
    methods: {
        async btn() {
            this.isShow = true;
            // this.$refs.myInp.focus()
            // 原因: data变化更新DOM是异步的
            // 输入框还没有挂载到真实DOM上
            // 解决:
            // this.$nextTick(() => {
            //     this.$refs.myInp.focus()
            // })
            // 扩展: await取代回调函数
            // $nextTick()原地返回Promise对象
            await this.$nextTick()
            this.$refs.myInp.focus()
        }
    }
}
</script>

<style></style>

 

$nextTick函数原地返回什么? Promise对象

如何在JS中主动触发标签的事件呢? 获取到DOM对象, 调用事件方法

6.组件name属性使用

目标:组件name可用作注册组件名字

1. 组件定义name属性和值

2. 注册组件可用上面name的值  

App.vue

<template>
  <div>
    <!-- <h1>1. 生命周期</h1>
    <LifeCycle v-if="show"></LifeCycle>
     <button @click="show = false">销毁组件</button> -->

     <!-- <hr>
    <h1>2.axios的使用</h1>
    <UseAxios></UseAxios> -->

    <!-- <hr>
    <h1>3.$refs的使用</h1>
    <MoreRef></MoreRef> -->

    <hr>
    <h1>4.$nextTick的使用场景</h1>
    <NextTick></NextTick>

      <hr>
      <h1>5. 组件对象里name属性</h1>
      <ComNameHaHa></ComNameHaHa>
  </div>
  
</template>

<script>
// import LifeCycle from './components/LifeCycle.vue';
// import UseAxios from './components/UseAxios.vue';
// import MoreRef from './components/MoreRef.vue';
import NextTick from './components/NextTick.vue';
import ComTick from './components/ComTick.vue'
export default {
  data() {
    return {
      show: true
    }
  },
  components: {
    // LifeCycle,
    // UseAxios,
    // MoreRef,
    NextTick,
    [ComTick.name]: ComTick // 对象里的key是变量的话[]属性名表达式
    // "ComNameHaHa": Com
  }
}
</script>

<style></style>

components/ComTick.vue 

<template>
    <div>
        <p>我是一个Com组件</p>
    </div>
</template>

<script>
export default {
    name: "ComNameHaHa" // 注册时可以定义自己的名字
}
</script>

<style></style>

组件使用分为几步? 创建组件 / 引入组件 / 注册组件 / 使用组件

注册组件名还可以用什么? 用组件对象的name属性的值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/606357.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数字IC乘法器结构

目录 一、原理分析二、Xinlinx中的乘法器结构1.直接相乘2.移位相加乘法器3.加法树加法器 在数字IC中乘法器的结构是什么样的呢&#xff1f;接下来我们以两个4bit数的乘法进行举例&#xff0c;假定有两个4bit数据&#xff0c;分别为X(X3&#xff0c;X2&#xff0c;X1&#xff0c…

Ti雷达常用工具

Ti雷达常用工具 名称网站功能雷达开箱界面mmWave Demo Visualizer (ti.com)显示距离谱、RD谱图雷达参数估计mmWaveSensingEstimator根据性能设计估计参数雷达项目资料Embedded Software (ti.com)Ti雷达示例及说明书官方论坛Sensors forum - Sensors - TI E2E support forumsTi…

【复试分数线】四电四邮历年分数线汇总(第一弹)

24年考研国家线预计3月中旬公布&#xff0c;接下来各大院校就会公布自己的复试分数线。这次会为大家整理四电四邮的整理了近三年各院校的复试分数线作为参考&#xff0c;大家可以参考&#xff01; 大多数院校采取的是1.2:1差额的形式复试。举个例子&#xff0c;比如学校今年拟…

人工智能|推荐系统——工业界的推荐系统之涨指标

一、推荐系统的评价指标 涨指标的方法有哪些? 二、涨指标的方法:召回 2.1 改进双塔模型 2.2 Item-to-Item (I2I) 2.3 类似I2I 的模型

三.搜索与图论(未完结)

DFS(深搜) 之前写过三篇关于dfs的 练习总结: 基础算法--递归搜索DFS练习总结(上)-CSDN博客 基础算法--递归搜索DFS练习总结(中)-CSDN博客 基础算法--递归搜索DFS练习总结(下)-CSDN博客 以下题目均为 补充练习: P1460 [USACO2.1] 健康的荷斯坦奶牛 Healthy Holsteins …

使用Python将数据表中的浮点数据转换为整数:详细教程与案例分析

目录 一、引言 二、环境准备 三、读取数据表 四、浮点数据转换为整数 五、写入数据表 六、案例分析 步骤一&#xff1a;读取数据表 步骤二&#xff1a;浮点数据转换为整数 步骤三&#xff1a;写入新的数据表 七、注意事项 八、总结 在数据处理和分析的过程中&#x…

58. 【Android教程】音频录制:MediaRecord

在第 57 节我们使用 MediaPlayer 实现了一个 mp3 播放器&#xff0c;除了播放 Android 还提供了 MediaRecorder 用于录音。Android 设备基本都会有一个麦克风&#xff0c;通过 MediaRecorder 可以打开麦克风进行语音采集&#xff0c;这一节我们就来学习如何在 Android 系统上实…

将ESP工作为AP路由模式并当成服务器

将ESP8266模块通过usb转串口接入电脑 ATCWMODE3 //1.配置成双模ATCIPMUX1 //2.使能多链接ATCIPSERVER1 //3.建立TCPServerATCIPSEND0,4 //4.发送4个字节在链接0通道上 >ATCIPCLOSE0 //5.断开连接通过wifi找到安信可的wifi信号并连接 连接后查看自己的ip地址变为192.168.4.…

太牛逼了,用ComfyUI中一键完成电商模特换装换背景!商业级教程附上!

&#x1f310; 大背景&#xff1a;电商时代的画卷正在翻页 在全球电子商务风起云涌的今天&#xff0c;市场竞争愈发激烈。商家们始终在寻求提高效率、减少成本和增强用户体验的新方法。然而&#xff0c;一个关键问题一直困扰着电商行业——**如何高效且经济地展示商品&#xff…

python如何整体缩进

python自带编辑器的缩进和取消缩进快捷键&#xff1a; 整体缩进 Ctrl【 整体取消缩进 Ctrl】 pycharm编辑器的缩进和取消缩进快捷键&#xff1a; 整体缩进&#xff1a; tab 整体取消缩进&#xff1a; tabshift

ADOP带你了解:温度如何影响您的室外以太网电缆?

温度&#xff1a;室外以太网电缆的隐形敌人 在构建和维护室外以太网网络时&#xff0c;我们通常会考虑到许多物理因素&#xff0c;如电缆的长度、宽带容量和连接质量。然而&#xff0c;有一个不那么显眼但同样重要的因素常常被忽视&#xff0c;那就是温度。温度的波动不仅影响…

力扣-21. 合并两个有序链表-js实现

/*** Definition for singly-linked list.* function ListNode(val, next) {* this.val (valundefined ? 0 : val)* this.next (nextundefined ? null : next)* }*/ /*** param {ListNode} list1* param {ListNode} list2* return {ListNode}*/ const mergeTwoList…

数据库索引回表困难?揭秘PolarDB存储引擎优化技术

引言 数据库系统为了高效地存储、检索和维护数据&#xff0c;采用了多种不同的数据组织结构。不同的组织结构有其特定的用途和优化点&#xff0c;比如提高查询速度、优化写入性能、减少存储空间等。常见的数据库记录组织结构有&#xff1a; B-Tree B-Tree是一种平衡的多路搜索…

【MySQL 数据宝典】【索引原理】- 007 索引优化示例

一、单表优化 1.1 数据准备 下面是一张用户通讯表的表结构信息,这张表来源于真实企业的实际项目中,有接近500万条数据. CREATE TABLE user_contacts (id INT(11) NOT NULL AUTO_INCREMENT,user_id INT(11) DEFAULT NULL COMMENT 用户标识,mobile VARCHAR(50) DEFAULT NULL C…

QT-小项目:连接MY SQL数据库实现登录(下一章实现登录注册账号和忘记密码功能)

一、环境准备 1、下载MYSQL 64位&#xff0c;安装完成&#xff0c;制作简易数据库教程如下&#xff1a; MY SQL安装 2、QT 编译器使用 二、实现工程目录&#xff08;基于上一章基础上&#xff09; 三、源程序增加内容如下&#xff1a; login.cpp 增加头文件&#xff1a; #in…

python代码自动生成器原理 python 生成器原理

python生成器原理剖析 函数的调用满足“后进先出”的原则&#xff0c;也就是说&#xff0c;最后被调用的函数应该第一个返回&#xff0c;函数的递归调用就是一个经典的例子。显然&#xff0c;内存中以“后进先出”"方式处理数据的栈段是最适合用于实现函数调用的载体&…

架空光缆用什么型号

架空光缆是什么意思 , 架空光缆用什么型号的 GYTC8A , 架空光缆型号是啥 8字形光缆 产品描述 Description GYTC8A光缆的结构是将250m光纤套入高模量材料制成的松套管中&#xff0c;松套管内填充防水化合物。缆芯的中心是一根金属加强芯&#xff0c;松套管(和填充绳 )围绕中心…

Davinci工程WrapNv模块讲解

配置讲解 WrapNv模块里面有两个东西&#xff0c;WrapNvGeneral和WrapNvMemoryLayout。 WrapNvGeneral里面配置的就是这个E方的基地址 WrapNvMemoryLayout里面就是分几个块来存储&#xff0c;每个块有自己的数据。 再里面一层&#xff0c;有各自的长度和默认值。我们可以在后面…

常见C语言基础说明二:位运算问题

一. 简介 前面一篇文章学习了 常见的 C语言基础题&#xff0c;文章如下&#xff1a; 常见C语言基础题说明一-CSDN博客 本文继续上一篇C语言基础题的学习。 二. C语言中 -> 位运算问题 1. 数据在计算机中的存储方式 当前的计算机系统使用的基本上是二进制系统&#…

Linux环境Redis部署

Redis部署 Redis是一个高性能的开源键值存储系统&#xff0c;它主要基于内存操作&#xff0c;但也支持数据的持久化。与其他数据库相比&#xff0c;Redis的主要优势在于它的高性能、丰富的数据结构和原生的持久化能力。Redis不仅提供了类似的功能&#xff0c;还增加了持久化和…