本文基于Vue.js官方网站上的视频教程,理解后整理出该入门学习资料,供大家参考。
Vue一篇入门--基本使用
一、如何引入Vue
- 最简单的方式:通过
<script>
标签引入Vue,只需在<body>
标签中写入:
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
二、创建第一个Vue应用
- Vue的使用分为两个部分:视图+脚本
- 视图:
<div id="app">
{{message}}, {{name}}
</div>
- 脚本:
- 通过Vue函数新建一个Vue的应用,其中包含两个关键属性
- el:ID选择器,选择对应div
- data:保存数据,需要注册和赋值视图中的变量
<script type="text/javascript">
var vm = new Vue({
el : '#app',
data: {
message: "Hello Vue!",
name: "nihao!"
}
});
</script>
三、数据与方法
- 可以定义对象,作为data里属性的值
- 此时,视图里的message和name是通过data这个对象进行参数传递的
<div id="app">
{{message}}---{{name}}
</div>
<script type="text/javascript">
var data = {message:1,name:2}
var vm= new Vue({
el : '#app',
data: data
});
vm.message = 100
</script>
- Vue实例的属性也可以使用,需要在前面增加
$
:
vm.$data.name = 'yuyu';
-
$watch
观察变量变化过程,开发调试有用
- 入参1:要观察的变量名
- 入参2:回调函数,回调函数有两个入参,一个是变化后的值,一个是变化前的值
<script type="text/javascript">
var data = {message:1,name:'hello'}
var vm= new Vue({
el : '#app',
data: data
});
vm.message = 100
vm.$watch('name', function(newVal,oldVal){
console.log(newVal,oldVal)
})
vm.$data.name = 'zhangsan';
</script>
- 生命周期钩子
- Vue实例被创建时需要经历一系列初始化过程,用户可以用生命周期钩子进行初始化操作
- 生命周期钩子写在new Vue的对象内,以属性的方式声明
- beforeCreate:整个页面创建之前调用
- created:实例创建完成后调用
- beforeMount:挂载之前
- mounted:挂载成功之后,相当于页面中的元素被
vm.$el
替换
- mounted:挂载成功之后,相当于页面中的元素被
- beforeUpdate:数据变化之前
- updated:数据变化之后
var vm = new Vue({
el: '#app',
data: {
message: "hi Vue",
},
beforeCreate: function() {
console.log("beforeCreate")
},
created: function() {
console.log("created")
},
beforeMount: function() {
console.log("beforeMount")
},
mounted: function() {
console.log("mounted")
},
beforeUpdate: function() {
console.log("beforeUpdate")
},
updated: function() {
console.log("updated")
}
});
setTimeout(function() {
vm.message = "changed..."
}, 3000);
</script>
-
输出结果为(控制台):在页面初始化执行了a~d,在3s后执行了e~f
四、模版语法
- 插值
-
{{msg}}
其中msg为变量名 - 如果后续不想让这个值改变,在标签里加上
v-once
指令:
<span>{{message}}</span>
<span v-once>{{message}}</span>
- JS表达式
- 支持在
{{}}
中使用JS表达式 :
<p>{{num+1}}</p>
<p>{{ok? 'YES':'NO'}}</p>
<p>{{msg.split("").reverse().join("")}}</p>
五、指令
- HTML元素
- 利用Vue在html里插入一个元素,如果直接使用
{{}}
,输出则是没有转换后的标签,是普通的文本 - 使用
v-html
属性,并将其赋值为一个变量,则可以在该标签内部插入HTML元素
<div id="app">
<p>Using mustaches: {{rawHtml}}</p>
<p v-html=rawHtml></p>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
rawHtml: "<span style='color:red'>This should be red</span>",
},
});
</script>
- 绑定属性
-
v-bind:标签属性="变量名"
:用变量名的值赋值给标签属性 - class绑定
- 使用
v-bind:class
定义了两个样式active
和green
,用isActive
和isGreen
两个变量控制是否激活
- 使用
<div id="app" class=“test” v-bind:class="{active: isActive, green: isGreen}"
style="width:200px;height:200ox;text-align: center;line-height: 200px;">
hello vue
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
isActive: true,
isGreen: true
}
});
</script>
<style>
.text {
font-size: 300px;
}
.green {
color: green;
}
.active {
background: red;
}
</style>
+ 也可以用数组+三元运算符的形式进行控制:
<div id="app" class=“test” v-bind:class="[isActive?'active':'', isGreen?'green':'']"
style="width:200px;height:200ox;text-align: center;line-height: 200px;">
hello vue
</div>
- style绑定
- 使用
v-bind:style
控制样式,用color
和size
两个变量控制字体颜色和字体大小
- 使用
<div id="app" v-bind:style="{color:color, fontSize:size}">
hi vue
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
color: 'red',
size: '50px'
}
});
</script>
+ 也可以直接给`v-bind:style`一个变量`color`,在Vue App中对该变量赋值
<div id="app">
<span v-bind:style="color">test...</span>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
color: "color:blue",
},
});
setTimeout(function() {
vm.color = "color:red"
}, 2000);
</script>
+ 还可以利用三元运算符
<div id="app" v-bind:style="{color:isRed?'red':''}">
hi vue
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
isRed: true,
}
});
</script>
- 其他
<div id="app">
<a v-bind:href="url">Click me!</p>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
url: "http://www.baidu.com"
},
});
</script>
- 条件渲染
-
v-if
- 只有该属性为true时,标签才会被渲染(存在),否则不渲染
<div id="app">
<p v-if="seen">现在你看到我了</p>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
seen: false
},
});
setTimeout(function() {
vm.seen = true;
}, 4000);
</script>
-
v-if
,v-else-if
和v-else
- 实现多个条件的判断
<div id="app">
<div v-if="type=='A'">
A
</div>
<div v-else-if="type=='B'">
B
</div>
<div v-else="type=='C'">
C
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
type: 'D',
}
});
-
v-show
- 根据条件,展示某个标签,和
v-if
的区别在于,后者如果是false直接不存在该标签,而前者则是存在该标签但是不显示 - 如果页面切换频繁,则建议使用
v-show
,否则使用v-if
- 根据条件,展示某个标签,和
<div id="app">
<div v-show="ok">
hello
</div>
</div>
- 列表渲染
-
v-for
-
v-for="item in items"
:items为数组名称,item为数组中一个元素的名称,用来操作使用 - 下例中
items
为数组的各个元素,它包含一个属性msg
,将其取出输出到页面
-
<div id="app">
<ul>
<li v-for="item in items">
{{item.msg}}
</li>
</ul>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
items:[
{msg:'hello'},
{msg:'hi'},
{msg:'nihao'}
]
}
});
</script>
+ `v-for="item,index in items"`:index为数组索引,从0开始
<ul>
<li v-for="item,index in items">
{{index}}:{{item.msg}}
</li>
</ul>
+ `v-for="value,key in objects"`:遍历对象,key为对象的键,value为对象的值,key和value的位置不能反
<div id="app">
<ul>
<li v-for="value,key in objects">
{{key}}:{{value}}
</li>
</ul>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
objects:{
name: 'zhangsan',
age: '12',
city: 'nanjing'
}
}
});
</script>
+ `v-for`中数据顺序改变,Vue不会改变显示的顺序,如果需要按照特定要求排序元素需要使用
v-bind:key
指令,对于数据组v-bind:key="index"
,对于对象v-bind:key="key"
- 事件处理
-
v-on
-
v-on:click="具体操作"
:执行具体操作中的内容
-
<div id="app">
<button v-on:click="counter+=1">点击:{{counter}}次</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
counter: 0
}
});
</script>
+ `v-on:click="函数名"`:执行函数中的内容,函数在new Vue中的methods中定义
<div id="app">
<button v-on:click="greet">Click Me</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
methods: {
greet : function(){
alert('hello vue')
}
}
});
</script>
+ `v-on:click="函数名(传递参数)"`:还可以为函数传递参数,还可以用`this`调用new Vue中data的属性
<div id="app">
<button v-on:click="greet('they are parameters')">Click Me</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data:{
name: "vue",
},
methods: {
greet : function(param){
alert('hello')
alert(this.name)
alert(param)
}
}
});
</script>
-
$event
:事件,可将其作为入参通过函数传入
<div id="app">
<button v-on:click="greet('they are parameters',$event)">Click Me</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data:{
name: "vue",
},
methods: {
greet : function(param,e){
alert(param)
console.log(e)
}
}
});
</script>
- 事件修饰符
- stop,prevent,capture等等
- 如下例,如果点击Click me,两个click事件都会触发:
<div id="app">
<div v-on:click="click1">
<div v-on:click="click2">Click me!</div>
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
methods: {
click1: function(){
console.log("click1")
},
click2: function(){
console.log("click2")
},
},
});
</script>
+ 我们可以使用修饰符,防止事件上传,只会触发内部div的事件:
<div id="app">
<div v-on:click="click1">
<div v-on:click.stop="click2">Click me!</div>
</div>
</div>
- 每个html元素都有不同的事件,不止click
- 指令缩写
-
v-on
:@
- 如:
<button @click="count++"> </button>
- 如:
-
v-bind
::
- 如:
<a :href="url">Click me</a>
- 如:
六、表单输入绑定
-
v-model
:用于<input>
,<textarea>
,<select>
,<radio>
,<checkbox>
元素,实现双向数据绑定- text和textarea:使用value属性和input事件
- select:使用value属性和change事件
- radio和checkbox:使用checked属性和change事件
<div id="app">
<input v-model="msg" placeholder="please say something"/>
<p>your input is: {{msg}}</p>
<textarea v-model="msg2" placeholder="please say many things"></textarea>
<p style="white-space: pre-line;">your input is: {{msg2}}</p>
<div style="margin-top:20px">
<input type="checkbox" id="apple" value="Apple" v-model="checkedNames"/>
<label for="apple">Apple</label><br>
<input type="checkbox" id="pear" value="Pear" v-model="checkedNames"/>
<label for="pear">Pear</label><br>
<input type="checkbox" id="watermelon" value="Watermelon" v-model="checkedNames"/>
<label for="watermelon">Watermelon</label><br>
<span>your selection is: {{checkedNames}}</span>
</div>
<div style="margin-top:20px">
<input type="radio" id="apple1" value="Apple" v-model="picked"/>
<label for="apple1">Apple</label><br>
<input type="radio" id="pear1" value="Pear" v-model="picked"/>
<label for="pear1">Pear</label><br>
<input type="radio" id="watermelon1" value="Watermelon" v-model="picked"/>
<label for="watermelon1">Watermelon</label><br>
<span>your selection is: {{picked}}</span>
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data:{
msg: "",
msg2: "",
checkedNames : [],
picked: "",
},
});
</script>
- 提交表单
- 定义一个按钮,点击触发
click
事件对应的函数,在函数中利用this
获取提交数据。
<div id="app">
... 表单 ...
<button @click="submit">submit data</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data:{
msg: "",
msg2: "",
checkedNames : [],
picked: "",
},
methods:{
submit : function(){
var obj = {};
obj.msg = this.msg
obj.msg2 = this.msg2
obj.checkedNames = this.checkedNames
obj.picked = this.picked
console.log(obj)
}
}
});
</script>
七、组件
- 创建组件
- 使用
Vue.component
函数创建组件,创建的是全局注册组件- 参数1:组件名称
- 参数2:以对象形式描述组件数据,属性,模版,事件等
- 组件是可复用的Vue实例,可以使用data,methods等以及生命周期钩子,但是不能使用el
<div id="app">
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script type="text/javascript">
Vue.component('button-counter',{
data: function(){
return {
count:0
}
},
template: '<button v-on:click="count+=1"> you clicked me {{count}} times.</button>'
})
var vm = new Vue({
el: "#app",
})
</script>
- 组件添加属性
- 第二个参数中,使用
props
(是一个数组)来定义属性,在template
中使用该属性 - 使用这个组件时,可以为这个属性赋值
<div id="app">
<button-counter name="zhangsan"></button-counter>
<button-counter name="lisi"></button-counter>
</div>
<script type="text/javascript">
Vue.component('button-counter',{
props: ["name"],
data: function(){
return {
count:0
}
},
template: '<button v-on:click="count+=1"> {{name}} clicked me {{count}} times.</button>'
})
var vm = new Vue({
el: "#app",
})
</script>
- 组件的
template
需要有一个根结点
- 如果使用多个标签定义一个组件,需要在最外层套上一个标签
<script type="text/javascript">
Vue.component('button-counter',{
props: ["name"],
data: function(){
return {
count:0
}
},
template: '<div><h1>hi vue</h1><button v-on:click="count+=1"> {{name}} clicked me {{count}} times.</button></div>'
})
var vm = new Vue({
el: "#app",
})
</script>
- 事件监听
- 在
template
中使用v-on
监听事件 - 在Vue.componet的第二个参数中定义
methods
属性用来定义事件处理函数 - 在处理函数中使用
this.$emit(事件名称,可携带的参数)
触发事件 - 使用组件,在new Vue的
methods
属性中处理事件
<div id="app">
<button-counter name="zhangsan" v-on:count="countEvent"></button-counter>
</div>
<script type="text/javascript">
Vue.component('button-counter',{
props: ["name"],
data: function(){
return {
count:0
}
},
template: '<div><h1>hi vue</h1><button v-on:click="clickCount"> {{name}} clicked me {{count}} times.</button></div>',
methods :{
clickCount: function(){
this.count ++;
this.$emit("count",this.count);
}
}
})
var vm = new Vue({
el: "#app",
methods:{
countEvent: function(e){
alert(e)
}
}
})
</script>
- 插槽
- 在
template
中定义插槽<slot></slot>
,则可以在自定义的组件中添加html元素
<div id="app">
<button-counter name="zhangsan">
<h2> hi...h2</h2>
</button-counter>
</div>
<script type="text/javascript">
Vue.component('button-counter',{
props: ["name"],
data: function(){
return {
count:0
}
},
template: '<div><h1>hi vue</h1><button v-on:click="count++"> {{name}} clicked me {{count}} times.</button><slot></slot></div>',
})
var vm = new Vue({
el: "#app",
})
</script>
- 局部注册组件
- new Vue时,使用components参数注册局部组件
<div id="app">
<test></test>
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
components: {
test: {
template: "<h2> ... h2 ... </h2>"
}
},
})
</script>
- 模块系统中局部注册
- 使用
import
和export
单文件组件
- 前序步骤
- 安装npm
- npm全称Node Package Manager,是一个基于Node.js的包管理器
- mac系统安装
- 下载安装包:https://nodejs.org/zh-cn/download/
- 查看npm版本:
npm -v
- 由于网络原因,安装cnpm镜像
- mac安装:
sudo npm install -g cnpm --registry=https://registry.npm.taobao.org
- mac安装:
- 安装vue-cli
- mac安装:
sudo cnpm install -g @vue/cli
- mac安装:
- 安装webpack
- webpack是js打包器
- mac安装:
sudo cnpm install -g webpack
- 启动Vue图形化管理界面,创建项目
vue ui
- 点击Create新建项目:输入名称,选择存储位置,选择包管理器npm
- 选择Default
- 运行项目
- 使用HBuilderX,将新建工程拖入HBuilderX
- 点击运行--运行到终端--
npm build serve
--生成运行网址--复制进浏览器运行
- 项目组成
- node_modules:以来包
- public:公共资源
- src:源代码,入口为App.vue
- assets:图片等资源
- components:自定义组件
- 其他文件:一些配置文件
- 新建单文件组件
- 在components下新建一个xx.vue文件(简单模版)
- 由
template
,script
,style
组成:分别表示视图、脚本(expoort default {}
属性、数据和方法等)和样式
<template>
<h2 class="red"> hi, this is a template </h2>
</template>
<script>
export default {
name: "test-comp",
props: {
msg: {
type: String,
default: "test msg"
}
},
methods: {},
data: function() {
return {}
}
}
</script>
<style>
.red {
color: red
}
</style>
- 使用单文件组件
- 引入自定义组件:
import 组件名 from './components/xx.vue'
- 局部注册组件:
export default{name:'app', components:{组件名,}}
- 在template中使用组件
<xx></xx>
<template>
<test></test>
</template>
<script>
import test from './components/test.vue'
export default {
name: 'App',
components: {
test
}
}
</script>
<style>
</style>
八、免终端开发Vue应用
-
uni-app
+HBuilderX
- 在HBuilderX中新建uni-app默认项目
- 项目目录结构
- pages:业务页面
- static:静态资源文件(图片、视频)
- App.vue:应用配置,全局样式以及监听应用生命周期
- manifest.json:配置应用名称、appid、logo、版本等打包信息
- pages.json:配置页面路由、导航条、选项卡等页面信息
- 项目运行:运行--运行到浏览器
- 项目发行:发行--网站--控制台会显示生成文件--将其部署到服务器即可
- 创建新闻组件news的例子
- 在项目中新建components文件夹
- 在该文件夹下新建组件news.vue,内容如下:
<template>
<view>
<news title="震惊!" content="无敌!!!!!" @tap1="tap"></news>
</view>
</template>
<script>
import news from "@/components/news.vue";
export default {
components:{
news
},
methods: {
tap: function(e){
console.log(e)
}
}
}
</script>
<style>
</style>
- 在项目的index.vue中引入、注册和使用组件,代码如下:
<template>
<view>
<news title="震惊!" content="无敌!!!!!" @tap1="tap"></news>
</view>
</template>
<script>
import news from "@/components/news.vue";
export default {
components:{
news
},
methods: {
tap: function(e){
console.log(e)
}
}
}
</script>
<style>
</style>