笔记

day01

一、框架介绍

1.什么是框架

框架,framework,它是一个网站的半成品,能够让开发人员能够专注于业务逻辑的处理。

2.vue框架

作者:尤雨溪

官网:https://cn.vuejs.org/

渐进式的Javascript框架

3.第四阶段主要学习内容

vue框架

​ vue、路由、vue-cli脚手架、axios、stylus、UI库、vuex状态管理、typescript、服务器端渲染

react框架

​ react、jsx语法糖、脚手架、路由

4.vue框架入门

vue两大核心:数据驱动页面,组件化开发

(1)优点

①体积小

②运行速度快(轻量级框架)

③虚拟DOM机制

④指令系统

⑤组件化开发

⑥生态系统繁荣

(2)缺点

①兼容性,不兼容ie8

②报错相对来说不是特别的清晰

(3)vue框架介绍

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

(4)安装vue

①直接引入外部js

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

②npm安装

npm i vue

安装好之后直接引入

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

使用npm安装或者初始化项目前,一定要确认是否设置淘宝镜像地址(这样下载速度会比较快)

npm config set registry https://registry.npm.taobao.org

二、框架基本使用

1.实例化vue

new Vue({配置选项})

el:设置vue的作用范围,一般使用的id选择器,能够保证唯一性

el的挂载点不能是HTML、body这样的标签,应该是一个普通标签

2.设置初始数据

new Vue({
	el:"#app",
	data:{
		msg:"这里是初始数据"
	}
})

3.函数的声明和使用

自定义函数在methods选项中进行声明

new Vue({
	el:"",
	data:{},
	methods:{
		函数名称:function(){},
		函数名称N(){}
	}
})

使用自定义函数要在vue的挂载点内

<div id="app">
    {{ 函数名称() }}
</div>

三、指令系统

1.内容展示

(1)文本插值语法 {{ }}

mustache语法,双花括号内,可以写单行js语法

<p>{{ 10 + 20 }}</p>
<p>{{ status ? '已登录' : '未登录' }}</p>
<p>{{ '欢迎:' + name }}</p>
<p>欢迎:{{name}}</p>

vue中的指令都是以v-开头,都写在标签的开始标签上,作为一个属性去使用。

<标签名 指令=“”></标签名>

(2)v-text

v-text会把指定的内容展示到指定标签内部,类似原生JS中的innerText

(3)v-html

v-html会把指定的内容展示到指定标签内部,同时,它可以解析html语法,类似原生js中的innerHTML

文本插值语法和v-text、v-html的区别

1.它们都可以在页面中展示指定的内容

2.不同的是,v-text和v-html用于展示固定内容,如果要展示内容是某段文字中的一部分时,要使用文本插值语法。

<p v-text='name'></p>
<p v-html="name"></p>

2.条件判断

(1)v-if

​ v-if、v-else

​ v-if、v-else-if

单路分支

<标签 v-if="布尔值或者条件表达式"></标签>

如果布尔值或者条件表达式返回值为true,指定的标签会在页面结构中存在,否则就不存在。

双路分支

<标签1 v-if="布尔值或者条件表达式"></标签1>
<标签2 v-else></标签2>

多路分支

<标签1 v-if="布尔值或者条件表达式"></标签1>
<标签2 v-else-if="布尔值或者条件表达式N"></标签2>
...
<标签2 v-else></标签2>

(2)v-show

<标签1 v-show="布尔值或者条件表达式"></标签1>

不论布尔值或者条件表达式的返回值是什么,标签都会在页面结构中存在

当布尔值或者条件表达式的返回值为true时,标签会在页面结构中显示

当布尔值或者条件表达式的返回值为false时,会给标签添加一个display:none属性

v-if 惰性加载,满足条件了才会在页面结构存在指定的标签

v-show 只是改变了display属性,如果需要频繁的控制元素显示/不显示时,推荐使用v-show

v-show不能和v-else配合使用

3.事件绑定

<标签 v-on:事件名="一行js代码或者自定义函数名称"></标签>

可以简写成:

<标签 @事件名="一行js代码或者自定义函数名称"></标签>

4.属性绑定

(1)普通属性绑定

当需要让标签的属性按照既定的规律进行变化时,可以通过v-bind进行绑定,这样属性绑定的变量值发生变化后,对应的属性也会跟着进行变化。

<标签 v-bind:属性名=“属性值”></标签>

可以简写成

<标签 :属性名=“属性值”></标签>

示例代码:

<div id="app">
    <img v-bind:src="arr[showidx]" />
    <button @click="showidx--">上一张</button>
    <button @click="showidx++">下一张</button>
