Vue2基础

news/2024/10/11 2:31:40

【一】初识Vue

【1】什么是Vue

Vue 是一套用于构建用户界面的渐(逐渐)进(递进)式 JavaScript 框架Vue 可以自底向上逐层应用,由国人尤雨溪开发采用组件化模式,提高代码的复用率、让代码更好维护声明式编码方式,让编码人员无需直接操作 DOM,提高开发效率使用虚拟DOM + 优秀的 Diff 算法,尽量复用 DOM 节点Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:

【2】引入Vue

本地方式引入

<script src="../js/vue.js"></script>

网络CDN方式引入

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

【3】Vue基本结构

在初学阶段,Vue 的结构由 容器 + 对象 两大部分构成

<body>
<div id="app">{{name}}{{age}}
</div>
</body>
<script>var vm = new Vue({el: '#app', // 这是Vue对象所绑定的容器对象,一般使用css选择器绑定data: {     // data用于存储数据name: 'green',age: 18}})
</script>

【二】基础知识

【1】模板语法

插值语法

<body>
<div id="app">{{name}}<br>{{age}}<br>{{hobby}}|{{hobby[0]}} // 数组只能用中括号取值<br>{{obj}}|{{obj.name}}|{{obj["name"]}} // 对象可以用中括号或者点属性取值<br>{{link}}
</div><script>var vm = new Vue({el: '#app',data: {name: 'green',age: 18,hobby: ['洗衣服', '做饭', '打游戏'],obj: {name: "hqq", age: 22, hobby: ['抽烟', '喝酒', '洗脚']},link: '<a href="https://meizi5.com">点击看美女</a>'}})
</script>
</body>

指令语法

<div id="root"><!-- v-bind 可以简写为 : --><a v-bind:href="url">点我去百度 - 完整写法</a><a :href="url">点我去百度 - 简略写法</a>
</div><script>new Vue({el: '#root',data: {url: 'https://www.baidu.com'}})
</script>

总结

​ 插值语法

​ 功能:用于解析标签体中的内容

​ 写法:{{xxxx}},其中 xxxx 是 js 表达式,且可以直接读取到 data 中的所有属性

​ 指令语法

​ 功能:用于解析标签(包括:标签属性,标签体内容,绑定事件)

【2】数据绑定

单向绑定:str变---》input框变,input框变---》str不变

单向绑定:str变---》input框变,input框变---》str也变

<div id="app">
单向绑定 <input type="text" :value="str">
双向绑定 <input type="text" v-model:value="str">
</div><script>let vm = new Vue({el: '#app',data: {str: '炎帝萧炎'}})
</script>
</body>

总结

总结:单向绑定(v-bind):数据只能由 data 流向页面双向绑定(v-model)数据既能从 data 流向页面,也能从页面流向 data双向绑定一般都应用在表单类元素上(input、select...)v-model:value 可以简写为 v-model,因为 v-model 默认绑定的就是 value 属性

【3】事件指令

es6的对象写法

// es6 的对象写法
var hobby=['抽烟','烫头']
var obj={  'name':'hqq',age:19,  // 键值可以不带引号 hobby, // 可以直接省略键名,在有定义的情况下showName() {console.log(this.name)// 函数可以省略:function}
}

函数传参数问题

<body>
<div id="app"><button v-on:click="showFunc1">不传参数,函数有参数(会自动把当前事件传入)</button><button v-on:click="showFunc2(name)">传参数,函数有参数(正常输出)</button><button v-on:click="showFunc3($event)">传参数,函数有参数,把事件对象传入(正常输出)</button><button v-on:click="showFunc4()">传参数,函数有多个参数,少传参数(少传就输出传入的,多传就不关多出来的)</button>
</div>
</body>
<script>let vm = new Vue({el: '#app',data: {name: 'green'},methods: {showFunc1(event) {console.log(event)},showFunc2(param) {console.log(param)},showFunc3(event) {console.log(event)},showFunc4(a,b,c) {console.log(a,b,c)}}})
</script>

【4】属性指令

1. 标签上有属性 如:
img的src属性,a标签的href属性2. 属性指令的作用就是使用变量动态的设置属性的值3. 使用方法v-bind:属性名='变量'简写:属性名='变量'

动态切换美女图片案例

<body>
<div id="app"><button @click="handleClick">点击切换自动切换美女</button><img :src="src" alt="">
</div><script>let vm = new Vue({el: '#app',data: {list: ['/img/1.jpg', '/img/2.jpg', '/img/3.jpg'],src: '',index: 0,flag: false,t: null},methods: {handleChange() {console.log(this.index)this.src = this.list[this.index]this.index += 1if (this.index === 3) {this.index = 0}},handleClick() {if (this.flag === false) {this.t = setInterval(this.handleChange, 1000)this.flag = true} else {clearInterval(this.t)this.flag = false}}}})
</script>
</body>

补充:js中的计时器

js 定时器有以下两个方法:setInterval() :按照指定的周期(以毫秒计)来调用函数或计算表达式。方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。
setTimeout() :在指定的毫秒数后调用函数或计算表达式。语法
setInterval(code,millisec,lang)
code 必需。要调用的函数或要执行的代码串。
millisec  	必须。周期性执行或调用 code 之间的时间间隔,以毫秒计。
lang	可选。 JScript | VBScript | JavaScript

【5】style和class

# 1 class 可以绑定 字符串,数组,对象字符串: 'div1 div2'---》字符串替换控制样式数组:['div1','div2']--->追加数组,删除数组控制样式对象:{div1: true, div2: true, div3: true, div4: false}--》通过true和false控制样式# 2 style 可以绑定 字符串,数组,对象字符串'background-color: green;height: 300px;width: 300px'---》字符串替换控制样式数组:[{'background-color': 'green'}, {height: '300px'}, {width: '300px'}]--->追加数组,删除数组控制样式对象:{backgroundColor: 'green', height: '330px', width: '300px'} --》通过根据key修改value控制样式# 3 坑:以后如果改了对象,或数组,发现页面没有变化,实际上值被真正的改了Vue.set(this.style_list,3,{'margin':'auto'})

【6】条件渲染

v-if v-else-if v-else

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="./vue/vue.js"></script><style></style>
</head>
<body>
<div id="app"><h1>条件判断</h1><h2>分数是:{{score}}</h2><h3 v-if="score>=90&&score<=100">优秀</h3><h3 v-else-if="score>=80&&score<90">良好</h3><h3 v-else-if="score>=60&&score<80">及格</h3><h3 v-else>不及格</h3></div>
</body>
<script>var vm = new Vue({el: '#app',data: {score: 99}})</script>
</html>

【7】列表渲染

通过使用v-for循环显示多条数据

购物车案例

<body>
<div class="container text-center" id="app"><div class="row"><div class="col-6 offset-3"><h1 class="text-center">购物车</h1><button class="btn btn-success" @click="showGood">加载购物车</button><div v-if="!good_list">空空如也</div><table class="table table-info"><thead><tr><th scope="col">商品ID</th><th scope="col">商品名称</th><th scope="col">商品数量</th><th scope="col">商品价格</th><th scope="col">商品图片</th></tr></thead><tbody><tr v-for="good in good_list"><th scope="row">{{good.id}}</th><td>{{good.name}}</td><td>{{good.number}}</td><td>{{good.price}}</td><td><img v-bind:src="good_img" alt="" v-bind:style="style_dic"></td></tr></tbody></table></div></div>
</div>
<script>let vm = new Vue({el: '#app',data: {good_list: null,good_img: null,style_dic: {}},methods: {showGood() {this.good_list = [{'id': 1, 'name': '短裙', 'number': 20, 'price': 22},{'id': 2, 'name': '黑丝', 'number': 34, 'price': 43},{'id': 3, 'name': '白丝', 'number': 55, 'price': 12},{'id': 4, 'name': '过膝袜', 'number': 19, 'price': 5},{'id': 5, 'name': '马油袜', 'number': 39, 'price': 3},]this.good_img = '/img/1.jpg'Vue.set(this.style_dic, 'width', '30px')Vue.set(this.style_dic, 'height', '30px')}}})
</script>
</body>

for循环不同数据类型

<body>
<div id="app"><h1>for循环字符串</h1><p>默认循环字符,还可以加入第二个参数,循环索引</p><p v-for="(item,index) in str">字符--->{{item}} 索引--->{{index}}</p><h1>for循环数字</h1><p>从1开始循环到最后一个数字(包括最后一个数字)也可以循环索引</p><p v-for="(item,index) in num">数字--->{{item}} 索引--->{{index}}</p><h1>循环数组</h1><p>默认循环元素,还可以加入第二个参数,循环索引</p><p v-for="(item,index) in list">元素--->{{item}} 索引--->{{index}}</p><h1>循环对象</h1><p>默认循环value值,还可以加入第二个参数,循环键值</p><p v-for="(value,key) in obj">值--->{{value}} 键--->{{key}}</p>
</div>
<script>let vm = new Vue({el: '#app',data: {list: ['张雪峰', '暴叔', '吉田'],str: 'hello word',obj: {name: 'green', age: 18},num: 10}})
</script>
</body>

标签内加入key属性

#1 以后写v-for,都要在标签上加  :key="key"  ,key必须唯一# 2 这样做可以提高虚拟dom的替换效率

【8】事件处理

# 1 input 标签的事件处理input	当输入框进行输入的时候 触发的事件change	当元素的值发生改变时 触发的事件blur	当输入框失去焦点的时候 触发的事件focus   当获得焦点的时候 触发的事件
<body>
<div id="app"><input type="text" @input="handleInput($event)" value="当输入框进行输入的时候 触发的事件"><br><input type="text" @change="handleChange" value="当元素的值发生改变时 触发的事件"><br><input type="text" @blur="handleBlur" :value="inputValue"><br><input type="text" @focus="handleFocus" :value="inputValue"><br></div>
<script>let vm = new Vue({el: '#app',data: {inputValue: ''},methods: {handleInput(event) {console.log(event.data)},handleChange() {alert('发生改变了')},handleBlur() {this.inputValue = '失去焦点了'},handleFocus(){this.inputValue = '得到焦点了'}}})
</script>
</body>

过滤小案例

<body>
<div id="app" class="container-fluid"><div class="row"><div class="col-6 offset-3"><h1 class="text-center">过滤小案例</h1><p class="text-center">搜索框</p><input type="email" class="form-control" v-model:value="kewWord" @input="handleInput"><table class="table"><tr v-for="item in list"><td class="text-center">{{item}}</td></tr></table></div></div>
</div><script>let vm = new Vue({el: '#app',data: {dataList: ['黑丝', '黑丝袜', '黑丝连体袜', '吊带', '吊带蝴蝶结', 'black', 'blac', 'bla'],kewWord: 'hahah',list: null},methods: {handleInput() {let _this = thisthis.list = this.dataList.filter(function (item) {return item.indexOf(_this.kewWord) >= 0})}}})
</script>
</body># 箭头函数优化代码写法
methods: {handleInput() {this.list = this.dataList.filter((item)=> item.indexOf(this.kewWord) >= 0)}}// 流程
核心是 要通过输入框的内容过滤数据列表
输入框的内容可以通过双向绑定得到通过filter函数过滤,它可以将数组里的一个个元素分别进行校验,如果不通过返回flase,通过返回true通过 indexOf 方法校验当前输入框的内容和数据数组里的元素是否匹配 如果匹配返回大于0的数,不匹配返回-1

补充:js中的filter函数

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。注意: filter() 不会对空数组进行检测。注意: filter() 不会改变原始数组。语法
array.filter(function(currentValue,index,arr), thisValue)currentValue 当前从array取出校验的元素
index 当前取出的元素的索引
arr 当前元素的来源

补充:es6语法箭头函数

    <!--  初始匿名函数写法-->let name = 'green'let f = function (name){return name + 'nb'}console.log(f(name))// 箭头函数写法,去掉function,在括号和大括号中间加上=>let f = (name) => {return name + 'nb'}console.log(f(name))// 当函数只需要传一个参数时,可以不用 用括号把参数括起来let f = name => {return name + 'nb'}console.log(f(name))//  当返回值只有一行代码时,可以不用写return 和 大括号let f = name => name + 'nb'console.log(f(name))为什么要写箭头函数?箭头函数是为了解决function函数的this指向问题,
箭头函数体内的this对象,就是定义该函数时所在的作用域指向的对象,而不是使用时所在的作用域指向的对象。

【9】事件修饰符

​ 在Vue中,事件修饰符处理了许多DOM事件的细节,让我们不再需要花大量的时间去处理这些烦恼的事情,而能有更多的精力专注于程序的逻辑处理。

在Vue中事件修饰符主要有:

.stop:等同于JavaScript中的event.stopPropagation(),防止事件冒泡.prevent:等同于JavaScript中的event.preventDefault(),防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播).capture:与事件冒泡的方向相反,事件捕获由外到内.self:只会触发自己范围内的事件,不包含子元素.once:只会触发一次

【10】jsfor循环的方式

普通的索引循环

<script><!--    普通的索引循环-->let arr = [18, 'green', {name: 'hqq', age: 22}]for(let i=0 ;i<arr.length;i++){console.log(arr[i])}
</script>

基于迭代的off循环

<script><!--    迭代off循环-->let arr = [18, 'green', {name: 'hqq', age: 22}]for (let item of arr) { // item就是数组里面的一个个元素console.log(item)}
</script>

基于迭代的in循环

<script><!--    迭代in循环-->let arr = [18, 'green', {name: 'hqq', age: 22}]for (let index in arr) { // index是索引console.log(arr[index])}
</script>

数组的forEach方法循环

<script><!--    数组的forEach方法循环-->let arr = [18, 'green', {name: 'hqq', age: 22}]arr.forEach((value,index,array)=>{ // 分别是元素,索引,数据源数组console.log(value,index,array)})
</script>

【11】按键修饰符

#1 按下某个键盘,触发事件,通过修饰控制只有按下某个键,才触发事件
#2 keyCode对应表--》按键修饰符https://www.cnblogs.com/841019rossi/p/16808455.html<body>
<div id="app"><button @keyup.enter="handleEnter">按回车有惊喜</button>
</div><script>let vm = new Vue({el: '#app',data:{},methods:{handleEnter(){alert('回车被按了')}}})
</script>
</body>

【12】表单控制

# 1 checkbox   v-model 绑定 -布尔 :选中没选中-数组:多选
# 2 radio:-字符串:value的值

购物车小案例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous"><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"integrity="sha384-/mhDoLbDldZc3qpsJHpLogda//BVZbgYuw6kof4u2FrCedxOtgRZDTHgHUhOCVim"crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script src="../js/vue.js"></script>
</head>
<body>
<div id="app" class="container"><div class="row"><div class="col-6 offset-3"><h1 class="text-center">图书商城</h1><p class="text-center"><button class="btn btn-success" @click.once="handleLoad">加载购物车</button></p><div class="input-group mb-3"><input type="text" class="form-control" placeholder="搜索书名"aria-label="Recipient's username" aria-describedby="button-addon2" v-model="searchText"><button class="btn btn-outline-secondary" type="button" id="button-addon2" @click="handleSearch" >搜索</button></div><table class="table table-bordered"><thead><tr><th scope="col">id</th><th scope="col">书名</th><th scope="col">作者</th><th scope="col">价格</th><th scope="col">数量</th><th scope="col"><p>全选/全不选 <input type="checkbox" v-model="checkAll" @change="handleChange"></p></th></tr></thead><tbody><tr v-for="(book,index) in showList"><th scope="row">{{index + 1}}</th><td>{{book.title}}</td><td>{{book.author}}</td><td>{{book.Price}}</td><td><button class="btn" @click="handleSub(book)">-</button>{{book.num}}<button class="btn" @click="handleAdd(book)">+</button></td><td><input type="checkbox" v-model="checkList" @change="handleSum" :value="book"></td></tr></tbody></table><p>总价格</p><input type="text" class="form-control" readonly :value="getSum"></div></div>
</div>
</body>
<script>let vm = new Vue({el: '#app',data: {bookList: [],checkList: [],checkAll: null,searchText: '',showList: []},methods: {handleLoad() {axios.get('http://127.0.0.1:8000/api/v1/book/').then((response) => {for (const responseElement of response.data.results) {responseElement.num = 0}this.bookList = response.data.results})},handleAdd(book) {book.num += 1this.handleSum()},handleSub(book) {if (!book.num) {return}book.num -= 1this.handleSum()},handleSum() {this.checkAll = (this.checkList.length === this.bookList.length)},handleChange() {if (this.checkAll) {this.checkList = this.bookList} else {this.checkList = []}},handleSearch() {this.showList = this.bookList.filter((book) => book.title.indexOf(this.searchText) >= 0)}},computed: {getSum() {let total = 0for (let book of this.checkList) {total += book.num * book.Price}return total}}})
</script>
</html>

【13】v-model进阶

v-model 之 lazy、number、trimlazy:等待input框的数据绑定失去焦点之后再变化number:数字开头,只保留数字,后面的字母不保留;字母开头,都保留trim:去除首位的空格

【14】vue与ajax

vue的数据与后端进行交互的ajax方式有:

原生js的ajax(不常用)
jquery封装的ajax(不常用)
H5自带的fetch (可能用)
vue的axios(Vue作者推荐用)

原生js的ajax

<!DOCTYPE html>
<html>
<head>   <meta charset="UTF-8">   <meta http-equiv="X-UA-Compatible" content="IE=edge">   <meta name="viewport" content="width=device-width, initial-scale=1.0">   <title>Document</title>
</head>
<body>
</body>
<script>
/* ajax */
//post数据传递,一般需要接口文档,自己用node写也是可以的
//创建ajax
var xhr = new XMLHttpRequest;
//请求地址
xhr.open('post', 'url');
//请求头
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
//因为ajax异步send还是写这里比较好
xhr.send('name=zhangsan&age=18')
xhr.onreadystatechange = function(){   if (xhr.readyState === 4){       if (xhr.status>=200 && xhr.status<300){           var res = xhr.responseText;           console.log(res);       }   }
}
</script>
</html>

jquery封装的ajax

因为jquery有比较完整的ajax封装,但它主要是操作DOM和Bom,所以一般也不怎么用,作为拓展吧

<!DOCTYPE html>
<html>
<head>   <meta charset="UTF-8">   <meta http-equiv="X-UA-Compatible" content="IE=edge">   <meta name="viewport" content="width=device-width, initial-scale=1.0">   <!-- bootcdn的镜像也可以自己下载jquery库-->   <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>   <title>Document</title>
</head>
<body>
</body>
<script>
/* jquery */$.ajax({    method:'post',    url:'url',
//     // dataType:"",    data:{        name:'zhangsan',        age:18   },    success:res=>{        console.log(res);    },
//     // error:err=>{//     // }})
</script>
</html>

H5自带的fetch

H5自带的fetch封装的ajax也是比较好的,现在市面上还有些公司在用

<!DOCTYPE html>
<html>
<head>   <meta charset="UTF-8">   <meta http-equiv="X-UA-Compatible" content="IE=edge">   <meta name="viewport" content="width=device-width, initial-scale=1.0">   <title>Document</title>
</head>
<body>
</body>
<script>
/* fetch */
//get,返回值是对象所以需要调用then()方法,调用出来fetch('url?name=zhangsan&age=18').then(res=>res.text()).then(res=>{     console.log(res);})
//post,body里还是不能用对象fetch('url',{   method:'post',    body:'name=zhangsan&age=14',    headers: {        "content-type": 'application/x-www-form-urlencoded'    }    //转json数据格式}).then(res=>res.json()).then(res=>{     console.log(res);})
</script>
</html>

axios库

主要使用的数据请求方式,因为作者推荐,作者都推荐了嘛,最后还得是看公司,没要求最好还是axios

使用需要下载axios插件,使用方法详见官网:axios官网

<!DOCTYPE html>
<html>
<head>   <meta charset="UTF-8">   <meta http-equiv="X-UA-Compatible" content="IE=edge">   <meta name="viewport" content="width=device-width, initial-scale=1.0">   <title>Document</title>
</head>
<body>
</body>
<script src="./node_modules/axios/dist/axios.js"></script>
<script>
/* axios */
//设置全局令牌,发送请求就不用特地带令牌了
axios.defaults.headers['authorization'] = 'token'
//get,可以设置全局地址提高代码复用率,减少自己写代码,就不用每个都写这么长的地址,嘿嘿
axios.defaults.baseURL='url'
axios.get('third', {   params: {       name: 'lisi',       age: 20   }
}).then(res => {   console.log(res.data);
})
//post
axios.post('/fourth', 'name=a&age=12').then(res => {   console.log(res);
})
</script>
</html>

【15】计算属性

# 1  计算属性是基于它们的依赖进行缓存的# 2 计算属性只有在它的相关依赖发生改变时才会重新求值# 3 计算属性就像Python中的property,可以把方法/函数伪装成属性# 4 写在computed中,必须返回值--》返回值才是属性-以后把他当属性用-可以被for循环

通过计算属性实现名字首字母大写

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div id="app"><input type="text"  v-model="nameText"> ---> {{upperFirst}}
</div>
<script>let vm = new Vue({el: '#app',data:{nameText:'',},methods:{},computed:{upperFirst(){return this.nameText.substring(0, 1).toUpperCase() + this.nameText.substring(1)}}})
</script>
</body>
</html>

【16】监听属性

​ 虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

​ 需要监听哪个属性,就在watch里面写哪个属性,只要这个属性发送改变,就会自动执行这个方法

小案例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous"><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"integrity="sha384-/mhDoLbDldZc3qpsJHpLogda//BVZbgYuw6kof4u2FrCedxOtgRZDTHgHUhOCVim"crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script src="../js/vue.js"></script>
</head>
<body>
<div id="app"><button class="btn btn-success" @click="res='python'">python</button><button class="btn btn-info" @click="res='java'">java</button><button class="btn btn-danger" @click="res='go'">go</button>result --->{{res}}
</div>
<script>let vm = new Vue({el: '#app',data: {res: ''},watch:{ // 想要监听哪个参数就在watch里面写哪个参数,当这个参数发生变化就会自动执行// before改变前,back改变后 这两参数可填可不填res(before,back){console.log(back,before)}}})
</script>
</body>
</html>

【17】生命周期

​ vue生命周期分别有创建、初始化数据、编译模板、挂在DOM、渲染-更新-渲染、卸载利用钩子函数完成对应的项目效果

beforeCreate( 创建前 )

在实例化之后,数据的观测和事件的配置之前的时候调用,此时组件的选项对象还未创建,el 和 data 并未初始化,因此无法访问methods, data, computed等上的方法和数据

created ( 创建后)

在创建之后使用,主要用于数据观测、属性和方法的运算,watch/event事件回调,完成了data 数据的初始化,el没有。 然而,挂在阶段还没有开始.

beforeMount (挂载前)

用于在挂载之前使用,在这个阶段是获取不到dom操作的,把data里面的数据和模板生成html,完成了data等初始化,注意此时还没有挂在html到页面上

mount (挂载后)

用于挂载之后使用,在这个时候可以获取到dom操作,比如可以获取到ref等,操作的dom, 在这个时候只能调用一次ajax,在这个时候el和data都可以获取的到

beforeUpdate (更新前)

在数据更新之前被调用,发生在虚拟DOM重新渲染,可以在该钩子中进一步地更改状态,不会触发重复渲染过程

updated (更新后)

在由于数据更改导致地虚拟DOM重新渲染会调用,调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作,然后在大多是情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环,但是在服务器端渲染期间不被调用,可以用于监听某些数据的时候使用钩子

beforeDestroy(销毁前)

在这个时候还是可以用this来获取,可以用于销毁计时器时候使用,为了防止跳转到其它页面该事件还在执行,还可以清除dom事件等

destroy(销毁后)

在实例销毁之后调用,调用后,所以的事件监听器会被移出,所有的子实例也会被销毁.

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="./js/vue.js"></script>
</head>
<body>
<div id="app"><child v-if="showChild"></child><button @click="showChild=!showChild">点我消失</button>
</div>
</body>
<script>Vue.component('Child', {template: `<div><button @click="handleClick">{{ title }}</button></div>`,data() {return {title: 'hello word'}},methods: {handleClick() {alert(this.title)this.title = '你好世界'},},// 在创建实例之前执行 this.title不会有值 this.$el不会有值beforeCreate() {console.log('beforeCreate')console.log(this.title)console.log(this.$el)},// 创建实例时执行 this.$el不会有值created() {console.log('Create')console.log(this.title)console.log(this.$el)},// 挂载之前执行 this.$el不会有值beforeMount() {console.log('beforeMount')console.log(this.title)console.log(this.$el)},mounted() {console.log('mounted')console.log(this.title)console.log(this.$el)},// 在没有更新数据就不会执行, 有更新的话会在更新之前执行beforeUpdate() {console.log('beforeUpdate')console.log(this.title)console.log(this.$el)},//  // 在没有更新数据就不会执行, 有更新的话会在更新之后执行updated() {console.log('Updated')console.log(this.title)console.log(this.$el)},// 在没有执行删除就不会执行, 有删除操作的话会在删除之前执行beforeDestroy() {console.log('beforeDestroy')console.log(this.title)console.log(this.$el)},// 在没有执行删除就不会执行, 有删除操作的话会在删除之后执行destroyed() {console.log('destroyed')console.log(this.title)console.log(this.$el)}})let vm = new Vue({el: '#app',data: {showChild: true},methods: {}})
</script>
</html>

【18】组件的使用

​ 组件分为局部组件和全局组件,全局组件可以在根组件的任意位置使用,局部组件只能使用在父组件里面

​ 组件中的数据,事件都是独立的

全局组件的书写

<body>
<div id="app"><Child></Child>
</div>
</body><script>// 全局组件的书写Vue.component('Child', {// 需要通过template挂载template: `<div><h1>我是全局组件</h1><p>{{ message }}</p><button @click="handleClick">点我显示名字</button></div>`,// data需要写成一个函数 然后把值写在函数的返回值里data() {return {message: '需要写在根组件里'}},// 方法的写法和根组件的写法一致methods: {handleClick() {this.message = 'green'}}})let vm = new Vue({el: '#app',})
</script>

局部组件的书写

<body>
<div id="app"><p>{{message}}</p><button @click="handleClick">点击显示根组件名字</button><Child></Child>
</div>
</body>
<script>let vm = new Vue({el: '#app',data: {message: '我是根组件'},methods: {handleClick() {this.message = 'green'}},// 在根组件中定义局部组件,这里以根组件为例子,定义在哪里的局部组件,就只能在哪里使用components:{Child:{template:`<div><h1>我是局部组件,根组件的子组件</h1><button @click="handleClick">点我弹窗</button></div>`,data(){return{message:'我是子组件Child'}},methods: {handleClick(){alert(this.message)}}}}})
</script>

【19】组件中通信

​ 各个组件的数据都是独立的,要想实现各个组件的数据互通,需要用到一些特定的方法

父传子

<body>
<div id="app"><button @click="handleClick">点击给在子组件发消息</button><!--    1.在子组件标签中绑定数据属性--><Child :message="message"></Child>
</div>
</body>
<script>let vm = new Vue({el: '#app',data: {message: ''},methods: {handleClick() {this.message = '我是来自父组件的消息--->你好'}},// 定义子组件components: {Child: {template: `<div><h1>我是子组件Child</h1><p>来自父组件的消息---->{{ message }}</p></div>`,// 2.在子组件中定义props,将子组件标签中定义的数据属性键值填入props的数组props: ['message']}}})
</script>

子传父

<body>
<div id="app"><h1>我是父组件</h1><img :src="src" width="250px" height="300px" alt="" v-if="src"><!--    子组件给父组件传参数,需要给子组件标签绑定一个自定义事件--><Child @event="handleEvent"></Child>
</div>
</body>
<script>let em = new Vue({el: '#app',data: {src: ''},methods: {handleEvent(src) {this.src = src}},components: {Child: {template: `<div><h1>我是子组件</h1><img :src="src" alt="" width="250px" height="300px" v-if="src"><button @click="handleClick">点击把图片传到父组件</button></div>`,data() {return {src: './img/1.jpg'}},methods: {handleClick() {// 通过this.$emit('event', this.src),第一个参数就是自定义事件的名称,第二个参数就是传递的参数this.$emit('event', this.src)this.src = ''}}}}})
</script>

【20】ref属性

​ ref是Vue2中一个重要的属性,用于在组件中对DOM元素或者子组件的引用。通过ref,可以在某个组件的内部直接访问DOM元素或者它的子组件。

​ 在Vue2中可以将ref添加到元素,组件或者子组件的标签上,然后可以通过组件实例的$refs对象来访问这些引用

<body>
<div id="app"><h1>我是父组件</h1><button @click="handleClick" ref="button">点我看控制台</button><Child ref="child"></Child>
</div>
</body>
<script>let vm = new Vue({el: '#app',data: {},methods: {handleClick() {// this是当前Vue的实例// this.$refs是一个对象,里面包含了所有的有ref属性的标签的dom对象或者组件对象// 1.拿到子组件的属性console.log(this.$refs.child.message)// 2.修改子组件的属性this.$refs.child.message = '我是修改后的消息'// 3.调用子组件的函数this.$refs.child.handleClick('我是来自父组件的参数')// 4.给子组件的函数传参数}},components: {Child: {template: `<div ><h1>我是子组件</h1> <button @click="handleClick">点我看看</button><p>{{message}}</p></div>`,data() {return {message: '我是来自子组件的消息'}},methods: {handleClick(name){console.log('我被父组件的事件调用了')console.log(name)}}}}})
</script>

【21】动态组件

动态组件,就是实现动态切换的组件

记住以下三点,就能掌握动态组件

① 利用 <component/> 元素的 is 属性

is 属性应该用 v-bind 修饰(可以简写为 :

is属性应该传入注册的组件名

<body>
<div id="app"><button @click="name='Girl1'">美女1</button><button @click="name='Girl2'">美女2</button><button @click="name='Girl3'">美女3</button>
<!--   component是一个万能组件,他的is属性就决定了它是哪一个组件 --><component :is="name"></component>
</div>
</body>
<script>let vm = new Vue({el: '#app',data: {name:''}})Vue.component('Girl1', {template: `<div><h1>美女1</h1><img src="./img/1.jpg" alt=""></div>`})Vue.component('Girl2', {template: `<div><h1>美女2</h1><img src="./img/2.jpg" alt=""></div>`})Vue.component('Girl3', {template: `<div><h1>美女3</h1><img src="./img/3.jpg" alt=""></div>`})
</script>

【22】keep-alive

​ 在平常开发中,有部分组件没有必要多次初始化,这时,我们需要将组件进行持久化,使组件的状态维持不变,在下一次展示时,也不会进行重新初始化组件。

​ 也就是说,keepaliveVue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染 。也就是所谓的组件缓存

<keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。

<!--被keepalive包含的组件会被缓存-->
<keep-alive><component><component />
</keep-alive>

【23】插槽

​ 正常情况下,如果已经写好了一个组件,并且想要往组件里面添加别的东西,就只能修改组件内容,拓展性很差

​ 所以就出现了插槽的概念,只需要在模板中可能需要更改的地方加上<slot></slot>,后续想要更新内容的时候直接在html里面加就行

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

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

相关文章

解决crypto.randomUUID is not a function

不在https、localhost等不安全的环境中访问时,crypto.randomUUID 是不可用的。 如果这个是由第三方库引起的,如果不影响使用可以不解决,如果影响到使用,暴力解决办法为修改node_modules里面的代码。 记得清除构建工具(例如vite)的缓存(例如./node_modules/.vite文件夹)…

最小割的结论

记 \(f\) 为任意最大流,令 \(G_f\) 为 \(f\) 的残量网络。记 \(G_f\) 中 \(s\) 可达的点集合为 \(S\),\(t\) 可达的点集合为 \(T\)。判断一个图的最小割是否唯一。最小割唯一 \(\iff\) \(S\cup T=V\)。若 \((u,u^C)\) 是最小割,则 \(G_f\) 中没有 \(u\rightarrow u^C\) 的边…

05. C语言数组

数组用于将多个数据集中存储,方便管理,此文将集中存储任何类型数据的语句都称为数组,数组根据存储数据的类型和方式分为同型数组、结构体、共用体、枚举。【同型数组】 同型数组也直接称为数组,用于存储多个类型相同的数据,数组内的数据称为数组元素,数组元素占用连续的虚…

linux22-IP地址和主机名

linux22-IP地址和主机名IP地址,查看本机IP地址主机名, 查看与修改域名解析,配置主机名映射虚拟机配置固定IPIP地址 联网计算机的网络地址, 用于在网络中定位 ifconfig 查看本机的ip地址, 如果无法使用ifconfig命令,可以安装net-tools # 安装net-tools (CentOS为yum) apt instal…

linux23-网络传输

linux23-网络传输使用ping检查服务器是否连通使用wget下载文件使用curl发起网络请求ping ping [-c num] ip或主机名-c 检查次数, 不使用-c选项会无限次数持续价差参数: 被检查的服务器IP地址或主机名地址检查baidu.com是否联通 ping baidu.com检查baidu.com是否联通, 检查三次 …

linux19-systemctl

linux19-systemctlsystem control, 控制应用的启动,停止,开机自启, 能被systemctl管理的软件,一般称之为服务 systemctl start | stop | status | enable | disable 服务名选项:start 启动stop 关闭status 查看状态enable 开启开机自启disable 关闭开机自启restart 重启系统内置…

linux20-ln软链接

linux20-ln软链接在系统中创建软链接, 可以将文件, 文件夹链接到其他位置, 类似Windows系统中的快捷方式 ln -s 参数1 参数2-s , soft , 创建软链接, 不添加时创建硬链接 (硬链接不允许指向目录) 参数1, 被链接的文件或文件夹, 不可以使用相对路径 参数2, 要链接去的目的地将/e…

linux21-日期时间

linux21-日期时间date 查看系统时间更改/etc/localtime 修改时区ntp自动校准时区date 查看系统时间 date [-d] [+格式化字符串]-d, 通过给定的字符串显示日期, 一般用于日期计算, 支持以下时间标记year 年month 月day 天hour 小时minute 分钟second 秒格式化字符串%Y 年%y 年份…