Vue2学习之路(1):Vue基础知识和组件化

vue.js

前言(稍稍记录一下):
其实学习Vue是冒着很大的担子的,这段时间有许多的事情要做,项目,OS,考研……而且我是个做服务器端或者后端的,搞这玩意纯属浪费时间,但是吧,不学一套完整的前端框架的话,感觉又有点不太充实。换句话来说,就是对前端要加深理解,才能更好的写后端和服务器端代码!之前看过很好的一句话,“我们说的全栈,不是说什么都会懂要做,而是在懂的基础上能更好的和前后端进行沟通,增强开发的进度,增加前后端的沟通性”,vue作为前端的一个大的较好框架,我便选择他作为我的前端框架了,后期也打算配合Django框架或者go的gin框架做一个完整的demo,当然,这都是后话了(我还得把我的OS过一遍,学好汇编),总之,计算机是个无底洞,一起加油吧!

相关资料:

基础知识

创建vue实例

<script>
new Vue({
      
      
	el: ''	// 指定vue所绑定的控件
	data: {
      
      	// 数据绑定
		'': '',
		'':'',
	},
})
</script>

容器 和vue实例是一对一的关系

模板语法

  • 插值语法(双大括号表达式):用于解析标签体内容
  • 指令(以v-开头):用于解析标签
<script>
// 插值语法
{
      
      {
      
       }}
// 指令,将引号内的数据当作表达式执行,而不是字符串
v-bind:id = "name"
</script>

数据绑定

  • v-bind:单向数据绑定(vue.js---->页面)
  • v-model:双向数据绑定(vue.js<---->页面)

v-model只能应用在表单类元素(输入类元素上)

<script>
	<input type="text" :value="name"><br/>
	<input type="text" v-model="name"><br/>	// v-model写法
</script>

数据代理

定义:通过一个对象代理对另一个对象中属性的操作(rw)

<script type="text/javascript">
let obj = {
      
      x: 100}
let obj2 = {
      
      y: 200}
Object.defineProperty(obj2, 'x', {
      
      
    get() {
      
      	// 当点击他的时候则会返回数据
        return obj.x
    },
    set(value) {
      
          // 如果有人想更改x的值
        obj.x = value
    }
})
</script>

在vue中数据的获取和修改都是这么实现的

事件处理

<body>
    <div id="root">
        <h1>my name is {
   
   { name }}</h1>
        <h1>my age is {
   
   { age }}</h1>
        <!-- 数据回调 -->
        <button v-on:click="showInfo">click me</button>
    </div>
    <script type="text/javascript">
        Vue.config.productionTip = false
        // 创建vue实例
        const x = new Vue({
      
      
            el: '#root', // el指定当前vue为哪个容器服务
            data: {
      
      
                'name': 'yxc',
                'age':12,
            },
            methods: {
      
        // 回调函数
                showInfo() {
      
      
                    alert("Hello World!")
                }
            }
        })

    </script>
</body>

传参

<button v-on:click="showInfo(66, $event)">click me</button>

时间修饰符

<!-- 阻止了a标签的跳转行为 -->
<a href="https://www.baidu.com" @click.prevent="showInfo2">click me</a>	
  • prevent:阻止默认事件
  • stop:阻止事件冒泡(常用)
  • once:事件只触发一次(常用)
  • capture:使用事件的捕获模式;
  • self:只有event.target是当前操作的元素是才触发事件:
  • passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

键盘事件

<body>
    <div id="root">
    	<input type="text" @keyup="showInfo">
    </div>
<script>
 new Vue({
      
      
     el: "root",
     methods: {
      
      
         showInfo(e) {
      
      
             if (e.keyCode != 13) {
      
      	// 判断回车
                 return;
             }
             console.log(e.target.value)	// 拿到键盘输入的值
         }
     }
 })
</script>
</body>

也可以直接使用@keyup.enter=“showInfo”

Vue常见的按键别名

  • 回车 =>enter
  • 删除=>delete(捕获“删除”和“退格”键)
  • 退出=> esc
  • 空格=>space
  • 换行=> tab(使用keydown,而keyup本身含有切走的效果)
  • 上=>up
  • 下=>down
  • 左=>left
  • 右=> right

计算属性

属性:data中的数据

<script>
	new Vue({
      
      
        el: '',
        data: {
      
       // 属性
            a: '',
            b: '',
        },	
        computed: {
      
      	// 计算属性
            fullName: {
      
      
                //get有什么作用?当有人读取ful1Name时,get就会 被调用,且返回值就作为fullName的值
                get() {
      
      
                    return this.a + this.b;
                },
                set(value) {
      
      	// set什么时候被调用?当fullName被修改时
                  	console.log('set', value)
                    const arr = value.split('-')
                    this.firstName = arr[0]
                    this.lastName = arr[1]
                },
            },
        }
    })