</div>
<script>
    var vm = new Vue({
        el:"#app",
        data:{
            showidx:0,
            arr:[
                '3.jpg',
                '2.jpeg',
                '1.jpg'
            ]
        },
        methods: {
            //下一张的点击事件
            next(){
                if(this.showidx >= (this.arr.length-1)){
                    return;//不能让showidx数组下标无条件的累加,return之后的代码就不再执行了
                }
                this.showidx++;
            },
            //上一张的点击事件
            prev(){
                if(this.showidx<=0){
                    return;
                }
                this.showidx--;
            }
        }
    })
</script>

此案例中,showidx就是要展示图片的下标值,当下标值发生变化时,就会根据下标从数组中获取对应的图片地址并绑定给src属性,数据变化后,页面会自动重新渲染。

(2)特殊属性绑定(动态样式绑定)

style

①变量的写法

<div id="app">
    <p :style="styleFont">破纪录!袁隆平团队双季稻晚稻亩产911.7公斤</p>
    <button @click="changeStyle('red')">红色</button>
    <button @click="changeStyle('blue')">蓝色</button>
</div>
<script>
	new Vue({
		el:"#app",
		data:{
			styleFont:{color:'red'}
		},
		methods:{
			changeStyle(color){
				this.styleFont = { color }
			}
		}
	})
</script>

②对象的写法

<p :style="{color:fontc,fontSize:'20px'}">破纪录!袁隆平团队双季稻晚稻亩产911.7公斤</p>
<p :style="{color:fontc,'font-size':'20px'}">破纪录!袁隆平团队双季稻晚稻亩产911.7公斤</p>

在对象写法中,属性名如果是多个单词,比如font-size、background-color、margin-left等,vue中需要把横杠和小写字母转换成大写字母:fontSize、backgroundColor、marginLeft。

③数组的写法

<p :style="[styleFont,styleSize]">破纪录!袁隆平团队双季稻晚稻亩产911.7公斤</p>

style的数组写法中,每一个数组元素都是一个变量,表示此标签可以使用多个行内样式。

class

①变量的写法

<style>
	.red{ color:red }
</style>
<div id="app">
	<p :class="className">港府公报:行政长官林郑月娥明起访问北京、广州和深圳</p>
</div>
<script>
	new Vue({
		el:"#app",
		data:{ className:'red' }
	})
</script>

②对象的写法

<style>
	.big{ font-size:40px; }
    .small{ font-size:15px;}
</style>
<div id="app">
	<p :class="{big:false,small:true}">港府公报:行政长官林郑月娥明起访问北京、广州和深圳</p>
</div>
<script>
	new Vue({
		el:"#app"
	})
</script>

布尔值或者表达式的结果为true时,表示使用指定的class属性,否则就不使用指定的class属性

③数组的写法

<style>
	.big{ font-size:40px; }
    .red{color:red;}
</style>
<div id="app">
	<p :class="['big','red']">港府公报:行政长官林郑月娥明起访问北京、广州和深圳</p>
</div>
<script>
	new Vue({
		el:"#app"
	})
</script>

5.列表渲染(循环)

v-for

语法格式:

<标签名 v-for="每次遍历的元素的变量名 of 数据源" ></标签名>

(1)数组

<标签名 v-for="(每次遍历的数组元素的变量名,遍历元素的下标) of 数据源" ></标签名>

(2)对象

<标签名 v-for="(每次遍历键值对中的键值,每次遍历键值对中的键名,每次遍历键值对的下标) of 数据源"></标签名>

(3)整数

<标签名 v-for="每次遍历键值对中的键值 of 整数值"></标签名>

如果想让某个标签遍历指定次数,可以直接遍历一个整数值,默认从1开始,每次递增1

示例代码:

<div id="app">
    <!-- 遍历数组,最多支持两个参数,第一个是元素,第二个是下标 -->
    <button v-for="(item,index) in arr">{{index}}---{{ item }}新闻</button>
    <!-- 遍历对象,最多支持三个参数,第一个是键名,第二个是键值,第三个是下标  -->
    <p v-for="(index,item,key) of info">{{key}}---{{ index }}---{{ item }}</p>
    <!-- 遍历整数,默认从1开始进行遍历,每次递增1,到指定数值结束 -->
    <p v-for="num in 10">{{ num }}</p>
</div>
<script>
    var vm = new Vue({
        el:"#app",
        data:{
            arr:[ '北京','中国','国际','热点'],
            info:{
                name:'小王',
                age:18,
                address:'北京市朝阳区'
            }
        }
    })
    // 原生js中of获取到是的元素内容,in获取到的是元素下标
    // var arr2 = [ '北京','中国','国际','热点']
    // for(item of arr2){
    //     console.log(item)
    // }
