创建项目:
npm init vue@latest
拿到项目 看看有没有node modules
没有的话先nmp install 安装
启动 npm run serve/ npm run dev
1.模板语法
双括号:文本中的数据绑定仅仅支持单一表达式(就是能被求值的JS代码), 简单判断方法:是否可以放在return后面
2.属性绑定
v-bind,简写是 :
<!-- 绑定属性 -->
<a v-bind:href="url">点击这里</a>
<!-- 简写形式 -->
<a :href="url">点击这里</a>
eg:
new Vue({
el: '#app',
data: {
url: 'https://www.example.com'
}
});
<div id="app">
<a :href="url">点击这里</a>
</div>
双括号 ({{ }}):适合简单的数据绑定,例如显示文本内容。
v-bind:适合需要动态绑定属性值的场景,如动态改变链接地址、类名、样式等
3.条件渲染
<template>
<h3>条件渲染</h3>
<div v-if="flag">can u see me</div>
<div v-else>还是看我</div>
<div v-if="type ==='A' ">A</div>
<div v-else-if="type ==='B'">B</div>
<div v-else-if="type ==='C'">C</div>
<div v-else>not ABC</div>
<div v-show="flag" >can u see me</div>
</template>
<script>
export default{
data()
{
return{
flag:false,
type:"D"
}
}
}
</script>
显示
条件渲染
还是看我
not ABC
v-if 和 v-show 的区别
v-if
是“真正的”条件渲染,因为它会确保在切换过程中,条件块内的事件监听器和子组件适当地被销毁和重建。v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比较下,v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
- 一般来说,
v-if
有更高的切换开销,而v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用v-show
较好;如果在运行时条件很少改变,则使用v-if
较好。
4.列表渲染
<template>
<h3>列表渲染</h3>
<p v-for="name in names">{{ name }}</p>
<div>
<p v-for="(value,key,index) of userinfo" >{{ value }}-{{ key }}-{{ index }}</p>
</div>
</template>
<script>
export default
{
data()
{
return {
names:["小红","小王","小芳"],
userinfo:{
name:"sdas",
age:21,
sex:"男"
}
}
},
}
</script>
输出
列表渲染
小红
小王
小芳
sdas-name-0
21-age-1
男-sex-2
<p v-for="(value, key, index) in userinfo" :key="key">{{ value }} - {{ key }} - {{ index }}</p>
v-for:这是 Vue.js 中的指令,表示循环遍历。
(value, key, index)
:这三个是循环的变量。
value
:当前遍历到的属性的值。
key
:当前遍历到的属性的键。
index
:当前遍历的索引,从 0 开始。
key的“就地更新”的策略
当 Vue 正在更新使用 v-for
渲染的元素列表时,它默认使用“就地更
新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素
来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每
个索引位置正确渲染。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和
重新排序现有元素,你需要为每项提供一个唯一的 key attribute:
2024.7.4
5.事件处理
我们可以使用 v-on
指令 (通常缩写为 @ 符号) 来监听 DOM 事件,
并在触发事件时执行一些 JavaScript。用法为v-on:click="methodName"
或
使用快捷方式 @click="methodName"
事件处理器 (handler) 的值可以是:
内联事件处理器:事件被触发时执行的内联 JavaScript 语句 (与 onclick 类似)。
方法事件处理器:一个指向组件上定义的方法的属性名或是路径。
<template>
<h3>内联事件处理器1</h3>
<!-- button按钮实现累加的操作 -->
<button v-on:click="count++">Add</button>
<p>{{count}}</p>
</template>
<script>
export default{
data()
{
return{
count:0
}
}
}
</script>
<template>
<h3>内联事件处理器2</h3>
<button v-on:click="addcount">Add</button>
<p>{{count}}</p>
</template>
<script>
export default{
data()
{
return{
count:0
}
},
methods: {
addcount()
{
this.count+=1,
console.log("点击了")
}
},
}
</script>
<template>
<h3>内联事件处理器3</h3>
<!-- 获取event对象 -->
<button v-on:click="addcount">Add</button>
<p>{{count}}</p>
</template>
<script>
export default{
data()
{
return{
count:0
}
},
methods: {
addcount(e)
{
this.count++;
e.target.innerHTML = "Add" +this.count;
}
},
}
</script>
<template>
<h3>内联事件处理器4传递参数</h3>
<!-- 点击哪个名字就获取哪个 --> <p @click= "getNameHandler(item)" v-for="(item,index) of names" :key="index">{{ item }}</p>
</template>
<script>
export default{
data()
{
return{
names:["iwe","sad","sda"],
}
},
methods: {
getNameHandler(name)
{
console.log(name);
}
},
}
</script>
6.事件修饰符
常用事件修饰符:
1.prevent:阻止浏览器默认事件(常用);
2.stop:阻止事件冒泡(常用);
3.once:事件只触发一次(常用);
4.capture:使用事件的捕获模式;
5.self:只有 event.target 是当前操作的元素时才触发事件;
6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
<template>
<h3>事件修饰符</h3>
<a @click.prevent = "clickhandle" href="https://cn.vuejs.org/">vue官网</a>
<!-- 触发子元素的同时也触发了父元素,所以需要阻止冒泡 -->
<div @click="clickdive">
<p @click.stop="clickp">测试冒泡</p>
</div>
</template>
<script>
export default
{
data(){
return{
}
},
methods:{
clickhandle(e)
{
//通过event对象阻止默认事件
// e.preventDefault();//成功打印文本信息
console.log("点击了");
},
clickDiv()
{
console.log("div");
},
clickp(e)
{
//e.stopPropagation();
console.log("p");
}
}
}
</script>
7数组变化侦测
1.数组变更方法
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
2.数组替换方法
不能引起UI界面变化
filter()
concat()
slice()
<template>
<h3>数组变化侦听</h3>
<button @click="addlistHandle">添加数据</button>
<ul>
<li v-for="(item,index) of names" :key="index">{{ item }}</li>
</ul>
</template>
<script>
export default{
data()
{
return {
names:["aaa","bbb","ccc"],
}
},
methods: {
addlistHandle()
{
//变更方法
//引起ui自动更新
//this.names.push("ddd");
//替换方法
//不会引起ui自动更新s
// this.names.concat(["ddd"]);
// console.log(this.names.concat(["ddd"]));
//若是想ui依然发生变化那么赋值给原数组
this.names = this.names.concat(["ddd"]);
}
},
}
</script>
8计算属性
计算属性(computed properties)是基于响应式数据的派生值,它们的结果会被缓存,并且只有在相关依赖项发生变化时才会重新计算。计算属性的主要作用是简化模板中的逻辑,将复杂的操作抽离出来,并且提高性能。
计算属性缓存 vs 方法:
虽然计算属性和方法都可以实现同样的功能,但计算属性有缓存机制,而方法每次调用都会重新执行。
计算属性适用于依赖于响应式数据的复杂计算,而方法适用于不需要缓存的逻辑。
<template>
<h3>计算属性</h3>
<!-- 计算一次 -->
<p>{{computeshuxing}}</p>
<p>{{computeshuxing}}</p>
<!-- 计算俩次 -->
<p>{{computedmethod()}}</p>
<p>{{computedmethod()}}</p>
</template>
<script>
export default{
data()
{
return{
itaaa:{
name:"sad",
content:["aaa","vvv","sss"],
}
}
},
//计算属性
computed:{
computeshuxing()
{
return this.itaaa.content.length >0 ? 'yes' : 'no';
}
},
methods:{
computedmethod()
{
return this.itaaa.content.length >0 ? 'yes' : 'no';
}
}
}
</script>
9class绑定
数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。因为 class 和 style 都是 attribute,我们可以和其他 attribute 一样使用 v-bind 将它们和动态的字符串绑定。但是,在处理比较复杂的绑定时,通过拼接生成字符串是麻烦且易出错的。因此,Vue 专门为 class 和 style 的 v-bind 用法提供了特殊的功能增强。除了字符串外,表达式的值也可以是对象或数组。
2024.7.5
<template>
<p :class="{'active' : isActive, 'text-danger' :hasError}">class绑定</p>
<p :class="classObject">class绑定2</p>
<p :class="[arractive,arrhaserror]">class绑定3数组</p>
</template>
<script>
export default{
data()
{
return{
isActive:false,
hasError:true,
//绑定多个属性
classObject:{
'active':true,
'text-danger':true
},
arractive:'active',
arrhaserror:'text-danger'
}
}
}
</script>
<style>
.active{
font-size: 30px;
}
.text-danger{
color: red;
}
</style>
10.style绑定
基本同class绑定
<template>
<h3 :style="{color:activecolor,fontSize:fontSize+'px'}">style绑定</h3>
<h3 :style="styleobejct">style绑定2</h3>
</template>
<script>
export default{
data()
{
return{
activecolor:"green",
fontSize:30,
styleobejct:{
color:"red",
fontSize:"30px"
}
}
}
}
</script>
11.watch侦听器
它之所以叫侦听器,是因为它可以侦听一个或多个响应式数据源数据,并再数据源变化时调用所给的回调函数。
就是你传给watch侦听器一个响应式变量,然后当这个变量变化时,自动触发一个你定义的函数,
就像一个人被监控了一样,只要这个人一动,摄像头就会报警
我们可以只用watch选项在每次响应式属性发生变化时触发一个函数
(函数名必须与侦听对象保持一致,如下面中的message)
<template>
<h3>侦听器</h3>
<p>{{ message }}</p>
<button @click="updateHandle">修改数据</button>
</template>
<script>
export default{
data()
{
return{
message:"hello",
}
},
methods:{
updateHandle(){
this.message = "world";
}
},
watch:{
message(newval,oldvel)
{
console.log(newval,oldvel);
}
}
}
</script>
**12.v-model 表单输入绑定 **
v-model 可以在组件上使用以实现双向绑定。
双向绑定的核心在于数据流的双向传递。在 Vue.js 中,这种数据流可以分为两个方向:
数据模型到视图(Model to View):当数据模型发生变化时,Vue.js 会自动更新视图。这是通过 Vue 的响应式系统实现的。
视图到数据模型(View to Model):当用户在视图上进行输入时,Vue.js 会自动更新数据模型。这是通过事件监听和数据更新实现的。
v-model修饰符:
.lazy 修饰符:
.lazy 修饰符用于延迟数据更新,只在输入框失去焦点时才将数据同步到模型。这对于减少数据更新频率,以避免频繁的计算和渲染非常有用。
<input v-model.lazy="message">
.number 修饰符:
.number 修饰符用于将用户输入的值转换为数值类型。这对于处理需要数字计算的输入框(如计数器)非常有用。
<input v-model.number="counter">
.trim 修饰符:
.trim 修饰符用于去除用户输入的首尾空格,以保持数据的干净性。这在处理用户输入时非常有用,尤其是文本输入框。
<input v-model.trim="username">
<template>
<h3>表单输入绑定</h3>
<form>
<input type="text" v-model="message">
<p>{{ message }}</p>
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
</form>
</template>
<script>
export default{
data()
{
return{
message:"",
checked:false,
}
}
}
</script>
13模板引用(其实就是获取DOM操作)
虽然 Vue 的声明性渲染模型为你抽象了大部分对 DOM 的直接操作,但在某些情况下,我们仍然需要直接访问底层 DOM 元素。要实现这一点,我们可以使用特殊的 ref attribute:
<input ref="input">
ref
是一个特殊的 attribute
,和 v-for
章节中提到的 key
类似。它允许我们在一个特定的 DOM 元素或子组件实例被挂载后,获得对它的直接引用。这可能很有用,比如说在组件挂载时将焦点设置到一个 input
元素上,或在一个元素上初始化一个第三方库。
<template>
<h3>ref模板引用</h3>
<div ref="container">{{content}}</div>
<button @click="getelementHandle">获取元素</button>
</template>
<script>
/*
内容改变:{{}}
属性改变:b-bind
事件: v-on:click
*/
export default{
data()
{
return{
content:"内容"
}
},
methods:{
getelementHandle()
{
console.log(this.$refs.container.innerHTML = "改变后");
}
}
}
</script>
14组件组成
创建组件及引用关系
项目中新建pages文件夹,然后添加如下组件
Hearder,Main,Aside
Article,Item
Header.vue
<template>
<h3>Header</h3>
</template>
<style scoped>
h3{
width:100%;
height: 100px;
border: 5px solid #999;
text-align: center;
line-height: 100px;
box-sizing: border-box;
}
</style>
Main.vue
<template>
<div class="main">
<h3>Main</h3>
<Article></Article>
<Article></Article>
</div>
</template>
<script>
import Article from './Article.vue';
export default{
components:{
Article
}
}
</script>
<style scoped>
.main{
float: left;
width: 70%;
height: 400px;
border: 5px solid #999;
box-sizing: border-box;
}
</style>
Aside.vue
<template>
<div class="aside">
<h3>Aside</h3>
<Item></Item>
<Item></Item>
<Item></Item>
</div>
</template>
<script>
import Item from './Item.vue';
export default{
components:{
Item
}
}
</script>
<style scoped>
.aside{
float: right;
width:29%;
height: 400px;
border: 5px solid #999;
box-sizing: border-box;
}
</style>
Article.vue
<template>
<h3>Article</h3>
</template>
<style scoped>
h3{
width:80%;
margin:0 auto;
text-align: center;
line-height: 100px;
box-sizing: border-box;
margin-top: 50px;
background: #999;
}
</style>
Item.vue
<template>
<h3>Item</h3>
</template>
<style scoped>
h3{
width:80%;
margin:0 auto;
text-align: center;
line-height: 100px;
box-sizing: border-box;
margin-top: 10px;
background: #999;
}
</style>
App.vue
<template>
<!-- 第三步:显示组件 -->
<Header></Header>
<Main></Main>
<Aside></Aside>
</template>
<script>
//第一步:引入组件
import Header from "./pages/Header.vue";
import Main from "./pages/Main.vue";
import Aside from "./pages/Aside.vue";
//第二步:注入组件
export default{
components:{
Header,
Main,
Aside
}
}
</script>
15组件传递数据
1.父组件向子组件传递数据,使用props属性;子组件向父组件中传递数据,在子组件中使用$emit派发事件,父组件中使用v-on监听事件;缺点:组件嵌套层次多的话,传递数据比较麻烦。
2.祖先组件通过依赖注入(inject / provide)的方式,向其所有子孙后代传递数据;缺点:无法监听数据修改的来源,不支持响应式。
3.通过属性$root / $parent / $children /ref,访问根组件、父级组件、子组件中的数据;缺点:要求组件之间要有传递性。
4.通过事件总线(eventbus)的方式,可以实现任意两个组件间进行数据传递;缺点:不支持响应式,这个概念是vue1.0版本中的,现在已经废弃。
5.通过 VueJs 的状态管理模式 Vuex,实现多个组件进行数据共享,推荐使用这种方式进行项目中各组件间的数据传递。
2024.7.7
16插槽slots
插槽:简单理解就是组件内部留一个或多个的插槽位置,可供组件传对应的模板代码进去。插槽的出现,让组件变的更加灵活。
父组件
// home.vue
<template>
<div class="home">
<footerComponent>
<p>我是匿名插槽</p>
</footerComponent>
</div>
</template>
<script>
import footerComponent from '@/components/footerComponent.vue'
export default {
components: {
footerComponent,
}
}
</script>
子组件
// footerComponent.vue
<template>
<div>
<h1>子组件</h1>
<slot></slot> // 替换为 <p>我是匿名插槽</p>
</div>
</template>
2024.7.8
17Vue的生命周期
vue生命周期分为四个阶段
第一阶段(创建阶段):beforeCreate,created
第二阶段(挂载阶段):beforeMount(render),mounted
第三阶段(更新阶段):beforeUpdate,updated
第四阶段(销毁阶段):beforeDestroy,destroyed
2024.7.9