视频资源来自:b站coderwhy王红元老师——最全最新Vue、Vuejs教程,从入门到精通
文件仅为个人观看视频后的学习心得笔记,用于个人查看和记录保存。文中定有疏漏错误之处,恳请指正。
目录:
邂逅Vuejs
Vue基础语法
组件化开发
前端模块化
webpack详解
Vue CLI详解
vue-router
Promise的使用
Vuex详解
网络模块封装
项目实战
组件化开发
认识组件化
组件化是Vue.js中的重要思想,提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。
注册组件
组件的使用分成三个步骤:
①创建组件构造器
②注册组件
③使用组件
反单引号可以自由换行:
a = `asdas
dads`
<div id="app">
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
//1.创建组件构造器对象
const cpnC = Vue.extend({
template: `
<div>
<h2>我是标题</h2>
<p>我是内容</p>
<p>内容是我</p>
</div>
`
})
//2.注册组件
Vue.component('my-cpn',cpnC)
必须放在vue实例中才能实现
组件其它补充
全局组件和局部组件
全局组件:意味着可以在多个Vue的实例下面使用
<script>
const cpnC = Vue.extend({
template: `
<div>
<h2>我是标题</h2>
<p>我是内容</p>
</div>
`
})
/*全局组件*/
Vue.component('cpn',cpnC)
const app=new Vue({
el: '#app',
data: {
message: '你好啊'
},
/*局部组件*/
components: {
cpn: cpnC
}
})
</script>
父组件和子组件
<div id="app">
<cpn2></cpn2>
</div>
<script src="../js/vue.js"></script>
<script>
const cpnC1 = Vue.extend({
template: `
<div>
<h2>我是标题1</h2>
<p>我是内容1</p>
</div>
`
})
const cpnC2 = Vue.extend({
template: `
<div>
<h2>我是标题2</h2>
<cpn1></cpn1>
<p>我是内容2</p>
</div>
`,
components: {
cpn1: cpnC1
}
})
const app=new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn2: cpnC2,
}
})
</script>
这里,cpn1是子组件,cpn2是父组件
注册组件的语法糖写法
全局组件:
Vue.component('cpn1',{
template: `
<div>
<h2>我是标题1</h2>
<p>我是内容1</p>
</div>
`
})
局部组件:
const app=new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
'cpn2': {
template: `
<div>
<h2>我是标题1</h2>
<p>我是内容1</p>
</div>
`
}
}
})
组件模板的分离写法
<template id="cpn">
<div>
<h2>{{title}}</h2>
<p>我是内容</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
Vue.component('cpn',{
template: '#cpn',
data(){
return {
title: 'abc'
}
}
})
组件数据存放
组件中不能直接访问vue实例中的data
<template id="cpn">
<div>
<h2>当前计数:{{counter}}</h2>
<button @click="add">+</button>
<button @click="sub">-</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
Vue.component('cpnc',{
template: '#cpn',
data(){
return {
counter: 0
}
},
组件模板的{{}}必须用自己的data数据,而不是顶层vue
组件对象也有data属性,但必须是一个函数。
为什么?
<div id="app">
<cpnc></cpnc>
<cpnc></cpnc>
<cpnc></cpnc>
</div>
<template id="cpn">
<div>
<h2>当前计数:{{counter}}</h2>
<button @click="add">+</button>
<button @click="sub">-</button>
</div>
</template>
这个三个cpnc数据不共享,因为data是函数。数据独立
父子组件通信
父传子(props)
properties属性
实际开发中,一般是服务器给大组件数据,小组件不请求(压力大)
<div id="app">
<cpn :cmovies="movies" :cmessage="message"></cpn>
</div>
<template id="cpn">
<div>
<p>{{cmovies}}</p>
<h2>{{cmessage}}</h2>
</div>
</template>
↑一定要v-bind,否则就把message当成字符串了
props: ['cmovies','cmessage'],
props,数组写法↑
props,对象写法↓
const cpn ={
template: '#cpn',
props: {
cmessage:{
type: String,
default: 'aaaaaa',
requires: true
},
cmovies: {
type: Array,
default: []
}
}
}
const app=new Vue({
el: '#app',
data: {
message: '你好啊',
movies: ['海王','海贼王','海尔兄弟']
},
components: {
cpn
}
})
requires: true ——必传值
还可以传对象(用函数写)、自定义验证函数
props 用驼峰标识 iLoveYou
html 类型属性不区分大小写,- - -命名法。cInfo可以写作c-info
子传父(自定义事件)
子组件 $emit 发射事件
父组件 v-on
<div id="app">
<cpn v-on:item-click="cpnClick"></cpn>
</div>
<template id="cpn">
<div>
<button v-for="m in categories"
v-on:click="btnClick(m)">
{{m.name}}
</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn={
template: '#cpn',
data() {
return {
categories: [
{id:'aaa',name: '热门推荐'},
{id:'bbb',name: '手机数码'},
{id:'ccc',name: '家用家电'},
]
}
},
methods: {
btnClick(item) {
this.$emit('item-click',item);
}
}
}
const app=new Vue({
el: '#app',
data: {
},
components: {
cpn
},
methods: {
cpnClick(itemm){
console.log('cpnnn',itemm);
}
}
})
</script>
结合双向绑定案例
num = parseInt(value)
num = parseFloat(value)
将数据转成number型
props: {
number1:Number,
},
data(){
return{
dnumber1:this.number1,
}
},
父组件传过来的值不可更改,必须用data把父组件数据拷贝一次后才能更改。
若想父组件跟着子组件改,用v-model双向绑定的例子。@input="函数"
watch实现
父子组件的访问
父子组件的访问方式$children、$refs (reference 引用)
子访问父 $parent、$root
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn ref="aaa"></cpn>
<button @click="btnClick">按钮</button>
</div>
<template id="cpn">
<div>
<h2>我是子组件</h2>
</div>
</template>
console.log(this.$children);
for(let c of this.$children){
console.log(c.name);
c.showMessage();
}
↑用$children,当有好几个子组件的时候,还可以依次访问。但是数组只能用1、2、3来标识,可能会指示不清。可以用$refs
↓在html标签上加上ref="aaa"
,相当于key,aaa是给这个子组件取的名字。用$refs访问。
console.log(this.$refs.aaa.name)
实际中,$refs用得多
用$parent,子组件与父组件耦合度太高,复用性低
而this.$root.message 直接访问vue实例
slot的使用
基本使用
<div id="app">
<cpn></cpn>
<cpn><span>哈哈哈</span></cpn>
<cpn><i>111</i></cpn>
</div>
<template id="cpn">
<div>
<h2>我是标题</h2>
<p>我是组件</p>
<slot><button>按钮</button></slot>
</div>
</template>
因为只有一个插槽,如果写得多了,就全部替换
<slot></slot>里的是默认显示
具名插槽
<div id="app">
<cpn>
<span slot="center">标题</span>
<button slot="right">返回</button>
</cpn>
</div>
<template id="cpn">
<div>
<slot name="left"><span>左边</span></slot>
<slot name="center"><span>中间</span></slot>
<slot name="right"><span>右边</span></slot>
</div>
</template>
编译的作用域
<!--vue实例作用域-->
<div id="app">
<cpn v-show="isShow"></cpn>
</div>
<!--字组件作用域-->
<template id="cpn">
<div>
<h2>我是标题</h2>
<p>我是内容</p>
<button v-show="isShow">按钮</button>
</div>
</template>
作用域插槽
父组件替换插槽的标签,但是内容由子组件来提供
<div id="app">
<cpn></cpn>
<cpn>
<template slot-scope="aaa">
<span v-for="item in aaa.ddd">{{item}} - </span>
</template>
</cpn>
<cpn>
<template slot-scope="aaa">
<span>{{aaa.ddd.join(' - ')}}</span>
</template>
</cpn>
</div>
<template id="cpn">
<div>
<slot :ddd="languages">
<ul>
<li v-for="m in languages">{{m}}</li>
</ul>
</slot>
</div>
</template>
this.languages.join('-')
:用 - 作为字符串间的连接