</script>

常见错误

1.vue.js:634 [Vue warn]: Do not mount Vue to or - mount to normal elements instead.

vue的挂载点不能是html、body标签,应该是一个普通的标签

2.[Vue warn]: Property or method “msg” is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

vue框架是一个声明式框架,变量或者函数要先声明然后再使用

3.[Vue warn]: Error compiling template:

v-else used on element without corresponding v-if.

v-else和v-else-if必须依存v-if才能使用

day02

一、表单元素双向绑定

1.设计模式

(1)MVC

smalltalk,把用户的输入、输出、处理分开

m model 数据模型层

v view 视图层(html、css、js)

c controller 控制器层

(2)MVVM

m model 数据模型层

v view 视图层

vm viewmodel 视图模型层

2.文本框

<input type="text" v-model="msg">

数据响应式原理:

原生JS示例代码:

<script>
    let person = {
        wh:"燕人",
        get wh(){
            console.log("获取外号....")
            return "张飞";
        },
        set wh(val){
            console.log("设置外号....",val)
        }
    }
    console.log(person.wh)//读取数据,就会自动触发get方法
    person.wh = "关羽"//设置数据,就会自动地触发set方法
</script>

3.文本域

textarea

<textarea cols="30" rows="10" v-model="content"></textarea>

4.复选框

checkbox

(1)多选

<div id="app">
    <div>
        <label>兴趣爱好:</label>
        <input type="checkbox" v-model="hobbys" value="打游戏">打游戏
        <input type="checkbox" v-model="hobbys" value="看电影">看电影
        <input type="checkbox" v-model="hobbys" value="逛吃">逛吃
    </div>
    <div>
        选择的是:{{ hobbys }}
    </div>
    
</div>
<script>
	new Vue({
		el:"#app",
		data:{
			hobbys:[]
		}
	})
</script>

复选框的初始数据类型,一定是数组,这样才能够实现多选的情况

多选的情况下,checkbox一定要设置value属性

(2)单选

<div id="app">
    <div>
    <!-- 是否同意协议:<input type="checkbox" :checked="isagree"> -->
    是否同意协议:<input type="checkbox" v-model="isagree">
    </div>
</div>
<script>
	new Vue({
        el:"#app",
        data:{
            isagree:true
        }
    })
</script>

单选的情况下,checkbox不需要设置value属性

5.单选框

radio

<div id="app">
	<div>
        <label>状态:</label>
        <!-- <input type="radio" name="status">正常
<input type="radio" name="status">禁用 -->
        <input type="radio" value="1" v-model="status">正常
        <input type="radio" value="2" v-model="status">禁用
    </div>
    <div>
        选择的是:{{ status }}
    </div>
</div>
<script>
	new Vue({
        el:"#app",
        data:{
            status:1
        }
    })
</script>

radio和checkbox(多选)一样,都是要设置value属性,这样在进行数据绑定时,才能够根据指定的数据,控制元素的选中效果。

6.下拉菜单

select > option

<div id="app">
    <div>
        <label>所学专业</label>
        <select v-model="course">
            <option value="">--请选择--</option>
            <option value="1">web前端</option>
            <option value="2">java开发</option>
            <option value="3">ui设计</option>
        </select>
    </div>
    <div>
        选择的是:{{ course }}
    </div>
</div>
<script>
	new Vue({
        el:"#app",
        data:{course:""}
    })
</script>

原生html中想让某个选项选中,需要在这个选项中添加selected属性

<option selected="selected">web前端</option>

在vue中直接给select标签添加v-model双向绑定,就可以给相应的选项设置选中效果

二、自定义指令

Vue.directive("指令名称",{
	//inserted:function(el)
	inserted(el){
		//el就是使用自定义指令的标签元素
		//js操作。。。
	}
})

指令名称不需要添加v-前缀,但是在使用指令的时候需要添加v-前缀

inserted 被绑定元素插入父节点时就会调用该函数

bind 指定绑定到对应的元素后就会调用该函数

示例代码:

<div id="app">
    <input type="text" v-focus>
</div>
<script>
    Vue.directive("focus",{
        inserted(el){
            //el 就是使用该指令的标签元素
            el.focus();
        }
    })
    new Vue({
        el:"#app"
    })
</script>

示例代码2:

<div id="app">
    <h1 v-color="'red'">{{ msg }}</h1>
    <h1 v-color="'green'">{{ msg }}</h1>
</div>
<script>
    Vue.directive("color",{
        bind:function(el,binding){
            //el 是使用自定义指令的元素
            //binding 是自定义指令绑定的相关数据信息
            el.style.color = binding.value;
        }
    })
    new Vue({
        el:"#app",
        data:{
            msg:'hello 自定义指令'
        }
    })
