-
vue绑定元素特性方法:
1.文本插值 {{msg}}
①v-once
指令你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。
这个将不会改变: {{ msg }}
②双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html
指令:
data:{
rawHtml:"red"
}
//输出红色的red
注意:不能使用 v-html
来复合局部模板
③javascript表达式
单个的!
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
但是复杂的表达式还是不要放在这里,使用计算属性比较好。
2.v-bind属性绑定
//可以简写为
//这个节点的title属性和vue实例的msg属性保持一致
从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:
data:{
attributName:'href'
}
v-bind:[attributName]="url"
//等价于
v-bind:href="url"
v-on也适用
-
条件渲染
v-if=" "
-
列表渲染
-
v-on事件监听
比如
//简写为
-
数据
只有当实例被创建时 data
中存在的属性才是响应式的。页面会重新渲染。
例外是:
使用 Object.freeze()
,这会阻止修改现有的属性,也意味着响应系统无法再追踪变化
var obj = {
foo: 'bar'
}
Object.freeze(obj)
new Vue({
el: '#app',
data: obj
})
{{ foo }}
-
实例方法:
都有前缀emit`方法
生命周期钩子
生命周期钩子的 this 上下文指向调用它的 Vue 实例。
这个特点使它,在生命周期钩子函数中,不要使用箭头函数。因为箭头函数并没有 this,this 会作为变量一直向上级词法作用域查找,直至找到为止。
-
计算属性
{{ message }}
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
其实上述过程也可以用,methods实现。那么compute和methods有什么区别呢?
不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message
还没有发生改变,多次访问 reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数。
(假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!)
setter
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
现在再运行 vm.fullName = 'John Doe'
时,setter
会被调用,vm.firstName
和 vm.lastName
也会相应地被更新。
-
侦听器
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
//执行某个方法
}
},
-
动态绑定属性
1.class
data:{isActive:true}
//渲染结果
他也是可以和普通class属性出现一起出现在标签中的。
也可以用[]
表示变量名,内部可以存放不止一个变量名。
或者放置一个表达式
2.style
①绑定变量或对象
data:{
fontsize:32,
obj:{
color: 'red',
fontSize: '13px'
}
}
CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名
②使用数组语法
③多重值
这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox
,那么就只会渲染 display: flex
。
-
条件渲染
1.v-if
v-else
v-else-if
用key管理可复用元素
进行条件渲染时,vue会最大程度复用组件。比如input的value就会保留上一个状态的value。给不同的key值就可避免这种情况。
2.v-show
v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
3.区别:一般来说, v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show
较好;如果在运行时条件很少改变,则使用 v-if
较好。
4.v-if
和v-for
不要在同一个标签内使用
(比如需要渲染符合条件的div,请先进行计算再列表渲染)
这是因为v-for优先级要比v-if要高,哪怕我们只渲染出一小部分用户的元素,也得在每次重渲染的时候遍历整个列表,不论活跃用户是否发生了变化。
-
列表渲染
v-for
index属性:遍历对象的下标
key值:如果不是特意依赖默认进行性能优化,建议保留key值,作为标签标识符。
还可以用来遍历对象
{{index}}:{{value}}
-
数组检测更新
1.变异方法
Vue 将被侦听的数组的变异方法进行了包裹,调用他们数组会被改变。所以它们也将会触发视图更新。
push()、 pop()、 shift()、 unshift()、 splice()、 sort()、 reverse()
2.非变异方法
调用他们原数组并不会发生变化。要使原数组变化需要另外赋值。
filter()、concat() 、slice()
在vue中这并不会丢失整个dom源,使列表重新渲染。
由于 JavaScript 的限制,Vue 不能检测以下数组的变动:(渲染不是响应式变化)
当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
解决第一个问题:
vm.$set(vm.items, indexOfItem, newValue)
解决第二个问题:
vm.items.splice(newLength)
还是js限制
Vue 不能检测对象属性的添加或删除
解决:vm.$set(vm.userProfile, propertyName, value)
这样添加的属性就是响应式的。
数据量大的时候,可以使用object.assign
方法新建一个对象
-
过滤属性
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
-
事件修饰符
https://blog.csdn.net/qq_29468573/article/details/80769778
他们还可以串联组合使用
-
v-model与表单绑定
1.基本用法
2.值绑定
3.修饰符
-定义组件
name:自定义组件名 (字母全小写且必须包含一个连字符)。
都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。
全局注册:
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: ''
})
局部注册:
var button-counter={...}
注意局部注册的组件,在其子组件是不可用的。
解决1:ComponentA 在 ComponentB 中可用,则你需要这样写:
var ComponentA = { /* ... */ }
var ComponentB = {
components: {
'component-a': ComponentA
},
// ...
}
解决2:es2015语法
import ComponentA from './ComponentA.vue'
export default {
components: {
ComponentA
},
// ...
}
-
通过prop向子组件传递数据
(之前是使用bind传递数据)
静态数据:
动态数据:
注意传递对象的时候,即使对象是静态的,也要用动态的传递方法。这是对象不是字符串。
如果在子组件需要修改prop值(一般不建议这样,会影响到父组件),最好使用计算属性进行计算。
prop检测
这利用的是prop定义时的方法
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
检测类型还可以是自定义的构造函数,并且通过 instanceof 来进行检查确认。
2.父子组件v-model传递问题
解决:
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
`
})
//使用
这里的 lovingVue 的值将会传入这个名为 checked 的 prop。同时当 触发一个 change 事件并附带一个新的值的时候,这个 lovingVue 的属性将会被更新。
注意你仍然需要在组件的 props 选项里声明 checked 这个 prop。
3.自定义组件时,一些原生的js组件(比如input等)被包裹了,所以在自定义组件上使用原生监听事件是不能够监听到的
解决:Vue 提供了一个 $listeners
属性,它是一个对象,里面包含了作用在这个组件上的所有监听器。
配合计算属性一起使用
computed: {
inputListeners: function () {
var vm = this
// `Object.assign` 将所有的对象合并为一个新对象
return Object.assign({},
// 我们从父级添加所有的监听器
this.$listeners,
// 然后我们添加自定义监听器,
// 或覆写一些监听器的行为
{
// 这里确保组件配合 `v-model` 的工作
input: function (event) {
vm.$emit('input', event.target.value)
}
}
)
template:
-
监听子组件事件
1.子组件通过$emit
抛出事件
2.父组件v-on
监听$emit
抛出的事件,触发操作
组件中使用v-model
-
插槽
1.概念:在组件中预留位置
!!!父组件使用插槽,推荐使用
包起来
Vue.component('alert-box', {
template:
Error!
})
Something bad happened.
// Something bad happened.渲染时代替插槽的位置
如果自定义组件内没有插槽的位置,则则该组件起始标签和结束标签之间的任何内容都会被抛弃。
2.作用域问题:
父级插槽内容是不能访问子组件的。但是可以用bind绑定
①
{{ user.lastName }}
②还可以在父组件中给这个插槽的user起个名字
{{ slotProps.user.firstName }}
3.默认插槽值
就是在子组件插槽中定义插槽值,如果父组件没有传递插槽值的话,就会渲染默认插槽值。如果有,就渲染父组件传递的插槽值。
4.具名插槽
当我们一个组件需要多个插槽的时候,我们可以使用name属性进行区分。
结合template
标签使用
//不设置name,则默认name为default
Here might be a page title
A paragraph for the main content.
And another one.
Here's some contact info
任何没有被包裹在带有 v-slot 的 中的内容都会被视为默认插槽的内容。
渲染结果
Here might be a page title
A paragraph for the main content.
And another one.
5.作用域插槽的内部工作原理是将你的插槽内容包括在一个传入单个参数的函数里:
function (slotProps) {
// 插槽内容
}
这意味着 v-slot 的值实际上可以是任何能够作为函数定义中的参数的 JavaScript 表达式。
更好的例子看这里:https://www.jianshu.com/p/e10baeff888d
{{ user.firstName }}
6.动态插槽名
...
7.缩写
Here might be a page title
Here might be a page title
-
动态组件
多标签的界面:
// 组件会在 `currentTabComponent` 改变时改变
某些html元素(比如:li),必须出现在特定标签(比如:ul)的内部。但是如果我们想要在ul中插入我们自定义的组件,可以这样
//aa是自定义组件
- 异步组件
只在需要的时候才从服务器加载一个模块。
Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
几种写法:
Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
// 向 `resolve` 回调传递组件定义
resolve({
template: 'I am async!'
})
}, 1000)
})
Vue.component(
'async-webpack-example',
// 这个 `import` 函数会返回一个 `Promise` 对象。
() => import('./my-async-component')
)
Vue.component('async-webpack-example', function (resolve) {
// 这个特殊的 require
语法将会告诉 webpack
// 自动将你的构建代码切割成多个包,这些包
// 会通过 Ajax 请求加载
require(['./my-async-component'], resolve)
})
处理加载状态: