vue 入门
Vue
一款切换镜像的工具:nrm
npm install nrm -g -g`代表全局安装
通过nrm use taobao
来指定要使用的镜像源
通过nrm test npm
来测试速度
cnpm命令,有时会有bug,不推荐
创建工程:
- 先输入:
npm init -y
进行初始化 - 安装Vue,输入命令:
npm install vue --save
每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模板等等。Vue为生命周期中的每个状态都设置了钩子函数(监听函数)。每当Vue实例处于不同的生命周期时,对应的函数就会被触发调用。
created
代表在vue实例创建后
<body>
<!--入demo-->
<div id="app">
<h2>姓名: {{name}}</h2>
<h2>爱好:{{hobby}}
<label><input type="text" v-model="hobby"/></label>
</h2>
<h2>
<label><button @click="num--">-</button></label>
xx值数:{{num}}
<label><button @click="num++">+</button></label>
</h2>
<button @click="alert">点我</button>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
// 生成vue实例
let app = new Vue({
el: "#app", //要渲染的页面元素
data: {
name: "",
hobby: "",
num: 0
},
methods: {
alert: function () {
alert("弹窗..")
}
},
created(){ //初始化,代表这个时期的构造函数
this.name = "张三";
console.log(this) //与 app 结果相同
}
});
</script>
</body>
指令
插值表达式
花括号
格式:
{{表达式}}
说明:
- 该表达式支持JS语法,可以调用js内置函数(必须有返回值)
- 表达式必须有返回结果。例如 1 + 1,没有结果的表达式不允许使用,如:var a = 1 + 1;
- 可以直接获取Vue实例中定义的数据或函数
示例:
HTML:
<div id="app">{{name}}</div>
JS:
var app = new Vue({
el:"#app",
data:{
name:"Jack"
}
})
插值闪烁
使用{{}}方式在网速较慢时会出现问题。在数据未加载完成时,页面会显示出原始的{{}}
,加载完毕后才显示正确数据,称为插值闪烁。
v-text和v-html
使用v-text和v-html指令来替代{{}}
不会出现插值闪烁,当没有数据时,会显示空白。
说明:
- v-text:将数据输出到元素内部,如果输出的数据有HTML代码,会作为普通文本输出
- v-html:将数据输出到元素内部,如果输出的数据有HTML代码,会被渲染
示例:
HTML:
<div id="app">
v-text:<span v-text="hello"></span> <br/>
v-html:<span v-html="hello"></span>
</div>
JS:
var vm = new Vue({
el:"#app",
data:{
hello: "<h1>大家好</h1>"
}
})
v-model
目前v-model的可使用元素有:
- input
- select
- textarea
- checkbox
- radio
- components(Vue中的自定义组件)
基本上除了最后一项,其它都是表单的输入项。
- 多个
CheckBox
对应一个model时,model的类型是一个数组,单个checkbox值是boolean类型 - radio对应的值是input的value值
input
和textarea
默认对应的model是字符串select
单选对应字符串,多选对应也是数组
<div id="app">
<input type="checkbox" v-model="language" value="Java" />Java<br/>
<input type="checkbox" v-model="language" value="PHP" />PHP<br/>
<input type="checkbox" v-model="language" value="Swift" />Swift<br/>
<h1>
你选择了:{{language.join(',')}}
</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
language: []
}
})
</script>
v-on
v-on指令用于给页面元素绑定事件。
语法:
v-on:事件名="js片段或函数名"
v-on:简写@
事件修饰符
.stop
:阻止事件冒泡.prevent
:阻止默认事件发生.capture
:使用事件捕获模式.self
:只有元素自身触发事件才执行。(冒泡或捕获的都不执行).once
:只执行一次
例子:
<!--事件冒泡-->
<div @click="myClick('div')" style="height: 100px;width: 100px;background: blue">
<button @click.stop="myClick('button')">点击</button>
</div>
按键修饰符
在监听键盘事件时添加按键修饰符:
<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
<input v-on:keyup.13="submit">
Vue 为最常用的按键提供了别名:
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">
全部的按键别名:
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.down
.left
.right
组合按钮
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl
.alt
.shift
<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
v-for
遍历数据渲染页面,Vue中通过v-for指令来实现。
<body>
<div id="app">
<!--遍历数组-->
<table border="1">
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
</tr>
<!--
- users:要迭代的数组
- user:迭代得到的数组元素别名
- index:迭代到的当前元素索引,从0开始
-->
<tr v-for="(user,index) in users">
<td>{{index+1}}</td>
<td>{{user.name}}</td>
<td>{{user.age}}</td>
</tr>
</table>
<!--遍历对象-->
<ul v-for="(user,index) in users" :key="index">
<!--
- 1个参数时,得到的是对象的值
- 2个参数时,第一个是值,第二个是键
- 3个参数时,第三个是索引,从0开始
-->
<li v-for="(v,k,i) in user">
id:{{index}} - 属性{{i}} - {{k}} - {{v}}
</li>
</ul>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el:"#app",
data:{
users:[
{name:'a',age:'10'},
{name:'b',age:'11'},
{name:'c',age:'12'},
{name:'d',age:'9'}
]
}
})
</script>
</body>
有效的提高渲染的效率
当 Vue.js 用 v-for
正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
有效的提高渲染的效率。
需要为每项提供一个唯一 key
属性。理想的 key
值是每项都有的且唯一的 id,如索引。
v-if和v-show
v-if,条件判断。当得到结果为true时,所在的元素才会被渲染。
v-else,v-else
元素必须紧跟在带 v-if
或者 v-else-if
的元素的后面,否则它将不会被识别。
v-else
,v-else-if
也必须紧跟在带 v-if
或者 v-else-if
的元素之后。
另一个用于根据条件展示元素的选项是 v-show
指令,不同的是带有 v-show
的元素始终会被渲染并保留在 DOM 中。v-show
只是简单地切换元素的 CSS 属性 display
。
例子:
<ul v-for="(k,i) in [1,2,3,4,5,6]">
<li v-if="i===0">{{k}}:金</li>
<li v-else-if="i===1">{{k}}:银</li>
<li v-else-if="i===2">{{k}}:铜</li>
<li v-else>{{k}}:加油</li>
</ul>
v-bind
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#div{
height: 100px;
width: 100px;
}
.red{
background: red;
}
.yellow{
background: yellow;
}
</style>
</head>
<body>
<div id="app">
<!--v-bind绑定实例-->
<div id="div" @click="isColor=!isColor" :class="{red:isColor,yellow:!isColor}">
点击变色
</div>
<!--计算属性-->
<h1>时间:{{myDate}}</h1>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el:"#app",
data:{
isColor:true,
birthday:1629032123201 // 毫秒值
},
computed:{//计算属性
myDate(){
const d = new Date(this.birthday);
return d.getFullYear()+"/"+d.getMonth()+"/"+d.getDay();
}
}
})
</script>
</body>
</html>
watch
watch可以监控一个值的变化。从而做出相应的反应
例子:
msg:<input type="text" v-model="msg">
age:<input type="text" v-model="user.age">
<script>
let app = new Vue({
el:"#app",
data:{
msg:"",
user:{
name:"aa",
age:1
}
},
watch:{
msg(newV,oldV){
console.log(newV,oldV)
},
//深监控
user:{
deep:true,
handler(val){
console.log(val.age)
}
}
}
})
</script>
组件化
全局组件与局部组件
<body>
<div id="app">
<!--每个组件互不干扰-->
<!--注意,组件名为全小写-->
<counter></counter>
<counter></counter>
<innercounter></innercounter>
<innercounter></innercounter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
// 定义全局组件
Vue.component("counter",{
template:'<button v-on:click="count++">赞:{{ count }} 次</button>',
data(){
return{
count:0
}
}
});
//局部注册
const innercounter = {
template:"<button v-on:click='innerCount++'>inner赞 {{ innerCount }} 次</button>",
data(){
return{
innerCount:0
}
}
};
const app = new Vue({
el:"#app",
components:{
// innercounter:innercounter // 将定义的对象注册为组件
innercounter //同名简写
}
});
</script>
</body>
组件通信
父向子传递props
<body>
<div id="app">
<innercounter count="1"></innercounter>
<innercounter2 count="2"></innercounter2>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
// 父向子传递props
const innercounter = {
template:"<button v-on:click='innerCount++'>inner赞 {{ count }} 次</button>",
props:['count']// 通过props来接收一个父组件传递的属性
};
// 传递复杂数据
const innercounter2 = {
template:"<button v-on:click='innerCount++'>inner2赞 {{ count }} 次</button>",
props: {
count:{
type:String,//要求的类型
default:0//默认值
}
}
};
const app = new Vue({
el:"#app",
components:{
innercounter,
innercounter2
}
});
</script>
</body>
子向父的通信
<body>
<div id="app">
<h2>{{num}}</h2>
<innercounter :count="num" @inc="increment" @dec="decrement"></innercounter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
// 子向父的通信
const innercounter = {
template:`
<div>
<button @click="plus">加</button>
<button @click="reduce">减</button>
</div>`,
props:['count'],
methods:{
plus(){
this.$emit("inc")
},
reduce(){
this.$emit("dec")
}
}
};
const app = new Vue({
el:"#app",
data:{
num:0
},
methods:{// 父组件中定义操作num的方法
increment(){
this.num++;
},
decrement(){
this.num--;
}
},
components:{
innercounter
}
});
</script>
</body>
路由vue-router
使用npm安装:npm install vue-router --save
例子:
index.js
const indexForm={
template:`
<div>
<h1>欢迎来到首页!</h1>
</div>
`
};
me.js
const meForm={
template:`
<div>
<h1>欢迎来到我的!</h1>
</div>
`
};
home.html
<body>
<div id="app">
<span><router-link to="/">首页</router-link></span>
<span><router-link to="/me">我的</router-link></span>
<hr/>
<div>
<router-view></router-view>
</div>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script src="node_modules/vue-router/dist/vue-router.min.js"></script>
<script src="index.js"></script>
<script src="me.js"></script>
<script>
// 创建VueRouter对象
const router = new VueRouter({
routes:[
{
path:'/',// 请求路径
component:indexForm// 组件名称
},
{
path: "/me",
component: meForm
}
]
});
const v = new Vue({
el: "#app",
components: {
indexForm,
meForm
},
router // 引用上面定义的router对象
});
</script>
</body>