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>