</script>

三、修饰符

1.事件修饰符

(1).prevent

阻止默认事件

(2).stop

阻止事件冒泡

(3).capture

捕获事件冒泡,影响事件冒泡的顺序

(4).self

事件触发者是元素本身时,对应的事件函数才会执行

(5).once

修饰指定事件、修饰符只执行一次

示例代码:

<div id="app">
    <!-- 阻止默认事件 -->
    <!-- 修饰符可以连贯起来使用,也就是给一个事件添加多个修饰符 -->
    <button @contextmenu.prevent.once="menu">按钮</button>
    <!-- 阻止事件冒泡 -->
    <div class="outer" @click="outer">
        <div class="inner" @click.stop="inner"></div>
    </div>
    <hr>
    <!-- 捕获事件冒泡 -->
    <div class="outer" @click.capture="outer">
        <div class="inner" @click="inner"></div>
    </div>
    <!-- self -->
    <hr>
    <div class="outer" @click.self="outer">
        <div class="inner" @click.once="inner"></div>
    </div>
</div>
<script>
    new Vue({
        el:"#app",
        methods: {
            menu(){
                console.log('右键被点击了....');
            },
            outer(){
                console.log("outer....")
            },
            inner(){
                console.log("inner....")
            }
        },
    })
</script>

2.表单元素修饰符

(1).lazy

不再对表单元素进行实时的数据双向绑定,只有遇到change事件时,才会进行数据的双向绑定

(2).number

number修饰符可以保持数据类型为number,如果输入的内容中是以数字开头,非数字结尾,可以把非数字内容进行过滤。

(3).trim

过滤输入内容左右两边的空格

3.其他修饰符

(1)鼠标修饰符

.left

.middle

.right

(2)键盘修饰符

keydown、keyup

.esc

.enter

.space

.backspace

.left

.right

.down

.up

.delete

day03

一、监听器

侦听器

作用:检测变量值的变化,只要数据变化,就可以触发相应的函数执行一定的操作。

作为vue实例的配置选项,watch

1.普通监听

可以检测标量类型数据的变化:字符串、数字(整数、浮点数)、布尔值

当依赖的数据发生变化时,就会触发对应的函数

①写法一

<script>
	new Vue({
		el:"",
		data:{ipt:''},
		watch:{
			ipt([newVal,oldVal]){
				....
			}
		}
	})
</script>

②写法二

<script>
	new Vue({
		el:"",
		data:{ipt:''},
		watch:{
			ipt:{
                handler([newVal,oldVal]){...}
            }
		}
	})
</script>

2.深度监听

如果要监听的数据类型是复合类型时,普通的监听方式是无法实现,需要使用第二种写法并添加deep配置选项,来实现监听复合类型数据的变化。

复合类型:对象、数组

<script>
	new Vue({
		el:"",
		data:{
            info:{ name:'' }
        },
		watch:{
			info:{
                handler:function([newVal,oldVal]){...},
                deep:true//显示的设置为深度监听
            }
		}
	})
</script>

二、数据变化后页面不更新

解决办法:

(1)$set

vue.$set(target,key,value)

target是要改变的数据

key是数组的下标

value是要改变的内容

(2)$forceUpdate

强制重新渲染页面

(3)使用数据的相关api方法(push、shift、unshift…)

三、计算属性

1.基本使用

页面上有频繁需要进行计算得到结果,可以使用计算属性

computed

<div id="app">
	{{ 要计算的结果变量名 }}
</div>
<script>
	new Vue({
		el:"",
		computed:{
			要计算的结果变量名1(){
				计算逻辑...
				return 计算结果
			},
            要计算的结果变量名N(){
				计算逻辑...
				return 计算结果
			},
		}
	})
</script>

2.计算属性和监听的区别

相同:依赖的数据发生变化时,对应的函数会自动执行

不同:触发场景不同,监听是在页面渲染完成后,数据发生变化时,才会触发对应的函数

​ 计算属性,只要页面中使用了计算属性的结果,或者依赖的数据发生变化时,就会触发对应的函数。

3.计算属性与函数的区别

计算属性依赖的数据,不发生变化时,不会重新执行相应的函数,因为计算属性在vue实例上产生了一个缓存。

函数调用几次,就会执行对应的函数几次,在性能上消耗比计算属性大很多。

计算属性的结果不能直接赋值

四、过滤器

作用:在页面展示数据前,可以通过过滤器对要展示的数据进行二次处理,满足一定的需求后再展示出数据。

1.定义

(1)全局定义

Vue.filter("过滤器名称",function(形参1){...})

(2)局部定义

