? 官方 文档 https://cn.vuejs.org/ or vue.js
使用版本 最新稳定版本:2.5.21
https://www.cnblogs.com/liwenzhou/p/9959979.html
下载 vue.js 文件 引入 或使用网络 链接导入
<!--第一步:引入vue,Vue function-->
<script src="./statics/vue.min.js"></script>
<!--网路链接 -->
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
声明领地(Vue实例的作用范围)
使用 id 来定义 作用范围 名字随意
<!--第二步:声明领地(Vue实例的作用范围)-->
<div id="app" >
</div>
创建一个对象(Vue对象)
<script>
// 第三步:创建一个对象(Vue对象)
new Vue()
</script>
查找领地(作用域)
el : ‘#app‘, 查找作用域 app 必须写# 号
<script>
new Vue({
// 第四步:查找领地(作用域)
el: "#app",
data: {
xxxx: "hello world"
}
})
</script>
基本使用
<body>
<!--第二步:声明领地(Vue实例的作用范围)-->
<div id="app">
<p>{{ content + content }}</p> 支持 拼接 字符串
<p>{{ '今晚去我家' }}</p> 直接显示
<p>{{ {'name': "鑫姐" } }}</p> 显示 object 对象
<p>{{ 1 > 2 ? "大于" : "傻逼" }}</p> 三元运算
<p>{{ python + linux }}</p> 数字相加
<p>{{ totalScore }}</p> 函数调用
<p>{{ list }}</p> 显示
</div>
<script>
// 创建一个对象(Vue对象)
new Vue({
// 查找作用域 领地
el: "#app",
// 定义 数据 字典的形式
data: {
content: "hello",
python: 88,
linux: 76,
list: ['抽烟', '喝酒', '烫头'],
},
// 定义方法 函数 尽量不在 页面中做过多的运算
computed: {
// 定义函数
totalScore: function () {
return this.python + this.linux;
},
}
})
</script>
</body>
v-text 渲染文本值
<div id='app' v-text='xxx'></div>
v-html 渲染原始标签
<div id='app' v-html='xxx'></div>
v-for: 处理丰富的数据结构
<div id='app'>
<ul>
<li v-for='(value, index) in list' :key='index'>{{ value }}</li>
</ul>
</div>
v-if, v-else-if, v-else: 判断标签是否显示
实现方式:
? v-if底层采用的是appendChild removeChild 来实现的
<div v-if="boo==='男'">
<p>滚</p>
</div>
<div v-else-if="boo==='女'">
<p>来啦老妹</p>
</div>
<div v-else>
<p>没有美女来吗</p>
</div>
boo 在 data 中定义
v-show:判断标签是否显示
实现方式:
? v-show通过样式的display控制标签的显示
<div v-show="show">
显示
</div>
show:true,
hide:false,
v-if和v-show的性能比较 开销问题
渲染的开销
v-if:低
v-show:高
切换的开销
v-if:appendChild, removeChild 高
v-show:低
一般来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用v-show较好,如果在运行时条件很少改变,则使用v-if较好。
(class,href,src)
简写 :class=‘aaa‘ 绑定
绑定类名
<div v-bind:class="aaa">
</div>
aaa:'box1', box1 为类名 必须通过 data 中的变量传输
bbb:'box2',
<div v-bind:class="{ aaa: boo, box1: 1<2 }">
<!-- 通过判断布尔值 来判断是否设置 此类名
</div>
绑定 href 链接地址
<div v-for="(item, index) in lis_links" :key="index">
<a v-bind:href="item.http"><span>{{item.name}}</span></a>
</div>
boo: true,
lis_links: [
{http: 'http://www.baidu.com', name: '百度'},
{http: 'http://www.jd.com', name: '京东'},
{http: 'http://www.taobao.com', name: '淘宝'},
],
<script v-bind:src="path">
</script>
小结:对于属性的操作,一定是通过动态的数据来进行增加或者删除的
简写 @click=‘function‘
<div id='app'>
<!--给输入框 绑定 回车事件 -->
<input type='text' @keyup.enter='enter' value=''/>
<!--给按钮 绑定 点击事件 -->
<button v-on:click='func' ></button>
</div>
<script>
new Vue({
el: '#app',
data:{},
methods:{
func:function(){
console.log('点击我就会执行')
},
enter:function(){
console.log('回车我就执行!')
},
}
})
</script>
修饰符
// 可以阻止form表单的 默认提交 请求 执行 mySubmit 事件
@click.prevent="mySubmit"
<div id='app'>
<input type='text' v-model='message'/>
<p>
输入的值 : {{ message }}
</p>
</div>
<input type="text" vmodel.number="python">
<input type="text" vmodel.number.lazy="python">
遇到一些复杂的需求,vue提供的指令不能完美的处理,有时候我们需要自定义指令,针对这一需求,vue提供了自定义指令,如下所示:
<div id="app">
<div class="box" v-pos.right.bottom="post"></div>
<input type="text" v-focus="aaa">
</div>
<script>
// directive就是vue实现指令系统的后台的功能函数
Vue.directive("pos", function (el, binddings) {
// console.log(binddings); 自定义 指令 的所有参数
// binddings.value 就是 post 的 值 为 true 通多 vue 实例 数据传递过来的
if (binddings.value) {
// 设置 标签的 属性 style='position: fixed' 绝对定位
el.style.position = "fixed";
// 自定义 指令 v-pos.right.bottom="post" 传递的 属性 样式 right bottom
console.log(binddings.modifiers);
//{right: true, bottom: true} 是一个字典 值默认 为 true
for (let key in binddings.modifiers) {
el.style[key] = 0;
}
} else {
// 如果 判断为空 则 不设置 指令
el.style.position = 'static';
}
});
// 注册 一个全局自定义 指令 v-focus
Vue.directive('focus', {
// 将绑定的元素插入到 DOM 中
inserted: function (el, items) {
// items 自定义 指令 的所有参数
console.log(items.value);
console.log(el, items);
// 聚焦元素
el.focus()
}
});
new Vue({
el: '#app',
data: {
// 自定义 指令的 开关
post: true,
//
aaa: 11111,
}
})
el: ‘#app‘ 查找作用域
data:
data: {
name: 'zhangziyi',
h1: '<h1>zhangziyi</h1>',
lis: ['张', '只', '阿斯蒂芬', '号啊'],
boo: '女',
show: true,
hide: false,
aaa: 'box1',
lis_links: [
{http: 'http://www.baidu.com', name: '百度'},
{http: 'http://www.jd.com', name: '京东'},
{http: 'http://www.taobao.com', name: '淘宝'},
],
},
computed: 计算属性
new Vue({
el:'#app',
data:{
python: 90,
linux: 80,
java: 50,
},
computed: {
sum: function () {
return this.python + this.linux + this.java
}
},
})
watch:侦听属性
watch:{
python:function (v,k) {
console.log(v,k);
console.log('改变成绩');
}
},
? 方法每次都执行
? 计算属性的数据没变就直接使用之前的结果
? 侦听器适用于那些
? 当某个值发生变化之后,我就要做什么事情 这种场景!
? 其他的场景都用计算属性就可以了
计算成绩的Demo
<div id='app'>
<table border="1px">
<thead>
<tr>
<th>科目</th>
<th>成绩</th>
</tr>
</thead>
<tbody>
<tr>
<td>python</td>
<td><input type="text" v-model.number.lazy="python"></td>
</tr>
<tr>
<td>linux</td>
<td><input type="text" v-model.number.lazy="linux"></td>
</tr>
<tr>
<td>java</td>
<td>{{java}}</td>
</tr>
<tr>
<td>总成绩</td>
<td>{{ sum }}</td>
</tr>
</tbody>
</table>
</div>
<script>
new Vue({
el: '#app',
data: {
python: 90,
linux: 80,
java: 50,
},
computed: {
sum: function () {
return this.python + this.linux + this.java
}},
watch:{
python:function (v,k) {
console.log(v,k);
console.log('改变成绩');
}},})
methods:{func_1:function(){-----},} 方法 事件绑定时触发
<style>
.box1{
background-color: red;
}
.box2{
background-color: green;
}
</style>
<div id='app'>
<span :class="aaa">小马哥</span>
<p>
<button v-on:click="color">点击</button>
</p>
</div>
methods: {
// 点击时执行 此方法
color: function () {
if (this.aaa === "box1") {
this.aaa = 'box2'
} else {
this.aaa = 'box1'
}
}
},
$refs
<div id="app">
<div ref="myRef"><h1>小马哥</h1></div>
<button @click="changeColor">点击让小马哥变绿</button>
</div>
<script>
new Vue({
el: "#app",
data: {
post: true
},
methods: {
changeColor: function () {
// $refs 获取 dom 对象 的 myRef
// 标签中 设置 ref='myRef' 的 属性
this.$refs.myRef.style.color = 'green';
}
}
})
</script>
// 通过file来选择需要上传的文件
<input type="file" class="file">
var formData = new FormData() // 声明一个FormData对象
var formData = new window.FormData() // vue 中使用 window.FormData(),否则会报 'FormData isn't definded'
// 'userfile' 这个名字要和后台获取文件的名字一样;
//'userfile'是formData这个对象的键名
formData.append('userfile', document.querySelector('input[type=file]').files[0])
var options = { // 设置axios的参数
url: '请求地址',
data: formData,
method: 'post',
headers: {
'Content-Type': 'multipart/form-data'
}
}
this.axios(options).then((res) => {}) // 发送请求
ES6 中 的常用语法
全局变量 有变量提升的的问题
var a = '11'
局部变量 有作用域的变量
let a = '11'
一般定义常量 不可以改变 值
const AA = '121'
模板字符串
? 用 `` 反引号 在 js 中 写html 便签
单体函数 foo( ){ }
// 单体函数就是指在Object里面定义普通函数的简写形式
let obj = {
foo:function () {
// 原始函数
},
foo(){
// 简写 形式
console.log(this);
},
};
箭头函数 () => {};
function Vue(obj) {
this.foo = obj.foo;
this.bar = obj.bar;
this.foo();
obj.foo();
this.bar();
obj.bar()
}
let obj = {
username: 'zhangziyi',
foo(){
console.log(this);
},
// 箭头函数的this指向调用该函数的对象的父作用域
bar: () => {
console.log(this);
}
};
// 普通函数的this指向调用该函数的对象
// obj.foo();
new Vue(obj);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="static/bootstrap-3.3.7/css/bootstrap.min.css">
</head>
<script src="static/vue.min.js"></script>
<style>
.box {
margin-top: 10px;
/*background-color: #7147ff;*/
}
</style>
<body>
<div id="app">
<div class="container">
<div class="row">
<div class="box col-lg-8 col-lg-offset-2">
<div class="panel panel-primary">
<div class="panel-heading">输入</div>
<div class="panel-body">
<div>
<form action="javascript:void (0)">
<p>输入:>>>{{ message }}</p>
<div class="form-group col-lg-11 pull-left">
<input class="form-control" type="text" v-model="message">
</div>
<button v-on:click="aaa" class="btn btn-sm btn-success">提交</button>
</form>
</div>
</div>
<div class="row">
<div class="col-lg-5 col-lg-offset-1">
<div class="panel panel-default" style="height: 400px;">
<div class="panel-heading">Left</div>
<div class="panel-body">
<ul>
<li v-for="(item,index) in left" :key="index" v-on:click="left_on(index)">
{{item}}
</li>
</ul>
</div>
</div>
</div>
<div class="col-lg-5 ">
<div class="panel panel-default" style="height: 400px;">
<div class="panel-heading">Right</div>
<div class="panel-body">
<ul>
<li v-for="(item,index) in right" :key="index" v-on:click="right_on(index)">
{{item}}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
left: ['左边'],
right: ['右边'],
message: '',
},
methods: {
aaa: function (asss) {
if (this.message) {
this.left.push(this.message);
console.log(111111111111111);
this.message = ''
}
},
left_on: function (index) {
this.right.push(this.left[index]);
this.left.splice(index, 1);
// event.currentTarget.checked = false;
// // 根据索引找到对应的值
// let things = this.left.splice(index, 1)[0]; // []
// this.right.push(things);
},
right_on: function (index) {
this.left.push(this.right[index]);
this.right.splice(index, 1);
},
}
})
</script>
</body>
</html>
实现页面布局的vue的一个非常重要的核心功能
组件只是vue里面的概念,浏览器没有这个概念
组件里面肯定会包含标签
组件里面可能会包含数据
组件里面可能还有事件
综上:组件其实就是一个可复用的Vue实例
声子=》挂子=>用子
Vue.component(组件的名字,{组件实例})
<div id="app">
<my-button></my-button>
<my-button></my-button>
</div>
<script>
Vue.component('my-button', {
template: `<button v-on:click="add">{{ message }}</button>`,
data: function () {
return {
message: 0,
}
},
methods: {
add() {
this.message++
}
}
});
new Vue({
el: '#app',
})
</script>
<div id="app">
<my-button></my-button>
<my-button></my-button>
<my-button></my-button>
</div>
<script>
new Vue({
el: '#app',
// 创建局部组件
components: {
// 注册 局部组件 以及指定名字
'my-button': {
template: `<button v-on:click="add">{{ message }}</button>`,
// 组件中的 data 必须 是 function 返回 对象
data: function () {
return {
message: 0,
}
},
methods: {
add() {
this.message++
}
}
},
}
})
</script>
分开的 写法
let myHeader = {
template: `
<div>
<h1>这是首页</h1>
</div>
`
}
new Vue({
el: "#app",
components: {
// key是自定义的名称,value是创建的局部组件名称
"my-header": myHeader,
}
})
<div id="app">
<my-header></my-header>
</div>
子组件
let myHeader = {
template: `
<div>
<h1>我是导航栏</h1>
</div>
`
}
父组件
let Container = {
// 使用子组件
template: `
<div>
<my-header></my-header>
</div>
`,
// 注册子组件
components: {
"my-header": myHeader
}
}
new Vue({
el: "#app",
components: {
"container": Container
}
})
父-->子 之间的 传递
在父组件中通过v-bind:变量名=‘变量‘
传递数据
在子组件中通过 props
声明需要被接收的参数
<div id="app">
<app-container></app-container>
</div>
<script>
// 1. 在 父组件 里面的 子组件 中绑定一个自定义属性
let Container = {
template: `
<div>
<app-header v-bind:fatherData="info"></app-header>
</div>
`,
data(){
return {
info: "传递的数据!!!"
}
},
components: {
'app-header': Header,
}
};
// 2. 在子组件中使用props接收这个数据
let Header = {
template: `
<div>
{{ fatherData }}
</div>
`,
props: ['fatherData'],
data(){
return {
name:"hahaha",
}
}
};
new Vue({
el: '#app',
components: {
'app-container': Container
}
})
</script>
子--> 父 组件之间的数据传递
抛出的事件(不推荐直接在组件里修改根实例的数据)
子组件中通过 $emit
(‘自定义事件名‘) 向外抛出自定义事件
父组件中用过 v-on:自定义事件名=动作函数
监听子组件抛出的事件
<div id="app">
<app-container></app-container>
</div>
<script>
// 1. 在子组件中使用this.$emit("change-size", 1) 抛出一个自定义事件
let Header = {
template: `
<div>
<button v-on:click="changeSize">点击修改父组件的字体大小</button>
</div>
`,
methods: {
changeSize: function () {
// 第一个参数是 自定义事件的 名称 第二个参数是 要传递的 内容
// 从 父组件的 事件 函数中 接受
this.$emit("change-size", 1);
}
}
};
// 2. 在父组件的子组件中绑定抛出的自定义事件
let Container = {
template: `
<div>
<app-header v-on:change-size="add"></app-header>
<span :style="{ fontSize: Size + 'px' }">苦海</span>
</div>
`,
data(){
return {
Size: 26,
}
},
methods:{
add:function(data){
consol.log(data)
this.Size++
}
}
components: {
'app-header': Header,
}
};
new Vue({
el: '#app',
components: {
'app-container': Container
}
})
借助一个空的Vue对象实现组件间通信
let bus = new Vue(); // 大项目用这个 VueX 保存数据
传值的那个组件:
let B = {
template: `
<div>
<h1>这是 子组件: my-mjj </h1>
<button v-on:click="add">选我</button>
</div>
`,
data(){
return {
num: 0
}
},
methods: {
add(){
this.num += 1;
// 利用bus对象抛出一个自定义事件
bus.$emit('xuanwo', this.num);
}
}
};
接收值的那个组件:
let A = {
template: `
<div>
<h1>这是 子组件: my-alex </h1>
<p>my-mjj被选中的次数:{{ num }}</p>
</div>
`,
data() {
return {
num: 0
}
},
mounted(){
// 在文档准备就绪之后就要开始监听bus的事件 bus.$on 是否触发了 xuanwo 的事件
bus.$on('xuanwo', (val)=> { // val 就是传递的参数
// this.num += 1; // ?
console.log(val);
console.log(this); // this 是组件A
this.num = val;
})
}
};
? vue 中的 代码 重复 问题
? mixins:[xxx,xxxx] 组件中 定义 将重复 的 内容提取 可设置多个
let xxxx = {
methods: {
show: function (name) {
console.log(`${name}`);
},
hide: function (name) {
console.log(`${name}`);
}
}
};
let xiaoMa = {
template: `
<div>
<button v-on:click="show('xiaoma_show')">欢迎小马哥过来视察工作</button>
<button v-on:click="hide('xiaoma_hide')">欢迎小马哥下次再来</button>
</div>
`,
mixins: [xxxx,]
};
let chaoGe = {
template: `
<div>
<button v-on:click="show('chaoge_show')">欢迎超哥过来视察工作</button>
<button v-on:click="hide('chaoge_hide')">欢迎超哥下次再来</button>
</div>
`,
mixins: [xxxx]
};
new Vue({
el: "#app",
components: {
'xiaoma': xiaoMa,
'chaoge': chaoGe
}
})
<slot></slot>
? 在 组件的模板中定义
<div id="app">
<global-component>首页</global-component>
<global-component>免费课程</global-component>
<global-component>轻课</global-component>
<global-component>学位课程</global-component>
<global-component>智能题库</global-component>
</div>
<script>
Vue.component('global-component', {
template: `
<div >
<div class="box"><slot></slot></div>
</div>
`,
});
new Vue({
el: "#app",
})
</script>
用在组件中,有一些特殊的需求
定义组件
let AlertBox = {
template: `<div>
<div class="title"><slot name='title'> Error! </slot></div>
<div class="title"><slot>...</slot></div>
<div class="text"><slot name='text'> 出错了!!</slot></div>
</div>`, // 必须包含在闭合标签那种
}
注册组件
let APP = new Vue({
el: '#app',
compoments: {
"alert-box": AlertBox,
}
})
使用组件
<div id="app">
<alert-box>
<template slot="title">报错: 只在定义的 name='title' 的插槽中显示 </tempalte>
<span slot='text'>覆盖之前插槽中的内容</span>
</alert-box>
<alert-box>没有指定插销的内容 统一在 原始slot 插槽中 显示</alert-box>
<alert-box/>
</div>
from functools import reduce
data = [
{'num': 10, 'name': '苹果'},
{'num': 3, 'name': '香蕉'},
{'num': 1, 'name': '草莓'},
{'num': 12, 'name': '橙子'},
]
# 求data中所有水果总数 0 是X 的默认值
ret3 = reduce(lambda x, y: x+y['num'], data, 0)
print(ret3)
<script>
let data = [
{'num': 10, 'name': '苹果'},
{'num': 3, 'name': '香蕉'},
{'num': 1, 'name': '草莓'},
{'num': 12, 'name': '橙子'},
];
/*
let ret = data.reduce(function (x,y) {
return x+y.num
}, 0);
*/
let ret = data.reduce((x,y) =>{
return x+y.num
}, 0);
console.log(ret)
</script>
8个钩子函数 (Hook)
常用 :
created: 多用来ajax从后端获取数据
mounted: 文档已经渲染完毕,绑定事件!
let app = new Vue({
el: '#app',
data: {
name: 'Alex'
},
// template: `<div class="s16">嘿嘿嘿</div>`,
beforeCreate(){
// 在创建实例之前,data只声明但没有赋值
console.log(this.name);
console.log('------ beforeCreate -------');
},
created(){
// 创建实例之后
console.log(this.name);
console.log('------ created -------');
},
// 挂载
beforeMount(){
// 在挂载DOM之前
console.log(document.getElementById('app'));
console.log('------ beforeMount -------');
},
mounted(){
// 挂载DOM
console.log(document.getElementById('app'));
console.log('------ mounted -------');
},
// 更新操作
beforeUpdate(){
console.log('准备要更新,但是还没有更新');
console.log('------ beforeUpdate -------');
},
updated(){
console.log('更新完成了');
console.log('------ updated -------');
},
})
<!-- 调用父组件的原生事件 native 原生的 -->
<button v-on:click.native="show"></button>
父组件 -> 子组件
? 在子组件中 通过 props声明 需要被传递的数据
? 在父组件中 通过 v-bind:name="值"
传递数据
子组件 -> 父组件
? 在子组件通过 $emit(自定义事件)
向外抛出事件
? 在父组件通过 v-on:自定义事件
触发执行自己的事件
子组件1-> 子组件2
? 在组件1中 通过公用的 Vue对象 bus
抛出自定义事件 bus.$emit(‘自定义事件‘, 数据)
? 在子组件2中的 mounted
方法中 给 bus 绑定监听事件 bus.$on(‘自定义事件‘, (val)=>{...})
原文:https://www.cnblogs.com/zhang-zi-yi/p/10800598.html