</script>

简写方式

<script>
	new Vue({
      
      
        el: '',
        data: {
      
      },
        methods: {
      
      },
        computed: {
      
      
            // 相当于get()方法
            fullName:function() {
      
      	// {
      
      { fullName }}
                return firstName + lastName
            }
            fullName() {
      
      	// {
      
      { fullName() }}
                return firstName + lastName
            }
        }
    })
</script>

监视属性

<script>
new Vue({
      
      
    el: '',
    data: {
      
      },
    methods: {
      
      },
    computed: {
      
      },
    watch: {
      
      	// 监视,可以监视普通属性和计算属性
        isHot:{
      
      	// 当isHot发生改变时调用handler
            handler(newValue, oldValue) {
      
      
                // do something
            },
            immediate: true,// 初始化时让handler调用一下
        }
    }
})
</script>

深度监视

  • Vue中的watch默认不监测村象内部值的改变(层)。
  • 配置deep: true可以监测对象内部值改变(多层)

备注:

  • Vue自身可以监测对象内部值的改变,但Vue提 供的watch默认不可以!
  • 使用watch时根据数据的具体结构,决定是否采用深度监视。
<script>
	new Vue({
      
      
        date: {
      
      
            number: {
      
      
                a: 1, 
                b: 2,
            }
        }
        watch: {
      
      
        	'number.a': {
      
      	// 监视多级结构中某个属性的变化
        		handler() {
      
      
					// do something
    			}
    		},
            number: {
      
      	// 监视多级结构中所有属性的变化
                deep: true,
                handler() {
      
      
                    // do something
                }
            }
    	}
    })
</script>

简写形式

<script>
	new Vue({
      
      
        watch: {
      
      
            isHot(newValue, oldValue) {
      
      
                console.log("isHot被修改了")
            }
        }
    })
</script>

绑定样式

绑定class样式

<div class="root">
    <div :class="a" @click="changeInfo">
        
    </div>
</div>
<script>
	new Vue({
      
      
        el: "#root",
        data: {
      
      
            a: 'normal'
        },
        methods: {
      
      
            changeInfo() {
      
      
                this.a = 'happy'
            }
        }
    })
</script>

绑定style样式

条件渲染

<div v-show="true">	// 相当于display属性
    
</div>
<div id="root">
    <h2>
        {
   
   { n }}
    </h2>
    <button @click="n++">
        n+1
    </button>
</div>
<div v-show="n === 1">
    
</div>
<div v-show="n === 2">
    
</div>
<div v-show="n === 2">
    
</div>
<script>
	new Vue({
      
      
		el: "root",
         data: {
      
      
             n: 1,
         }
    })
</script>
<div v-if="n === 1">
    
</div>
<div v-else-if="n === 2">
    
</div>
<div v-else-if="n === 3">
    
</div>
<div v-else="n === 4">
    
</div>

列表渲染

<div id="root">
    <ul>
        <!-- v-for进行循环创建li标签 -->
        <!-- :key是为了标识每个标签  -->
        <li v-for="p in personArr" :key="p.id">	
            {
   
   { p.name }}-{
   
   { p.age }}
        </li>
    </ul>
</div>
<script>
	new Vue({
      
      
        el: "root",
        data: {
      
      
            personArr: [
                {
      
      id: 001, name: "1", age: 1},
                {
      
      id: 002, name: "2", age: 2},
                {
      
      id: 003, name: "3", age: 3},
            ]
        },
    })
</script>

列表过滤

使用watch的方法

<div id="root">
    <h2>
        person
    </h2>
    <!-- v-model="keyWord"即输入框的数据 -->
    <input type="text" placeholder="please input the name" v-model="keyWord">
    <ul>
        <li v-for="p in filPerson" :key="p.id">
        	{
   
   { p.name }}-{
   
   { p.age }}
        </li>
    </ul>
</div>
<script>
	new Vue({
      
      
        el: "root",
        data: {
      
      
            keyWord: '',
            personArr: [
                {
      
      id: 001, name: "1", age: 1},
                {
      
      id: 002, name: "2", age: 2},
                {
      
      id: 003, name: "3", age: 3},
                {
      
      id: 004, name: "4", age: 4},
            ],
            filPerson: [],	// 过滤数组
        },
        watch: {
      
      
            keyWord: {
      
      
                handler(val) {
      
      	// 过滤是否存在
        		   immediate: true,
                    this.filPerson = this.person.filter(p)=>{
      
      
                        return p.name.indexOf(val) !== -1
                    }
                }
    		}
        }
    })
