前言
Vue脚手架工具vue-cli学习笔记
安装脚手架工具
查看版本号
创建一个项目
<name>
:项目名
1 2
| vue create <name> cd <name>
|
基本命令
运行项目
构建项目
验证项目
项目结构
···
- node_modules
- public
- src 项目源码
- .gitignore
- babel.config.js
- package.json
- package-lock.json
- README.md
···
vue组件
vue组件结构
- 所有的vue组建都是
.vue
结尾的文件
App.vue
是所有组件的根组件
template
:结构
script
:逻辑
style
:样式
1 2 3 4 5 6 7 8 9 10 11 12 13
| <template>
</template>
<script> export default { name: "" } </script>
<style scoped>
</style>
|
渲染数据
- 最外层必须有默认暴露,vue的对象清单都必须在
export default
里面去罗列
- 在vue组件中,为了防止javascript数据污染,data不可以是对象,而是一个函数返回一个对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <template> <div id="app"> {{num}} </div> </template>
<script> export default { data: function() { return { num: 100 } } } </script>
<style scoped>
</style>
|
引入组件
- 引入组件
- 注册组件
- 调用组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <template> <div> <Hello/> </div> </template>
<script>
import Hello from "./components/Hello";
export default { components: { Hello } } </script>
<style scoped>
</style>
|
定义自定义函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <template> <div> <h1>{{num}}</h1> <button v-on:click="add">+</button> </div> </template>
<script> export default { name: "Hello", data: function() { return { num: 0 } }, methods: { add() { this.num++; } } } </script>
<style scoped>
</style>
|
native修饰器
- 原生的事件监听在vue组件中不生效,需要在原生事件监听后添加后缀
.native
来使原生事件监听生效
Father.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <template> <div> <Son @click.native="click"></Son> </div> </template>
<script> import Son from "./Son";
export default { name: "Father", components: { Son }, methods: { click() { console.log("事件监听"); } } } </script>
<style scoped>
</style>
|
Son.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <div> <button>+</button> <Grandson></Grandson> </div> </template>
<script> import Grandson from "./Grandson";
export default { name: "Son", components: { Grandson } } </script>
<style scoped>
</style>
|
父子组件传值
- 父组件通过
v-bind:自定义属性
传值
- 如果父组件传值需要用驼峰命名,需要使用
-
来代替,子组件接收时使用驼峰命名接收
- 子组件通过props接收对应的参数,并在双大括号内直接通过自定义参数名调用
- 子组件接收的可以是数组,也可以是对象
父组件传递给子组件值
父组件传值
App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <template> <div> <Hello v-bind:value-a="num"></Hello> </div> </template>
<script> import Hello from "./components/Hello";
export default { components: { Hello }, data: function() { return { num: 100 } } } </script>
<style scoped>
</style>
|
子组件接收为数组
Hello.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <div> <h1>父组件传递过来的值是{{valueA}}</h1> </div> </template>
<script> export default { name: "Hello", props: ["valueA"] } </script>
<style scoped>
</style>
|
子组件接收为数对象
Hello.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <template> <div> <h1>父组件传递过来的值是{{valueA}}</h1> </div> </template>
<script> export default { name: "Hello", props: { valueA: Number } } </script>
<style scoped>
</style>
|
配置参数为必传项
type
:定义类型
require
:true开启必传值校验,如果未接收到传值,控制台会报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <div> <h1>父组件传递过来的值是{{valueA}}</h1> </div> </template>
<script> export default { name: "Hello", props: { valueA: { type: Number, require: true } } } </script>
<style scoped>
</style>
|
配置参数默认值
- 如果默认值是一个对象或数组,需要以函数和返回值的形式定义
defaule
:接收不到传值的默认值。一般不和require混用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <template> <div> <h1>父组件传递过来的值(默认值)是{{valueA.num}}</h1> </div> </template>
<script> export default { name: "Hello", props: { valueA: { type: Object, default: function() { return { num: 100 } } } } } </script>
<style scoped>
</style>
|
配置参数校验
validator
:传值的手动校验,如果校验结果为false,则会在控制台报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <template> <div> <h1>父组件传递过来的值是{{valueA}}</h1> </div> </template>
<script> export default { name: "Hello", props: { valueA: { type: Number, validator: function(value) { return value>50 } } } } </script>
<style scoped>
</style>
|
子组件修改父组件值
- 子组件不可以直接修改父组件的值
- 子组件通过触发事件,调用
this.$emit("自定义事件名")
,向父组件传递事件被触发
- 父组件通过接收到子组件被触发,从而触发自己的事件,来激活自己的函数
子组件向父组件传递事件触发
Hello.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <template> <div> <button v-on:click="add">+</button> </div> </template>
<script> export default { name: "Hello", methods: { add() { this.$emit("a"); } } } </script>
<style scoped>
</style>
|
父组件接收到子组件事件被触发
App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <template> <div> <h1>{{num}}</h1> <Hello v-on:a="add"></Hello> </div> </template>
<script> import Hello from "./components/Hello";
export default { components: { Hello }, data: function() { return { num: 0 } }, methods: { add() { this.num++; } } } </script>
<style scoped>
</style>
|
watch监听数据变化
非对象数据
- 通过watch对象中对应的以数据名命名的函数,得到新数据和旧数据,实现监听数据
newVal
:新数据
oldVal
:旧数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <template> <div> <h1>{{num}}</h1> <button v-on:click="add">+</button> </div> </template>
<script>
export default { data: function() { return { num: 0 } }, methods: { add() { this.num++; } }, watch: { num: function(newVal, oldVal) { console.log(newVal); console.log(oldVal); } } } </script>
<style scoped>
</style>
|
对象数据(某个属性)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| <template> <div> <h1>{{obj.age}}</h1> <button v-on:click="add">+</button> </div> </template>
<script>
export default { data: function() { return { obj: { age: 16 } } }, methods: { add() { this.obj.age++; } }, watch: { "obj.age": function(newVal, oldVal) { console.log(newVal); console.log(oldVal); } } } </script>
<style scoped>
</style>
|
对象数据(整个对象)
- 如果需要页面初始化就能触发一次监听,必须使用handler函数
- 监听复杂数据只能在页面初始化监听一次
immediate
:true表示开启初始化时监听
handler
:监听函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <template> <div> <h1>{{obj.age}}</h1> <button v-on:click="add">+</button> </div> </template>
<script>
export default { data: function() { return { obj: { age: 16 } } }, methods: { add() { this.obj.age++; } }, watch: { "obj": { handler(val) { console.log(val); }, immediate: true } } } </script>
<style scoped>
</style>
|
计算属性
- 计算属性(computed)和普通函数(methods)的区别:计算属性利用缓存,如果要重复渲染相同的函数,不会重复渲染
字符串反转
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <template> <div> <h1>{{reverseStr}}</h1> </div> </template>
<script>
export default { data: function() { return { str: "Hello" } }, computed: { reverseStr() { return this.str.split("").reverse().join(""); } } } </script>
<style scoped>
</style>
|
实例属性
$attrs
- $attrs可以从父组件接收到非props接收到的值
- $attrs可以多级子孙传递
- 如果父组件和子组件都传递给孙子组件相同的$attrs,那么子组件会覆盖父组件的$attrs
Father.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <template> <div> <Son :name="name" :age="age" :sex="sex"></Son> </div> </template>
<script> import Son from "./Son";
export default { name: "Father", components: { Son }, data: function() { return { name: "张三", age: 50, sex: "男" } } } </script>
<style scoped>
</style>
|
Son.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <template> <div> <Grandson v-bind="$attrs" :age="age"></Grandson> </div> </template>
<script> import Grandson from "./Grandson";
export default { name: "Son", components: { Grandson }, data: function() { return { age: 25 } } } </script>
<style scoped>
</style>
|
Grandson.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <template> <div>
</div> </template>
<script> export default { name: "Grandson", created() { console.log(this.$attrs) } } </script>
<style scoped>
</style>
|
$listeners
- $linteners可以从父组件接收到非native修饰器接收到的事件监听
- $linteners也可以多级子孙传递
Father.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <template> <div> <Son @cli="cli"></Son> </div> </template>
<script> import Son from "./Son";
export default { name: "Father", components: { Son }, methods: { cli() { console.log("事件监听"); } } } </script>
<style scoped>
</style>
|
Son.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <div> <button>+</button> <Grandson v-on="$listeners"></Grandson> </div> </template>
<script> import Grandson from "./Grandson";
export default { name: "Son", components: { Grandson } } </script>
<style scoped>
</style>
|
Grandson.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <template> <div>
</div> </template>
<script> export default { name: "Grandson", created() { console.log(this.$listeners); } } </script>
<style scoped>
</style>
|
$refs
- $refs包含了当前组件的所有DOM和函数
- 先在子组件上定义ref属性,再通过$refs调用子组件的函数
- 如果ref对象不是一个自定义组件而是一个普通元素,返回的就是该元素本身
Father.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <template> <div> <Son ref="child"></Son> <button @click="click">+</button> </div> </template>
<script> import Son from "./Son";
export default { name: "Father", components: { Son }, methods: { click() { this.$refs.child.add(); } } } </script>
<style scoped>
</style>
|
Son.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <template> <div> <h1>{{num}}</h1> </div> </template>
<script>
export default { name: "Son", data: function() { return { num: 100 } }, methods: { add() { this.num++; } } } </script>
<style scoped>
</style>
|
$el
- 通过ref获取子组件,再通过el获取子组件的根节点,从而实现css的修改
Father.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <template> <div> <Son ref="child"></Son> <button @click="click">+</button> </div> </template>
<script> import Son from "./Son";
export default { name: "Father", components: { Son }, methods: { click() { this.$refs.child.$el.style="color: red"; } } } </script>
<style scoped>
</style>
|
Son.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <div> <h1>{{num}}</h1> </div> </template>
<script>
export default { name: "Son", data: function() { return { num: 100 } } } </script>
<style scoped>
</style>
|
混入
- 把共性的js抽离出来,在需要调用的组件中引入
- 如果组件中的函数和js中的函数重名,组建中的函入会覆盖js中的函数
- 如果组件中和js中都有created函数,会先执行js中的created,后执行组件中的created,不会覆盖
a.js
1 2 3 4 5 6 7 8 9 10 11 12
| export const a = { data() { return { num: 0 } }, methods: { add() { this.num++; } } }
|
Father.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <template> <div> <h1>{{num}}</h1> <button @click="add">+</button> </div> </template>
<script> import {a} from "../a.js"
export default { name: "Father", mixins: [a] } </script>
<style scoped>
</style>
|
完成
参考文献
哔哩哔哩——Python小清风