Vue-学习1
VUE
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
1.vue的介绍
vue是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。
渐进式框架的理解
阶梯式向前,逐步集成
vue是轻量级的,提供足够的功能或库,并且没有很多强制性的要求,
分层设计,每层可选,不同层可以灵活接入其他方案架构模式。
Vue的渐进式表现:
声明式渲染----组件系统-----客户端路由------大数据装填管理-------构建工具
如下图:
声明式渲染和组件系统是Vue的核心库所包含内容,而客户端路由、状态管理、构建工具都有专门解决方案。这些解决方案相互独立,你可以在核心的基础上任意选用其他的部件,不一定要全部整合在一起。
Vue的使用没有很多强制性的要求,但需要使用它的特殊形式来定义组件(这一点每个视图框架都有,Vue也难以避免)。
自底向上逐层应用
由基层开始做起,把基础的东西写好,再逐层往上添加效果和功能。
MVVM
MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 Model 的双向数据绑定,这使得Model 的状态改变可以自动传递给 View,即所谓的数据双向绑定。
M:model 数据层也就是数据 前端的js
V: view 指DOM层或用户界面
VM:view-model 处理数据和界面的中间层
Vue.js 就是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性。Vue会通过DOM Listeners来监听并改变Model层的数据。反之,当Model层的数据发生改变时,也会通过Data Bingings来监听并改变View层的展示。从而实现双向数据绑定的功能。
2.组件
组件的定义其实就是实现应用中局部功能代码(html,css,js)和资源(MP3 ,MP4,img,ttf等)的集合。其优势是能复用编码,简化项目代码,提高运行效率,降低程序员重复编码。
一个应用会以一棵嵌套的组件树的形式来组织
例:一个页面有页头、侧边栏、内容区等内容,那可以将页头、侧边栏、内容区这些以组件的形式嵌套在主页面中,而每个组件又包含了其它的像导航链接、博文之类的组件。
全局注册组件
通过 Vue.component
全局注册的:
Vue.component('my-component-name', {
// ... options ...
})
my-component-name为组件名,组件在全局注册注册之后可以用在任何新创建的 Vue 根实例 (new Vue
) 的模板中也包括其组件树中的所有子组件的模板中。
如:
Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })
new Vue({ el: '#app' })
<div id="app">
<component-a></component-a>
<component-b></component-b>
<component-c></component-c>
</div>
局部注册组件
输入框或按钮之类的元素等称为基础组件。
真正的 Vue 应用往往是由嵌套组件创建的。
一个组件中可以在模板中渲染另一个组件作为子组件,那这个组件称为父组件。
想要使用子组件,需要先导入子组件文件,还需要使用 components
选项注册组件,代码如下:
import ChildComp from './ChildComp.vue'
export default {
components: {
ChildComp
}
}
在模板中使用组件,如下:
<ChildComp />
或者
<child-comp></child-comp>
在组件上使用 v-model
v-bind 主要用于属性绑定,Vue官方提供了一个简写方式 :bind
自定义事件也可以用于创建支持 v-model 的自定义输入组件。
<input v-model="searchText">
等价于
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
- 将其
value
attribute 绑定到一个名叫value
的 prop 上 - 在其
input
事件被触发时,将新的值通过自定义的input
事件抛出
如:
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
})
<base-checkbox v-model="lovingVue"></base-checkbox>
lovingVue
的值将会传入这个名为 checked
的 prop。同时当 <base-checkbox>
触发一个 change
事件并附带一个新的值的时候,这个 lovingVue
的 property 将会被更新。
组件传值
1.父组件传值子组件(props)
Prop类型
props: {
title: String, // 字符串
likes: Number, // 数字
isPublished: Boolean, // 布尔
commentIds: Array, // 数组
author: Object, // 对象
callback: Function, // 函数
contactsPromise: Promise // Promise是一种异步编程解决方法,Promise本质上是一个构造函数或者类,可以产生promise实例对象
}
子组件可以通过props从父组件接受动态数据。
Prop 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。
所有的 props 都遵循着单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。
需要声明接受的props:
// 在子组件中
export default {
props: {
msg: String
}
}
一旦声明,msg
prop 就会暴露在 this
上,并可以在子组件的模板中使用。
父组件可以像声明 HTML attributes 一样传递 props。若要传递动态值,也可以使用 v-bind
语法:
<ChildComp :msg="greeting" />
Vue 支持将模板中使用 kebab-case 的标签解析为使用 PascalCase 注册的组件。这意味着一个以 MyComponent
为名注册的组件,在模板中可以通过 <MyComponent>
或 <my-component>
引用。
可以通过 ref
这个 attribute 为子组件赋予一个 ID 引用.
<base-input ref="usernameInput"></base-input>
已经定义了这个 ref
的组件里,就 可以使用:
this.$refs.usernameInput
来访问子组件中的方法
2.子组件传值父组件
export default {
// 声明触发的事件
emits: ['response'],
created() {
// 带参数触发
this.$emit('response', 'hello from child')// (父组件函数,要传的参数)
}
}
this.$emit()
的第一个参数是事件的名称。其他所有参数都将传递给事件监听器。
父组件可以使用 v-on
监听子组件触发的事件——这里的处理函数接收了子组件触发事件时的额外参数并将它赋值给了本地状态:
<ChildComp @response="(msg) => childMsg = msg" />
3.监听器
watch: {
// 如果 `question`(需要监听的属性名) 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
// newQuestion 为最新的值,oldQuestion 为更新之前的值
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
},
<input type="text" v-model="cityName"/>
new Vue({
el: '#root',
data: {
cityName: 'shanghai'
},
watch: {
cityName(newName, oldName) { // ... }
}
})
immediate立即监听
watch时有一个特点,就是当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行。如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性。
当父组件向子组件动态传值时,子组件props首次获取到父组件传来的默认值时,也需要执行函数,此时就需要将immediate设为true。
immediate属性:布尔值
immediate:true:首次加载就监听数据变化
immediate:false:只有发生改变才监听
new Vue({
el: '#root',
data: {
cityName: ''
},
watch: {
cityName: {
handler(newName, oldName) {
// ... },
immediate: true
}
}
})
handler固定方法触发
immediate表示在watch中首次绑定的时候,是否执行handler,值为true,则表示在watch中声明的时候,就立即执行handler方法,值为false,则和一般使用watch一样,在数据发生变化的时候才执行handler。
deep深度监听
需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。
<input type="text" v-model="cityName.name"/>
new Vue({
el: '#root',
data: {
cityName: {id: 1, name: 'shanghai'}
},
watch: {
cityName: {
handler(newName, oldName) { // ... },
deep: true,
immediate: true
}
}
})
设置deep: true 则可以监听到cityName.name的变化,此时会给cityName的所有属性都加上这个监听器,当对象属性较多时,每个属性值的变化都会执行handler。如果只需要监听对象中的一个属性值,则可以做以下优化:使用字符串的形式监听对象属性:
watch: { 'cityName.name': {
handler(newName, oldName) { // ... },
deep: true,
immediate: true
}
}
数组(一维、多维)的变化不需要通过深度监听,对象数组中对象的属性变化则需要deep深度监听。
计算属性和监听器
-
计算属性computed是:监听依赖值的变化
计算属性是基于它们的响应式依赖进行缓存的
只在相关响应式依赖发生改变时它们才会重新求值。
- 只要依赖值不变,都会直接读取缓存进行复用
- 计算属性不能响应异步操作中数据的变化
- 需要人为调用
-
监听器watch是:监听属性值的变化
- 只要属性值发生变化,都可以触发一个回调函数
- 监听器可以响应异步操作中数据的变化
- 自动触发
-
计算属性和方法
- methods 是一个方法,它可以接受参数,而 computed 不能
- computed 是可以缓存的,methods 不会
4.vue 中 message.split(‘’).reverse().join(‘’)函数用法
1.split(‘’)是将一个字符串分割成字符串数组
如:字符串msg为“123”,msg.split(‘’)的结果是[‘1’,‘2’,‘3’]
2.reverse()是将字符串数组进行反转
只作用于数组,跟在split(‘’)后才能起作用,在一个字符串后面不起作用
如:字符串msg为“123”,msg.split(‘’).reverse()的结果是[‘3’,‘2’,‘1’]
3.join(‘’) 把数组中的所有元素加入到一个字符串中
5. filter()用法
filter()过滤器,将一些内容过滤掉,但又不实际变更或者重置原始数据。
如下代码所示,将nembers数组中的数据除2余数为零的数据显示,不是则过滤掉。
const numbers = ref([1, 2, 3, 4, 5])
numbers.value.filter((n) => n % 2 === 0)