发布于:2019-06-28 22:52
- Vue入门 使用Typora打开
- vue中文官网教学 安装与使用,我也经常看这个
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架
谷歌浏览器安装vue插件
- GitHub搜索IMI-SOURCE-CODE,下载第一个crx的文件
- 把.crx改.rar,再解压到一个文件夹,然后开发者模式添加
生命周期
初步操作
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--vue对象的html模版-->
<div id="app">
<!--双向绑定,v-model对应的值是数据模型-->
<input type="text"v-model="num">
<!--v-on:事件名=js表达式-->
<!--<input type="button" value="点击增加一位马仔" v-on:click="num++">-->
<input type="button" value="点击增加一位马仔" v-on:click="incr">
<!--两对大括号:js表达式,例如{{1+1}} 就是2-->
<h1>大家好,我是{{name}},手下有{{num}}位马仔</h1>
</div>
</body>
<!--引入vue.js-- 不要用"/>" 必须用"></script>"-->
<script src="node_modules/vue/dist/vue.js"></script>
<script>
//初始化一个vue实例
const app=new Vue({
el:"#app",//el即element,选择器
data:{//定义数据模型
name:"陶攀峰",
num:100
},
methods:{//定义方法
incr(){
//this表示Vue实例中的数据,可以this.属性 this.方法
this.num++;
}
}
});
</script>
</html>
created() mounted()
created()
视图渲染前,还没有形成HTMLmounted()
视图已经渲染,已形成HTML
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--vue对象的html模版-->
<div id="app">
<!--双向绑定,v-model对应的值是数据模型-->
<input type="text" v-model="num">
<!--v-on:事件名=js表达式-->
<!--<input type="button" value="点击增加一位马仔" v-on:click="num++">-->
<input type="button" value="点击增加一位马仔" v-on:click="incr">
<!--两对大括号:js表达式,例如{{1+1}} 就是2-->
<h1>大家好,我是{{name}},手下有{{num}}位马仔</h1>
</div>
</body>
<!--引入vue.js-- 不要用"/>" 必须用"></script>"-->
<script src="node_modules/vue/dist/vue.js"></script>
<script>
//初始化一个vue实例
const app = new Vue({
el: "#app",//el即element,选择器
data: {//定义数据模型
name: "陶攀峰",
num: 100
},
methods: {//定义方法
incr() {
//this表示Vue实例中的数据,可以this.属性 this.方法
this.num++;
}
},
created() {
//ajax
//可以覆盖data中的数据
this.num = 1801957499
},
mounted() {
//可以覆盖之前的created中数据
this.num=1801
}
});
</script>
</html>
数据使用
花括号
格式{{表达式}}
该表达式支持JS语法,可以调用js内置函数(必须有返回值)
表达式必须有返回结果。例如 {{1 + 1}},没有结果的表达式不允许使用,如:{{var a = 1 + 1}};
可以直接获取Vue实例中定义的数据或函数,使用函数{{方法名()}},使用属性{{属性名}}
单项绑定:v-text,v-html
<h1 v-text="vtext"></h1>
<h1 v-html="vhtml"></h1>
data: {//定义数据模型
vtext:"<p style='color: red'>这是测试v-text</p>",
vhtml:"<p style='color: red'>这是测试v-html</p>"
}
双向绑定:v-model
- v-model的可使用的元素
- input
- select
- textarea
- checkbox
- radio
- components(Vue中的自定义组件)
- 对应类型
- 多个checkbox对应一个model时,model的类型是一个数组,单个checkbox值默认是boolean类型
- radio对应的值是input的value值
- text和textarea默认对应的model是字符串
- select单选对应字符串,多选对应也是数组
- 测试
...
<div id="app">
<input type="checkbox" value="ios" v-model="language">ios<br>
<input type="checkbox" value="java" v-model="language">java<br>
<input type="checkbox" value="php" v-model="language">php<br>
您选择了:{{language}}<br>
您选择了:{{language.join(',')}}<br>
</div>
...
...
const app = new Vue({
el: "#app",
data: {
language: []
}
});
...
v-on
语法
v-on:事件名="js片段或函数名"
v-on:click
<div id="app">
<!--事件中直接写js片段-->
<button v-on:click="num++">增加一个</button><br/>
<!--事件指定一个回调函数,必须是Vue实例中定义的函数-->
<button v-on:click="decrement">减少一个</button><br/>
<h1>有{{num}}个女神迷恋峰哥</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
num:100
},
methods:{
decrement(){
this.num--;
}
}
})
</script>
v-on:contextMenu
- 指令后缀
.stop
阻止事件冒泡到父元素.prevent
阻止默认事件发生.capture
使用事件捕获模式.self
只有元素自身触发事件才执行。(冒泡或捕获的都不执行).once
只执行一次
.prevent
演示
<div id="app">
<!--右击事件,并阻止默认事件发生-->
<button v-on:contextmenu.prevent="num++">增加一个</button>
<br/>
<!--右击事件,不阻止默认事件发生-->
<button v-on:contextmenu="decrement($event)">减少一个</button>
<br/>
<h1>有{{num}}个女神迷恋峰哥</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data: {
num: 100
},
methods: {
decrement(ev) {
//用也可以禁用默认事件,不会显示右击菜单 ev.preventDefault();
this.num--;
}
}
})
</script>
v-on:keyup
- enter 回车调用submit方法代码
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">
- 事件类型,对应键盘字母
- .enter
- .tab
- .delete (捕获“删除”和“退格”键)
- .esc
- .space
- .up
- .down
- .left
- .right
- .13 等于.enter
- .65表示a按键
- .66表示b按键,以此类推
- 组合件按钮,对应按键
- .ctrl
- .alt
- .shift
<!-- Alt + C 因为65是a 66是b 67为c 依次类推 -->
<input @keyup.alt.67="clear">
<!-- Alt + C -->
<input @keyup.alt.c="clear">
<!-- Ctrl + Click 也就是Ctrl加上鼠标左键点击 -->
<div @click.ctrl="doSomething">Do something</div>
v-for
遍历数组
- 语法
v-for="元素别名 in 数组名"
角标从0开始
<div id="app">
<ul>
<li v-for="user in users">
{{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
users:[
{name:'大牛', gender:'女', age: 11},
{name:'二蛋', gender:'男', age: 36},
{name:'三驴', gender:'女', age: 24},
{name:'四毛', gender:'女', age: 98},
{name:'五虎', gender:'女', age: 29}
]
},
});
</script>
- 数组角标语法
v-for="(元素别名,角标别名) in 数组名"
角标从0开始
<ul>
<li v-for="(user,aaa) in users">
{{aaa}}---{{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>
遍历对象
- 语法
v-for="(value别名,key别名,角标别名) in 对象名"
<div id="app">
<ul>
<li v-for="(value1, key1, index1) in daniu">
{{index1 + 1}}. {{key1}} - {{value1}}
</li>
</ul>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
daniu:
{name:'大牛', gender:'女', age: 11}
}
});
</script>
- key 标注一个key数组索引,唯一,可以让你读取vue中的属性,并赋值给key属性
<li v-for="(value1, key1, index1) in daniu" :key=index1></li>
v-if,v-show
<div id="app">
<button v-on:click="show=!show">点我呀</button><br>
<h1 v-if="show">我是v-if</h1>
<h1 v-show="show">我是v-show</h1>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
show: true
}
});
</script>
- 默认显示
- 点击一下
- 点击两下
- v-if与v-for并用
<div id="app">
<ul>
<li v-for="user in users" v-if="user.gender=='女'&&user.age>25">
{{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
users:[
{name:'大牛', gender:'女', age: 11},
{name:'二蛋', gender:'男', age: 36},
{name:'三驴', gender:'女', age: 24},
{name:'四毛', gender:'女', age: 98},
{name:'五虎', gender:'女', age: 29}
]
},
});
</script>
v-if与v-else-if与v-else结合
<div id="app">
<button v-on:click="random=Math.random()">点我呀</button><span>{{random}}</span>
<h1 v-if="random >= 0.75">看到我啦?!if</h1>
<h1 v-else-if="random > 0.5">看到我啦?!if 0.5</h1>
<h1 v-else-if="random > 0.25">看到我啦?!if 0.25</h1>
<h1 v-else>看到我啦?!else</h1>
</div>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data: {
random: 1
}
});
</script>
v-bind 绑定
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>a.html</title>
</head>
<style>
.diyclassred{
color: red;
}
.diyclassblue{
color: blue;
}
</style>
<body>
<div id="app">
<!--双向绑定,文本num中值变,num的值也改变-->
<input type="text" v-model="num">
<!--按钮显示字体绑定的value为context属性-->
<!--绑定class名称为diyclassblue,当num大于100的时候才启用diyclassblue-->
<input type="button" v-bind:value="context" v-bind:class="{diyclassblue:num>100}"><br>
<!--绑定自定义样式diystyle-->
<input type="button" value="我是v-style" v-bind:style="diystyle"><br>
<ul>
<!--如果用户性别为女并且年龄大于25使用class样式diyclassred-->
<li v-for="user in users" v-bind:class="{diyclassred:user.gender=='女'&&user.age>25}">
{{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
num:1,
context:"大于100字体变蓝色",
diystyle:"background-color:red;color:blue;",
users:[
{name:'大牛', gender:'女', age: 11},
{name:'二蛋', gender:'男', age: 36},
{name:'三驴', gender:'女', age: 24},
{name:'四毛', gender:'女', age: 98},
{name:'五虎', gender:'女', age: 29}
]
},
});
</script>
</html>
- 如果文本框1改为大于100值
computed 计算属性
<div id="app">
<h1>您的生日是:{{birth}} </h1>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
birthday:1429032123201 // 毫秒值
},
//计算属性,里面也是定义方法,但是必须要有返回值,可以像数据模型去使用
//与方法不同,无论birthday是否变化,方法都会重新执行一次
//计算属性会对之前的结果进行缓存,如果birthday变化,才会重新执行计算属性
computed:{
//错误使用{{birth()}}
//正确用{{birth}}
birth(){
const date = new Date(this.birthday);
return date.getFullYear() + "-" + date.getMonth() + "-" + date.getDay();
}
}
});
</script>
watch
<div id="app">
<input type="text" v-model="message">
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
message:""
},
watch:{
message(new_message,old_message){
console.log(new_message,old_message);
}
}
});
</script>
- 依次输入123456789 显示
组件化
//可以
template: "\
<div>\
<button @click='part_incr'>加</button> \
<button @click='part_decr'>减</button> \
</div>"
//不可以
template: "\
<div>\
<button @click='part_incr'>加</button> \
<button @click='part_decr'>减</button> \
</div><span></span>"
<div id="app">
<!--每个标签不会互相影响效果-->
<counter></counter><br>
<counter></counter><br>
<counter></counter>
</div>
const app = new Vue({
el:"#app",
data:{
num: 0
}
});
Vue.component("counter",{
//定义全局组件,两个参数: 1,组件名称 2,组件参数
template:"<button @click='num++'>已点击{{num}}次</button>",
data(){
return{
num:0
}
}
});
<div id="app">
<counter></counter>
</div>
const counter1 = {
template: "<button @click='num++'>已点击{{num}}次</button>",
data() {
return {
num: 0
}
}
};
//new Vue需要写在定义的组件下面
new Vue({
el: "#app",
components: {
//counter为标签名,counter1位自定义的组件
"counter": counter1
}
});
- 点击两次按钮
组件通信
props
<div id="app">
<!--自定义属性num1,双向绑定num-->
<counter :num1="num"></counter>
</div>
<script>
Vue.component("counter",{
//两个num1是props接收的属性
template:"<button @click='num1++'>已点击{{num1}}次</button>",
//通过props接收父组件传递的属性
props:["num1"]
});
new Vue({
el: "#app",
data:{
num:0
}
});
</script>
- 点击两次后显示
$emit
<div id="app">
<h2>num: {{num}}</h2>
<diy_tag :diy_props="num" @diy_incr="global_incr" @diy_decr="global_decr"></diy_tag>
</div>
<script>
Vue.component("diy_tag", {
template: "\
<div>\
<button @click='part_incr'>加</button> \
<button @click='part_decr'>减</button> \
</div>",
props: ["diy_props"],
methods: {
part_incr() {
this.$emit("diy_incr");
},
part_decr() {
this.$emit("diy_decr");
}
}
});
var app = new Vue({
el: "#app",
data: {
num: 0
},
methods: { // 父组件中定义操作num的方法
global_incr() {
this.num++;
},
global_decr() {
this.num--;
}
}
});
</script>
vue-router
安装vue-router
- 进入IDEA下面Terminal
- 进入项目
cd hello-vue
- 安装
npm install vue-router --save
模块结构
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>src/index.html</title>
</head>
<body>
<div id="app">
<span>登录</span>
<span>注册</span>
<hr>
<!--使用login-form来匹配loginForm-->
<!--直接使用<loginForm></loginForm>会解析成<loginform></loginform>,会导致匹配不到-->
<login-form></login-form>
<register-form></register-form>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script></script>
<script src="js/login.js"></script>
<script src="js/register.js"></script>
<script>
const app=new Vue({
el:"#app",
components:{
//loginForm:loginForm, 缩写 loginForm,
loginForm,
registerForm
}
});
</script>
</html>
- login.js
const loginForm = {
//组件内template只能有一个根标签
// 代表一个汉字
template: `
<div>
<h1>登录页</h1>
用户名:<input type="text"><br>
密 码:<input type="password"><br>
<input type="button" value="登录">
</div>
`
}
- register.js
const registerForm = {
//组件内template只能有一个根标签
// 代表一个汉字
// 代表半个汉字
template: `
<div>
<h1>注册页</h1>
用 户 名:<input type="text"><br>
密  码:<input type="password"><br>
确认密码:<input type="password"><br>
<input type="button" value="注册">
</div>
`
}
- 使用vue-router,改写后index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>src/index.html</title>
</head>
<body>
<div id="app">
<!--<span>登录</span>
<span>注册</span>
<hr>
<!–使用login-form来匹配loginForm–>
<!–直接使用<loginForm></loginForm>会解析成<loginform></loginform>,会导致匹配不到–>
<login-form></login-form>
<register-form></register-form>-->
<span><router-link to="/login">登录</router-link></span>
<span><router-link to="/register">注册</router-link></span>
<hr>
<router-view></router-view>
</div>
</body>
<!--先引入vue.js再引入vue-router.js-->
<!--引入vue.js-->
<script src="../node_modules/vue/dist/vue.js"></script>
<!--引入vue-router.js-->
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script src="js/login.js"></script>
<script src="js/register.js"></script>
<script>
//需要在Vue中引入才可使用
const router=new VueRouter({
routes:[
{
//路由路径,必须以/开头
path:"/login",
//组件名称
component:loginForm
},
{
//路由路径,必须以/开头
path:"/register",
//组件名称
component:registerForm
}
]
});
const app=new Vue({
el:"#app",
/*//使用路由vue-router后,不需再引入components
components:{
//loginForm:loginForm, 缩写 loginForm,
loginForm,
registerForm
},*/
router//引用上面定义的router对象
});
</script>
</html>