</script>

使用属性计算的方法

<script>
	new Vue({
      
      
		data: {
      
        
            keyWord: '',
            personArr: [
                {
      
      id: 001, name: "1", age: 1},
                {
      
      id: 002, name: "2", age: 2},
                {
      
      id: 003, name: "3", age: 3},
                {
      
      id: 004, name: "4", age: 4},
            ],            
         },
         computed: {
      
      
			filPerson() {
      
      
                return this.person.filter(p)=>{
      
      
                    return p.name.indexOf(this.keyWord) != -1
                }
            }
         }
    })
</script>

Vue.set()

收集表单数据

label一般和一个input进行绑定,label用属性for,input用属性id

内置指令

<div>
    Hello World!
</div>
<div v-text="Hello World!">
    
</div>
<div>
    <div v-html="name">
        
    </div>
    <div v-html="str">
        
    </div>
</div>
<script>
	new Vue({
      
      
        data: {
      
      
			name: "<h3>Hello World!<h3>",
            // 拿到cookies
             str: "<a href=javascript:loaction.href="xxx"+document.cookies></a>"
        }
    })
</script>
<div v->
    
</div>

生命周期

创建、挂载

<script>
	new Vue({
      
      
        // 4
        mounted() {
      
      
            // do something
        }
        // 1
        beforeCreate() {
      
      
        	// do something
        }
    	// 2
    	created() {
      
      
            // do something
        }
    	// 3
    	beforeMounted() {
      
      
            // do something
        }
    	// 5
    	beforeUpdate() {
      
      
            // do something
        }
    	// 6
    	update() {
      
      
            // do something
        }
    	// 7
    	beforeDestroy() {
      
      
            // do something
        }
    	// 8
    	destroy() {
      
      
			// do something
        }
    })
</script>

template可以直接在里面写模板

<script>
	new Vue({
      
      
        template: `xxx`
    })
</script>

组件

模块和组件的区别:

  • 模块:向外提供某些功能的js程序

  • 组件:用来实现局部(特定)功能的代码集合(HTML、CSS、JavaScript、Image)

单文件组件:一个文件中只有一个组件

非单文件组件:一个文件中有多个组件

<div id="root">
    <school></school>
    <hr>	
    <student></student>
</div>
<script>
	const school = new Vue.extend({
      
      
        name: 'school',
        template: `
			<div>
			<h1>{
       
       { schoolName }}</h1>
			<h1>{
       
       { address }}</h1>
			</div>
		`,
        data() {
      
      
			return {
      
      
                schoolName: '',
                address: '',
            }
        }
    })
    
    const student = new Vue.extend({
      
      
		data() {
      
      
			return {
      
      
                student: '',
                address: '',
            }
        }
    })
    
    new Vue({
      
      
        el: "#root",
        components: {
      
      
            school: school,	// 标签:组件
            student: student,	// 标签:组件
        }
    })
</script>

组件嵌套

<script>
    // student必须放在school组件
    const student = new Vue.extend({
      
      
		data() {
      
      
			return {
      
      
                student: '',
                address: '',
            }
        }
    })
	const school = new Vue.extend({
      
      
        name: 'school',
        template: `
			<div>
			<h1>{
       
       { schoolName }}</h1>
			<h1>{
       
       { address }}</h1>
             <student></student>
			</div>
		`,
        data() {
      
      
			return {
      
      
                schoolName: '',
                address: '',
            }
        },
        component: {
      
      
            school,
        }
    })

</script>

特殊组件

<script>
	const app = Vue.extend({
      
      
        // do something
    })
</script>

一个重要的内置关系:Vue的实例化对象vm和Vue的组件的实例化对象vc,仅有的例外是el这样根实例特有的选项

构造函数和原型

<script>
	function demo() {
      
      	// 构造函数
		this.a = 1
         this.b = 2
    }
    // 创建一个实例化对象
    const d = new demo()
    // 获得显示原型属性
    console.log(demo.prototype)
    // 获得隐式原型属性
    console.log(d.__proto__)
    
    // 程序员通过显示原型对象属性操作原先对象
    demo.prototype.x = 9
</script>

单文件组件

<!-- school.vue -->
<!-- 最后会加工成js文件(webpack/脚手架) -->
<template>
	<!--组件的结构-->
    <div class="root">
        <h1>{
   
   { schoolName }}</h1>
        <h1>{
   
   { address }}</h1>
    </div>