<script>
	new Vue({
		el:"",
		data:{},
		methods:{},
		watch:{},
		computed:{},
		filters:{
			过滤器名称:function(实参1){
				处理逻辑...
				return 处理结果
			}
		}
	})
</script>

2.使用

在挂载点内,通过管道符“|” 来使用定义好的过滤器。

{{ 要展示的变量 | 过滤器名称 }}

3.过滤器的参数

在过滤器中,第一个参数默认是管道符左边的数据

如果要传递额外的其他参数时,需要像使用函数传参一样,把过滤器名称当成函数名称,然后在后面传递额外的参数。

示例代码:

<div id="app">
	<p>
        <!-- 调用过滤器后,就会展示一个两位小数的价格 -->
        价格:{{ price | formatPrice }}
    </p>
    <p>
        <!-- 调用过滤器后,就会展示一个一位小数的价格 -->
        价格:{{ price | formatPrice(1) }}
    </p>
</div>
<script>
    new Vue({
        filters:{
            formatPrice:function(price,n=2){
                return '¥' + price.toFixed(n) + '元';
            }
        },
        el:"#app",
        data:{ price:288 }
    });
</script>

五、生命周期

vue实例从创建、挂载、更新、销毁的一个完整的过程叫做生命周期。

钩子函数(在指定的场景下会自动触发的函数)

1.页面渲染期

beforeCreate vue实例创建之前

created vue实例创建完成

beforeMount vue实例挂载到挂载点之前

mounted vue实例挂载到挂载点之后

2.页面更新期

beforeUpdate 数据更新之前

updated 数据更新完成

3.页面销毁期

beforeDestroy 页面销毁之前

destroyed 页面销毁完成

day04

一、过渡动画

使用场景:v-if、v-show、动态组件、组件根节点

1.内置类名

<transition>
	<要使用过渡动画效果的标签></要使用过渡动画效果的标签>
</transtion>

(1).匿名动画

进入

​ 进入开始 v-enter

​ 进入进行中 v-enter-active

​ 进入结束 v-enter-to

离开

​ 离开开始 v-leave

​ 离开进行中 v-leave-active

​ 离开结束 v-leave-to

示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <style>
        .box{
            width: 300px;
            height: 300px;
            background-color: red;
        }
        .v-enter,.v-leave-to{ opacity: 0; }
        .v-enter-active,.v-leave-active{ transition:1.5s linear; }
        .v-enter-to,.v-leave{ opacity: 1; }
    </style>
</head>
<body>
    <div id="app">
        <transition>
            <div class="box" v-if="show"></div>
        </transition>
        <button @click="show=!show">切换</button>
    </div>
    <script>
        new Vue({
            el:"#app",
            data:{
                show:true
            }
        })
    </script>
</body>
</html>

(2)具名动画

页面中有多个标签要设置不同的过渡动画效果时,需要给transition标签设置name属性,设置name属性之后,内置类名的前缀就要改为对应的name属性。

<style>
	/* 具名过渡动画 */
    .move-enter,.move-leave-to{left:0;}
    .move-enter-active,.move-leave-active{ transition:1.5s linear;background-color: blue; }
     .move-enter-to,.move-leave{ left: 600px; }
    </style>
<transition name="move">
	<div class="box2" v-if="show"></div>
</transition>

2.animate.css动画库

(1)安装

npm i animate.css

(2)引入

<link rel="stylesheet" href="./node_modules/animate.css/animate.css">

(3)使用

需要给transition标签设置两个属性

enter-active-class 进入的动画

leave-active-class 离开的动画

示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>过渡动画-动画库</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <link rel="stylesheet" href="./node_modules/animate.css/animate.css">
    <style>
        .box{
            width: 300px;
            height: 300px;
            background-color: red;
        }
    </style>
</head>
<body>
    <div id="app">
        <button @click="show=!show">切换</button>
        <transition 
            enter-active-class="animate__animated animate__bounceInUp"
            leave-active-class="animate__animated animate__bounceOutLeft"
        >
            <div class="box" v-if="show"></div>
        </transition>
        
    </div>
    <script>
        new Vue({
            el:"#app",
            data:{
                show:true
            }
        })
    </script>
</body>
</html>

二、组件【重点】

1.介绍

组件即零件,组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用

组件是可复用Vue 实例

因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。

2.注册

(1)局部注册

new Vue({
	components:{
		组件名称1:{
			template:"组件模板内容"
		},
		组件名称N:{
			template:"组件模板内容"
		}
	}
})

(2)全局注册

Vue.component("组件名称1",{ template:"组件模板内容" })
Vue.component("组件名称N",{ template:"组件模板内容" })

3.使用

