依次执行以下命令
修改app.vue文件,只保留以下结构即可
<template>
</template>
<script>
</script>
<template>
<h3>
模版语法
</h3>
<p>{{msg}}</p>
</template>
<script>
export default{
data(){
return{
msg:"开始学习vue"
}
}
}
</script>
页面效果
删成以下目录即可
值的绑定:{{ }}
属性绑定:v-bind: /:属性
去app.vue添加配置
<template>
<h3>条件渲染</h3>
<div v-if="flag">
您能看见我吗
</div>
<div v-else="flag">
你看不见我
</div>
</template>
<script>
export default{
data(){
return{
flag:true
}
}
}
</script>
<template>
<h3>条件渲染</h3>
<div v-if="flag">
您能看见我吗
</div>
<div v-else="flag">
你看不见我
</div>
<div v-show="flag">
你看不见我show
</div>
</template>
<script>
export default{
data(){
return{
flag:true
}
}
}
</script>
我们可以使用 v-for 指令基于一个数组来渲染一个列表。v-for 指令的值需要使用 item in items
形式的特殊语法,其中 items 是源数据的数组,而== item 是迭代项的别名==
<template>
<h3>
列表渲染
</h3>
<div v-for="item in names">{{item}}</div>
<div v-for="(item,index) in names">{{item}}-----{{index}}</div>
</template>
<script>
export default{
data(){
return{
names:["张三","李四","王五"]
}
}
}
</script>
<template>
<h3>遍历对象</h3>
<div v-for="item in userInfo">{{item}}</div>
<div v-for="(value,key,index) in userInfo">{{value}}----{{key}}---{{index}}</div>
</template>
<script>
export default{
data(){
return{
userInfo:{
username:"孙悟空",
age:34,
sex:"男"
}
}
}
}
</script>
Vue 默认按照就地更新的策略来更新通过 v-for 渲染的元素列表。当数据项的顺序改变时,Vue 不会随之移动 DOM 元素的顺序,而是就地更新每个元素,确保它们在原本指定的索引位置上渲染。
默认模式是高效的,但只适用于列表渲染输出的结果不依赖子组件状态或者临时 DOM 状态 (例如表单输入值) 的情况。
为了给 Vue 一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你需要为每个元素对应的块提供一个唯一的 key attribute
<template>
<div v-for="(item,index) in names" :key="index">
v-for 属性 Key {{item}}
</div>
</template>
<script>
export default{
data(){
return{
names:["zhangsan","lisi","anng"]
}
}
}
</script>
推荐在任何可行的时候为 v-for 提供一个 key attribute,除非所迭代的 DOM 内容非常简单 (例如:不包含组件或有状态的 DOM 元素),或者你想有意采用默认行为来提高性能。
我们可以使用 v-on 指令 (简写为 @) 来监听 DOM 事件,并在事件触发时执行对应的 JavaScript。用法:v-on:click="handler" 或 @click="handler"
。
事件处理器 (handler) 的值可以是:
很少用
<template>
<h3>内联事件</h3>
<button v-on:click="count++">Add</button>
<h3>{{ count }}</h3>
</template>
<script>
export default {
data() {
return {
count: 0
}
}
}
</script>
<template>
<h3>内联事件</h3>
<button @click="addCount">Add</button>
<h3>{{ count }}</h3>
</template>
<script>
export default {
data() {
return {
count: 0
}
},
//所有的方法或者函数都放在methods中
methods: {
addCount() {
//读取data数据中的值,利用this. 实现 例如 this.count
this.count++
}
}
}
</script>
有时我们需要在内联事件处理器中访问原生 DOM 事件。你可以向该处理器方法传入一个特殊的 $event
变量,或者使用内联箭头函数.
事件参数,可以获取event对象,和通过事件传递参数
<template>
<h3>事件参数</h3>
<button @click="addCount">Add</button>
<h3>{{ count }}</h3>
</template>
<script>
export default {
data() {
return {
count: 0
}
},
//所有的方法或者函数都放在methods中
methods: {
//event对象
addCount(e) {
//读取data数据中的值,利用this. 实现 例如 this.count
this.count++
console.log(e)
}
}
}
</script>
传递参数
事件传参2
<template>
<h3>传递参数</h3>
<button @click="getNameHandler(item)" v-for="(item, index) of names" :key="index">{{ item }}</button>
<h3>{{ count }}</h3>
</template>
<script>
export default {
data() {
return {
names: ["daddd", "smmm", "ssssdsddse"]
}
},
//所有的方法或者函数都放在methods中
methods: {
//event对象
getNameHandler(name) {
//读取data数据中的值,利用this. 实现 例如 this.count
console.log(name)
}
}
}
</script>
在处理事件时调用 event.preventDefault()
或 event.stopPropagation()
是很常见的。尽管我们可以直接在方法内调用,但如果方法能更专注于数据逻辑而不用去处理 DOM 事件的细节会更好。
为解决这一问题,Vue 为 v-on 提供了事件修饰符。修饰符是用 . 表示的指令后缀,包含以下这些:
.stop
.prevent
.self
.capture
.once
.passive
...
vue能够侦听响应式数组的变更方法,并在它们被调用时触发相关的更新操作
<template>
<h3>数组变化侦测</h3>
<button @click="addListHandle">添加数据</button>
<div v-for="(item, index) in names " :key="index" >{{ item }}</div>
</template>
<script>
export default {
data() {
return {
names: ["张三", "李四", "swh"]
}
},
methods: {
addListHandle() {
// //引起UI自动更新 ,在前台自动添加相应的展示
// this.names.push("我是自动更新的")
//数组发生变化,但是UI不会自动更新
this.names.concat("不是自动更新")
// // //引起UI自动更新 ,在前台自动添加相应的展示
// this.names = this.names.concat("自动更新")
}
}
}
</script>
模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。
你可能注意到我们在表达式中像这样调用一个函数也会获得和计算属性相同的结果:
<template>
<h3>ceee
{{ author.name }}
<!-- <p>{{ author.books.length > 0 ? 'Yes' : 'No' }}</p> -->
</h3>
<p>{{ calculateBooksMessage }}</p>
<p>{{ calculateBooksMessages() }}</p>
</template>
<script>
export default {
data() {
return {
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
}
},
computed: {
// 组件中
calculateBooksMessage() {
return this.author.books.length > 0 ? 'Yes' : 'No'
}
},
methods: {
calculateBooksMessages() {
return this.author.books.length > 0 ? 'Yes' : 'No'
}
}
}
</script>
数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。
因为 class 和 style 都是 attribute,我们可以和其他 attribute 一样使用 v-bind 将它们和动态的字符串绑定。
但是,在处理比较复杂的绑定时,通过拼接生成字符串是麻烦且易出错的。
因此,Vue 专门为 class 和 style 的 v-bind 用法提供了特殊的功能增强。除了字符串外,表达式的值也可以是对象或数组。
计算属性允许我们声明性地计算衍生值。然而在有些情况下,我们需要在状态变化时执行一些“副作用”:例如更改 DOM,或是根据异步操作的结果去修改另一处的状态。
在选项式 API 中,我们可以使用 watch 选项在每次响应式属性发生变化时触发一个函数。
在前端处理表单时,我们常常需要将表单输入框的内容同步给 JavaScript 中相应的变量。手动连接值绑定和更改事件监听器可能会很麻烦:
v-model 指令
帮我们简化了这一步骤
默认情况下,v-model 会在每次 input 事件后更新数据 (IME 拼字阶段的状态例外)。你可以添加 lazy 修饰符来改为在每次 change 事件后更新数据
简而言之 :就是在你输入完后,才去做对应的事件,而不是边输入边根据输入内容去搜索
<!-- 在 "change" 事件后同步更新而不是 "input" -->
<input v-model.lazy="msg" />
如果你想让用户输入自动转换为数字,你可以在 v-model 后添加 .number 修饰符来管理输入:
<input v-model.number="age" />
如果你想要默认自动去除用户输入内容中两端的空格,你可以在 v-model 后添加 .trim 修饰符:
<input v-model.trim="msg" />
当使用构建步骤时,我们一般会将 Vue 组件定义在一个单独的 .vue 文件中,这被叫做单文件组件 (简称 SFC):
scoped 作用
组件允许我们将 UI 划分为独立的、可重用的部分,并且可以对每个部分进行单独的思考。在实际应用中,组件常常被组织成层层嵌套的树状结构
建议局部组件引入,参照12.1引入方式
如果我们正在构建一个博客,我们可能需要一个表示博客文章的组件。我们希望所有的博客文章分享相同的视觉布局,但有不同的内容。要实现这样的效果自然必须向组件中传递数据,例如每篇文章标题和内容,这就会使用到 props。
Props 是一种特别的 attributes,你可以在组件上声明注册。要传递给博客文章组件一个标题,我们必须在组件的 props 列表上声明它。
props 只能父组件传递子组件
实际上任何类型的值都可以作为 props 的值被传递。
父组件
子组件
父组件向子组件动态传值
export default {
props: {
// 基础类型检查
//(给出 `null` 和 `undefined` 值则会跳过任何类型检查)
propA: Number,
// 多种可能的类型
propB: [String, Number],
// 必传,且为 String 类型
propC: {
type: String,
required: true
},
// Number 类型的默认值
propD: {
type: Number,
default: 100
},
// 对象类型的默认值
propE: {
type: Object,
// 对象或者数组应当用工厂函数返回。
// 工厂函数会收到组件所接收的原始 props
// 作为参数
default(rawProps) {
return { message: 'hello' }
}
},
// 自定义类型校验函数
propF: {
validator(value) {
// The value must match one of these strings
return ['success', 'warning', 'danger'].includes(value)
}
},
// 函数类型的默认值
propG: {
type: Function,
// 不像对象或数组的默认,这不是一个
// 工厂函数。这会是一个用来作为默认值的函数
default() {
return 'Default function'
}
}
}
}
在组件的模板表达式中,可以直接使用 $emit 方法触发自定义事件 (例如:在 v-on 的处理函数中)
触发自定义事件的目的是组件之间传递数据
父组件
<template>
<div>父组件</div>
<ChildB @someEvent="getHandle"></ChildB>
<div>显示子组件传递过来的数据{{ message }}</div>
</template>
<script>
import ChildB from './ChildB.vue';
export default {
data() {
return {
message: ""
}
},
components: {
ChildB
},
methods: {
getHandle(data) {
this.message = data;
}
}
}
</script>
子组件
<template>
<div>子组件</div>
<button @click="clickEventHandle">传递数据</button>
</template>
<script>
export default {
data() {
return {
msg: '子组件传递的数据'
}
},
methods: {
clickEventHandle() {
//自定义事件
this.$emit("someEvent", this.msg)
}
}
}
</script>
父组件
<template>
<div>父组件</div>
<div>子组件实时输入数据在父组件中实时显示: {{ search }}</div>
<main-c @searchEvent="getSearch"></main-c>
</template>
<script>
import MainCVue from './MainC.vue';
export default {
data() {
return {
search: ""
}
},
components: {
MainCVue
},
methods: {
getSearch(data) {
this.search = data;
}
}
}
</script>
子组件
<template>
<div>子组件</div>
搜索:<input type="text" v-model="search">
</template>
<script>
export default {
data() {
return {
search: " "
}
},
//监听器,监听数据 search 变化
watch: {
search(newValue, oldValue) {
this.$emit("searchEvent", newValue)
}
}
}
</script>
每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到 DOM,以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。
才开始不把所有的组件都加载进来,只有需要的时候才加载对应的组件
虽然这里的
provide,inject 只能由上到下,不能反向传递
祖宗级: 直接传递数据给孙子 provide
没有中间商
孙子:可以直接接收祖宗传递的数据 inject
Provide (提供)
要为组件后代提供数据,需要使用到 provide 选项:
export default {
provide: {
message: 'hello!'
}
}
Inject (注入)
要注入上层组件提供的数据,需使用 inject 选项来声明:
export default {
inject: ['message'],
created() {
console.log(this.message) // injected value
}
}
浏览器可以执行文件
html
css
js
image
所有vue文件最后会被打包成main.js执行
下面目录存放公共资源,图片等