Vue基础知识整理
vue实例方法:
<div id="root">
{{num}}
<my-components></my-components>
</div>
<template id="tem">
<div>
<p>这是组件</p>
</div>
</template>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
const app = new Vue({
el: "#root",
data: {
num: 123,
obj: {c: 666}
},
components: {
"my-components": {
template: "#tem"
}
}
})
</script>
-
app.$el
与app.$refs
都是获取dom的节点,app.$el
是组件挂载的节点,而app.$refs.xxx
则是ref=xxx
的节点 -
app.$data
用于获取data中的所有数据,如果要直接获取数据可以通过app.$num
某个属性即可 -
app.$children
获取子组件 -
app.$root === app
相等获取vue实例 -
app.$options
返回一个对象,里面包含创建vue实例时传入的参数以及默认的参数,所以可以通过app.$options.data().num
来获取数据;app.$options.render = (h) => h("div", {}, "页面上数据重新update时触发"),例如加个定时器,那么h函数就会执行并渲染页面
-
const unWatch = app.$watch('xx', (n, o) => {})
,可用来监听data中的数据变化,但是用app监听是,watch
不会自动关闭,需要手动关闭,unWatch()
-
app.$on
与app.$emit
,用来定义事件以及触发事件,在父组件emit子组件的on事件vm.$on('test', (a ,b) => { //vm.$once事件是代表只执行一次 console.log('test is emit') }) vm.$emit('test', 1, 2) //可以传递给a, b
-
app.$forceUpdate
与app.$set(app.obj, 'xx', 1)
可以用来渲染当data中的obj并没?定义a时,但在html中我们有写入了a,原来a是不会被渲染出来的,但是这两条语句都能使得a渲染出来;起到了类似强制刷新的作用 -
app.$nextTick(function() {})
:常用来获取dom更新后的数据,因为dom更新数据时异步的,有时候并不能及时获取到,则可用这么方法;也可当做promise
使用Vue.nextTick() .then(function () { // DOM 更新了 })
vue的生命周期
- vue创建到挂载
beforeCreate () {
this.$on('test', (a, b) => {
console.log(a, b, '执行事件')
})
this.$emit('test', 1, 2)
//事件已完成,但dom与数据不能进行操作
},
created () {
console.log(this.msg)
this.msg = 888
console.log(this.msg)
//能操作data中的数据但不能操作dom
},
beforeMount () {
console.log(this.$refs.span, '还是不能操作获取dom')
//b不能获取dom
},
//这中间会执行render函数,进行虚拟dom的渲染
//接下来菜市mounted阶段
mounted () {
console.log(this.$refs.span, 'mounted能进行dom的获取与操作')
}
如果new Vue()时没有进行el的指定则不会进行beforeMount与mounted
,我们可以手动vm.$mount("#app")
如果new Vue()时有template: '<div>888</div>',或者render (h) { h('div', {}, '888')}
都会对el:#app的dom进行整体覆盖
- vue数据更新
beforeUpdate
与updated
当数据发生变化时会执行这两个钩子函数,但是一般可以通过watch与
Computed`进行监听数据变化,执行相应操作,
官方提到:
注意 updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick 替换掉 updated:
updated: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been re-rendered
})
}
- vue卸载
vm.$destroy()
螚手动触发beforeDestroy
与destroyed
;卸载不是消除页面上的dom,而是解除任何绑定
vue-data
-
data中存放着组件或者vue实例的数据;但是在
new Vue()
时,data则可以直接
写成一个对象,而在组件中时data必须为一个方法,并且return
一个对象,这是为什么呢?
就是必须返回一个独立的对象,防止组件之间相互影响当组件中的data为一个对象时:因为组件时可复用的,父组件A中使用了子组件b,并且对b组件中data的值进行了改变,那么当父组件c再次使用子组件b时也会使用被A改变了的data,这是不合理的,所以在组件中data必须为一个`function`并且返回一个对象
vue-html
<div v-html="html"></div>
data: {
html: '<span>888</span>' //会解析html结构并append进去
}
vue-bind
绑定dom的一些attribute
<div v-bind:class="{active: isActive}"></div> //v-bind可省略
data: {
isActive: true
}
//或者
<div :class="classname"></div>
computed: {
classname () {
return {
active: !this.isActive
}
}
},
computed
,watch
,methods
浅谈区别
-
computed
本质就是get
方法,通常用的就是get
方法去获取数据,该数据不用放在data
中;直接放在computed
中,通过计算通过get
方式获取数据,默认第一次渲染就能获取到,而不用等到重新渲染在获取;(监听多个data数据来get
自己想要数据,不要出现无限循环
)通常形式如下computed: { xx () { return 'xxx' } }
-
watch
通常用于监听data中的数据,有两个参数(new, old)
来改变相应的数据,看起来是一对多,与computed
的多对一有区别;而且默认第一次渲染不刷新;可以手动handle
并且不要改自身监听的属性的值
watch: { xxx (new, old) { .... } } //默认第一次渲染不刷新
watch: { xxx: { handle (new, old) { ... } }, immediate: true, deep: true //深度监听,例如监听obj时其中的元素发生变化,并不会监听到,但是deep为true时则会生效,这样性能开销会大 } //通过handle第一次渲染刷新
所以我们可以使用
字符串形式
,来指定监听obj中的awatch: { 'xxx.a': { //监听xxx对象中的a属性 handle (new, old) { ... } }, immediate: true, } //通过handle第一次渲染刷新
-
methods
与computed
不同,所有数据变化都会执行methods
内的方法
vue原生指令
-
v-text
等价于textContent
,v-html
等价于`innerHTML -
v-show="bool"
就是是否display:none
;v-if
,v-else-if
,v-else
是动态增删dom会消耗性能不推荐使用 v-for
<div id="app">
<ul>
<li v-for="(item, index) in arr" :key="item">{{item}}: {{index}}</li>
</ul>
<ul>
<li v-for="(value, key, index) in obj" :key="key">{{key}}: {{value}} - {{index}}</li>
</ul>
</div>
<script>
Vue.config.devtools = true
const vm = new Vue({
el: '#app',
data: {
msg: 123,
obj: {
'a': 12,
'b': 34
},
arr: [1, 2, 3, 4]
}
})
</script>
-
v-on
绑定事件,当绑定对象不是vue实例时,实际上是使用addEventListener
进行事件添加,若是实例对象则vm.$on()
v-model
<div id="app">
<!-- <comp-one :value="num" @input="num = arguments[0]"></comp-one> -->
<comp-one v-model="num"></comp-one>
<div>{{num}}</div>
</div>
<script>
Vue.config.devtools = true
const component = {
props: ['value'],
template: "<input type='text' :value='value' @input='handleInput'/>",
methods: {
handleInput(e) {
this.$emit('input', e.target.value)
}
}
}
Vue.component('CompOne', component)
const vm = new Vue({
el: '#app',
components: {
CompOne: component
},
data: {
num: 1
}
})
</script>
vue组件
- 创建
- 方法1:全局创建一个组件
const component = {
template: '<span>{{text}}</span>',
data () {
return {
text: 123456
}
}
}
Vue.component('CompOne', component)
const vm = new Vue({
el: '#app',
template: '<comp-one></comp-one>',
})
- 组件内部创建组件
const component = {
template: '<span>{{text}}</span>',
data () {
return {
text: 123456
}
}
}
const vm = new Vue({
el: '#app',
components: {
CompOne: component
},
data: {
arr: [1, 2, 3]
}
})
-
props
属性
通过父组件向子组件传递数据,但props
是单项数据流,不能有子组件进行改变,需要父组件传递一个函数,由父组件来决定怎么改变props
的值
<div id="app">
<comp-one :prop-one="num" :on-change="handleChange"></comp-one>
//<comp-one :prop-one="num" @change="handleChange"></comp-one>
</div>
<script>
Vue.config.devtools = true
const component = {
template: '<span @click="handleClick">{{propOne}}</span>',
props:{
propOne: Number,
onChange: Function //这便可省略用$emit
},
methods: {
handleClick() {
this.onChange()
//this,$emit('change')
}
}
}
Vue.component('CompOne', component)
const vm = new Vue({
el: '#app',
components: {
CompOne: component
},
data: {
num: 1,
},
methods: {
handleChange() {
this.num += 1
}
}
})
</script>
-
extend
属性
const component = {
template: '<span @click="handleClick">{{propOne}}{{text}}</span>',
props:{
propOne: Number,
},
data () {
return {
text: 888
}
},
mounted () {
console.log('component mounted') //先执行
},
methods: {
handleClick() {
// this.onChange()
this.$emit('change')
}
}
}
const compVue = Vue.extend(component) //生成vue子类并拥有组件的属性
//也可通过新建一个组件并继承上个组件属性(extend:component),并new Vue()
new compVue({
el:'#app',
propsData: {
propOne: 12356 //用propsData进行赋值
},
data: {
text: 666 //后覆盖继承组件的data中的值
},
mounted () {
console.log('compVue mounted') //后执行
}
})
vue-插槽
父组件决定放什么内容,子组件决定放哪
- 具名插槽
<div id="app">
<comp-one>
<span slot="body">具名插槽</span>
<span slot="foot" slot-sc>{{value}}</span>
<span slot-scope="props">{{props.value}}作用域插槽</span>
</comp-one>
</div>
<script>
Vue.config.devtools = true;
const component = {
template: `
<div>
<div>
<slot name='body'></slot>
</div>
<div>
<slot name='foot'></slot>
</div>
<div>
<slot :value="value"></slot>
</div>
</div>
`,
data () {
return {
value: 888
}
}
};
const vm = new Vue({
el: "#app",
components: {
CompOne: component
},
data: {
value: 666
}
});
</script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。