在vue的挂载点内,以标签的方式来使用组件

在vue的挂载点内使用组件后,组件名称的所在位置会被组件的template内容进行替换。

示例代码:

<div id="app">
    <!-- 使用组件 -->
    <mycom></mycom>
    <mycom></mycom>
    <mycom></mycom>
</div>
<script>
    new Vue({
        el:"#app",
        components:{
            mycom:{
                // 组件的template中只能有一个根标签
                template:"<div><h1>这是一个自定义组件</h1><h2>标题2</h2></div>"
            }
        }
    })
</script>

4.注册组件注意事项

(1)组件名称不能是系统内置的标签名

(2)组件名称不能是系统内置的大写的标签名

(3)如果组件名称中包含了大写字母,在使用要把大写字母转换成-小写字母

(4)template内容中只能有一个根标签

5.template的使用

(1)vue实例的template选项

组件中可以通过template属性来设置该组件的模板内容

vue实例上也可以设置一个template属性,用来把指定的template对应的内容或者组件,替换到vue实例的挂载点内。

示例代码:

<script>
	new Vue({
        el:"#con",
        // template:"<h2>vue实例的template属性</h2>"
        template:"<my-div />",
        components:{
            myDiv:{
                template:"<h1>自定义组件</h1>"
            }
        }
    });
</script>

(2)template标签

如果组件中的模板内容比较多时,使用字符串的方式编写html代码会很麻烦,且没有任何语法提示,如果代码编写不够熟练,非常容易出现错误。

vue中给提供了一个template标签,用来存放组件的模板内容

示例代码:

<div id="app">
    <mycom></mycom>
</div>
<template id="mycom">
	<div>
    	<h1>自定义组件</h1>
    </div>
</template>
<script>
    new Vue({
        el:"#app",
        components:{
            mycom:{
                // 让组件的template属性和template标签关联起来
                template:"#mycom"
            }
        }
    })
</script>

6.组件的key属性

组件遍历循环时,需要给组件添加一个唯一的标识,能够加快页面的渲染速度

7.组件中的data应该是一个函数

由于对象是引用类型,所以在data中以对象的方式定义初始数据,然后在组件中使用数据并复用这个组件时,会产生数据上的冲突(也就是一个数据改变了之后,其他的也跟着进行变化)

所以,在组件中定义初始数据,需要以函数的方式返回一个新的对象来定义数据,这样每复用一次组件,就会调用一次data的函数并返回一个新的数据存储空间,这样组件与组件之间的数据就不会互相影响了。

实例代码:

<div id="app">
    <v-box></v-box>
    <v-box></v-box>
    <v-box></v-box>
</div>
<template id="box">
<div class="box">
    <p>数量:{{ num }}</p>
    <button @click="num++">增加数量</button>
    </div>
</template>
<script>
    new Vue({
        el:"#app",
        components:{
            vBox:{
                template:"#box",
                data:function(){
                    return{
                        num:100
                    }
                }
            }
        }
    })
</script>

注意:在组件中,不能直接使用vue根实例上的data数据,因为组件也是一个vue实例,实例与实例之间的数据是不共享的。

三、vue-cli脚手架

最新版本:4.X

稳定版本:2.9.6

1.安装

node环境

(1)webpack

npm i webpack -g

(2)vue-cli

npm i vue-cli -g

2.初始化项目

进入到一个指定的目录中,然后进入命令行

vue init webpack mydemo

安装过程:

Project name (mydemo) 	项目名称,如果不需要修改直接回车
Project description (A Vue.js project) 项目描述,如果不需要修改直接回车
Author (fan <fanmingjian@offcn.com>) 项目作者,如果不需要修改直接回车
Vue build (Use arrow keys) vue构建方式,选择默认的热编译
> Runtime + Compiler: recommended for most users
  Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specific HTML) are ONLY allowed in .vue files - re
nder functions are required elsewhere
Install vue-router? (Y/n) 是否安装vue路由,输入n
Use ESLint to lint your code? (Y/n) 是否安装eslint代码验证工具,输入n
Set up unit tests (Y/n) 是否创建单元测试,输入n
Setup e2e tests with Nightwatch? (Y/n) 是否创建端对端测试,输入n
Should we run `npm install` for you after the project has been created? (recommended) (Use arrow keys) 选择依赖安装方式,选择npm
> Yes, use NPM
  Yes, use Yarn
  No, I will handle that myself

3.运行项目

在命令行中,进入项目根目录,执行如下命令:

npm run dev

localhost:8080

4.目录结构