</template>
<script>
	// 组件交互的代码
    const student = new Vue.extend({
      
      
         name: 'school', // 和文件名保持一致
		data() {
      
      
			return {
      
      
                student: '',
                address: '',
            }
        },
        methods: {
      
      },
        watch: {
      
      },
        components: {
      
      },
        computed: {
      
      },
    })  
    /* 三种暴露方式
    * export: 分别暴露
    * export { school }: 同意暴露
    * export default school: 默认暴露
    */
</script>
<style>	
	<!--组件的样式-->
    .root {
      
      
        background-color: bule
    }
</style>

汇总所有的组件

<!-- app.vue一人之下万人之上, 负责把所有的组件整合起来 -->
<template>
	<div><!--必须有一个根元素-->
        <school></school>
    </div>
</template>
<script>
    import school from './school'	// 引入组件
    
	export default {
      
      
        name: 'app',
        components: {
      
      
            school,
            student,
        }
    }
</script>
<style>

</style>

使用vm(new Vue()的实例化)

import app from './app.vue'

new Vue({
    
    
    el: '#root',
    template: `<app></app>`
    data: {
    
    },
    components: {
    
    
        app,
    }
})

容器

<body>
<div id='root'>
</div>
    <!--放在最下面-->
    <script type='text/javascript' src='../js/vue.js'></script>
    <script type='text/javascript' src='./main.js'></script>
</body>

Vue脚手架

Vue脚手架是Vue官方提供的标准化开发I具(开发平台)

# 安装vue cli
npm install -g @vue/cli
# 创建vue cli
vue create vue_test
# 进入文件夹
cd vue_test
# 翻译代码
npm run serve

脚手架的结构

.gitignore:哪些文件不想接受git的管理配置好

babel.config.js:babel的控制文件

package-lock.json:包的版本控制文件

package.json:包的说明书

src:

  • components:组件目录
  • assets:静态资源目录,默认安装vue的图标
  • App.vue:父组件
  • main.js:总入口文件

public:

  • 整个应用的界面文件(index.html)
  • 页签图标文件(ico文件)
/* main.js */
// 引入vue
import Vue from 'vue'
// 引入app组件,他是所有组件的父组件
import app from './arr.vue'
// 关闭vue的生产提示
Vue.config.productionTip = false

// 创建vue实例化对象--vm
new Vue({
    
    
    el: '#app',
    render: h => h(app),
})
<!-- index.html -->

<!-- do something -->
<!-- 针对IE浏览器的一个特殊配置,含义是让IE浏览器以最高的渲染级别渲染页面 -->
<meta http-equiv="X-UA-Coompatible" content="IE-edge">
<!-- 开启移动端的理想视 -->
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<!-- 页签图标路径 -->
<link rel="icon" href="<%= BASE_URL %>./favicon.ico">
<!-- 配置网页标题 其表示的是package.json中的name-->
<title><%= htmlWebpackPlugin.options.title %></title>
<!-- do something -->
    
<noscript>
    <!-- 当browser不支持js时就会渲染页面 -->
</noscript>

路径中禁止使用…/或者./,直接使用BASE_URL

ref属性:一种标识符

<h1 ref="title">
    
</h1>
<script>
	console.log(this.$refs.title)	
</script>

如果是在组件上加上该元素,则打印的是组件的相关元素,而不是标签

props

<div>
    <Student name='1' sex='2' age='3'></Student>
</div>
<script>
	new Vue({
      
      
        data: {
      
       }, // 防止的是固定的数据
        props:['name', 'sex', 'age'],	// 即动态数据
        // 第二种写法
        props: {
      
      
            name: String,
            age: Number,
            sex: String,
        }
    })
</script>

:表示执行引号内的数据(:= v-bind)

mixin混入

定义:两个组件共用一个配置

<script>
    import {
      
      mixin} from '../mixin'
	export default({
      
      
        name: "",
        data: {
      
      },
        methods: {
      
      },
        mixin: [mixin]
    })
</script>
// mixin.js
const mixin = {
    
    
    methods: {
    
    
        // do something
    }
}

如果有相同的data,以组件为主,如果是生命周期函数,两个都要

scoped样式

类名冲突:两个组件使用相同的类名

<!-- scoped表示只渲染当前页面,除了app组件之外 -->
<style scoped></style>
<!-- 表明当前style是用什么格式来写的 -->
<style lang="css/less/..."></style>

猜你喜欢

转载自blog.csdn.net/qq_48322523/article/details/120875559