mydemo
	build		项目打包主程序目录
	config		项目配置文件目录
	node_modules 项目依赖目录
	src			项目源码目录
		assets	项目静态资源目录(参与打包)
		components 项目组件目录
		App.vue	项目根组件
		main.js	项目启动文件
	static		项目静态资源目录
	index.html	项目首页
	package.json项目依赖配置文件

项目运行流程:

index.html

/src/main.js

/src/App.vue

5.vue组件构成

在脚手架中,组件以单独的.vue后缀的文件存在,组件由三部分组成:

template模板,只有一个,所以不需要设置id属性

script 组件逻辑代码【非必须】

style 组件样式代码【非必须】

所有的组件都要先从App.vue开始,它是脚手架的根组件,在App.vue要引用其他组件的话需要使用import关键词

示例代码:

创建一个Home组件

/src/components/Home.vue

<template>
    <div>
        <h1>home组件</h1>
        <v-top></v-top>
    </div>
</template>
<script>
import vTop from './Top'
export default {
    components:{ vTop}
}
</script>

/src/App.vue

<script>
// 引入Home组件
import Home from './components/Home'
export default {
	components: {
		Home
	}
}
</script>
<template>
	<div id="app">
		<Home />
	</div>
</template>

<style>
/* 全局样式 */
h1 { color: red;}
</style>

常见错误

1.[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the “name” option.

组件没有正确的注册就使用了

2.vue.js:634 [Vue warn]: Do not use built-in or reserved HTML elements as component id: div

不使用系统内置标签作为组件名称

3.[Vue warn]: The “data” option should be a function that returns a per-instance value i

day05

一、组件通信【重点】

场景:由于组件与组件数据不共享,当需要复用组件并让组件中的内容不一样时,可以使用组件通信来实现。

1.父子组件

自定义属性和props

第一步:先创建两个组件,一个父组件parent.vue,一个子组件child.vue

在App.vue中引入父组件,并使用它

<script>
import vParent from './components/parent'
export default {
	components: {
        vParent
    }
}
</script>
<template>
	<div class="page">
        <v-parent></v-parent>
	</div>
</template>

第二步:在父组件中引入子组件,构建父子组件的关系,并通过自定义属性传递数据

/src/components/parent.vue

<template>
    <div>
        <h1>父组件</h1>
        <!-- 在父组件使用子组件时,通过自定义属性来传递数据 -->
        <v-child v-for="(item,index) of newsarr" :key="index"
            :newstitle="item"
        ></v-child>
    </div>
</template>
<script>
import vChild from './child'
export default {
    components:{ vChild },
    data(){
        return{
            newsarr:['国内','北京','国际','娱乐']
        }
    }
}
</script>

第三步:在子组件child.vue中通过props选项来接收父组件传递数据,并在子组件中使用这些数据

/src/components/child.vue

<template>
    <div class="box">
        <h1>{{ newstitle }}新闻</h1>
    </div>
</template>
<script>
export default {
    // 在子组件中通过props来接收父组件传递的数据
    // 子组件接收到数据后,就可以直接在子组件的模板中使用该数据了
    props:['newstitle']
}
</script>
<style>
    .box{
        border:1px solid #000;
        margin:20px;
        padding:20px;
    }
</style>

props验证

子组件可以对父组件传递的数据进行一些验证:数据类型、默认值、自定义验证。。。

(1)验证数据类型
<script>
export default {
    props:{
        // 验证数据类型,可以验证常见的数据类型:
        //字符串String 数字Number 布尔值 Boolean 对象 Object 函数 Function等
        newstitle:String
    }
}
</script>

验证多个数据类型

如果要接收的变量是多个数据类型,则需要这样去进行验证

<script>
export default {
    props:{
        newstitle:[String,Number]//此时父组件传递的数据既可以是字符串,也可以是数字
    }
}
</script>
(2)验证必填
<script>
export default {
    props:{
        viewnum:{
        	required:true,
            type:Number//验证必填的同时还可以验证数据类型
        }
    }
}
</script>

如果子组件中有一个父组件必须传递的数据,可以通过required来进行验证。

(3)默认值
<script>
export default {
    props:{
        viewnum:{
        	required:true,
            type:Number//验证必填的同时还可以验证数据类型
        },
        first:{
            // default:"什么也没有"
            //如果数据类型是对象或者数组时,默认值是一个函数,返回对应的数据格式
            default:function(){
                return{
                    title:'什么也么有'
                }
            }
        }
    }
}
</script>
(4)自定义验证规则
<script>
export default {
    props:{
        viewnum:{
        	required:true,
            type:Number,//验证必填的同时还可以验证数据类型
            validator:function(val){
                //自定义验证规则,只要返回值为false就会出现警告
                return val > 1 && val <= 999;
            }
        }
    }
}
</script>

props验证给出只是警告,不影响程序的运行。

2.子父组件

自定义事件、$emit

第一步:在父组件使用子组件的时候,传递一个自定义函数,并在父组件中定义好对应的函数操作

<v-child v-for="(item,index) of newsarr" :key="index"
    :newstitle="item.title" :num="item.num"
    :newsidx="index"
    @addbychild="addnum"
></v-child>
<script>
export default {
    components:{ vChild },
    methods:{
        addnum(n){
            this.newsarr[n].num++;
        }
    },
    data(){
        return{...}
    }
</srcipt>
    

第二步:在子组件中通过vue实例上的$emit方法,来触发父组件传递的事件函数

<template>
    <div class="box">
        <span>{{ newstitle }}</span>
        <span>访问量:{{ num }}</span>
        <button @click="add">访问</button>
    </div>
</template>

<script>
export default {
    props:['newstitle','num','newsidx',"arr"],
    methods:{
        add(){
            //触发父组件传递的事件函数,并传递参数
            this.$emit("addbychild",this.newsidx)
        }
    }
}
</script>

3.非父子组件

公用的容器(eventbus)、 e m i t 、 emit、 emiton

第一步,创建一个公用的容器

/src/main.js实例化vue之前

Vue.prototype.$ev = new Vue();

第二步:在数据发送的组件中,通过公用容器进行数据发送

this.$ev.$emit("事件名称","要传递的数据")

第三步:在数据接收的组件的挂载完成生命周期中实现数据的接收

mounted() {
    //通过容器,一直监听数据,只要有数据的发送,就可以收到数据
    this.$ev.$on("时间名称",(str)=>{
    	...
    })
}

二、组件进阶

1.is属性

改变html标签默认结构约束

动态组件

示例代码:

menu.vue

<template>
    <div class="menu">
        <a @click="tab('setting')">系统设置</a>
        <a @click="tab('student')">学生管理</a>
        <a @click="tab('course')">课程管理</a>
    </div>
</template>

<script>
export default {
    methods:{
        tab(tag){
            console.log(tag,'发送')
            this.$ev.$emit("changeTag",tag)
        }
    }
}
</script>

<style>
    .menu{
        text-align: center;
    }
    .menu a{
        display: block;
        color:#fff;
        font-size: 20px;
        margin:10px;
        cursor: pointer;
    }
</style>

main.vue

<template>
    <div class="main">
        <v-menu></v-menu>
        <div class="right">
            <!-- 动态组件 -->
            <div :is="tagname"></div>
        </div>
    </div>
</template>
<script>
import vMenu from './menu'
import setting from './setting'
import student from './student'
import course from './course'
export default {
    components:{
        vMenu,setting,student,course
    },
    mounted() {
        this.$ev.$on("changeTag",(t)=>{
            console.log(t,'接收')
            this.tagname = t;
        })
    },
    data(){
        return{
            msg:'hello',
            tagname:'setting'
        }
    }
}
</script>
<style>
    .main{
        flex:1;
        display: flex;
    }
    .menu{
        width:120px;
        background-color: #000;
    }
    .right{
        flex:1;
    }
</style>

2.ref

vue中提供了一个ref属性,可以给标签添加ref属性,来实现原生JS的一些操作或者父子组件通信的效果。

(1)字符串

<h1 ref="myh1">系统设置页面</h1>

此时在$refs中就会增加了一个myh1的内容,它的值就是DOM元素。

(2)数组

<ul>
	<li ref="lis" v-for="item of numarr" :key="item">{{ item }}</li>
</ul>

如果ref应该在一个遍历循环上,则会在$refs中增加一个数组,数组的每个元素都是一个DOM元素

(3)组件【常用】

给自定义组件添加ref属性后,可以利用DOM操作的方式,来给组件进行数据的传递

<template>
	<div>
		<v-item ref="myitem"></v-item>
	</div>
</template>
<script>
import vItem from './item'
export default {
    components:{ vItem },
    mounted(){
        //直接在父组件中通过ref来给子组件进行数据的传递
        this.$refs.myitem.msg = '系统设置-数据'
    }
}
</script>

3.jquery

如果有一些页面效果,不知道用vue如何实现,但是知道用jquery去实现,那么在vue中可以用jquery来进行操作。

(1)安装

npm i jquery

(2)使用

<script>
//引入jquery
import $ from 'jquery'
export default {
    methods:{
        toggle(){
            this.jQuery(".box").slideUp(2000)
        }
    }
</script>
<template>
	<div>
        <button @click="toggle">toggle</button>
        <div class="box"></div>
    </div>
</template>
<style>
    .box{
        width: 200px;
        height: 200px;
        background-color: #f00;
    }
</style>
# 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值