慕课视频:https://www.imooc.com/learn/980
Vue cli介绍:https://blog.csdn.net/wulala_hei/article/details/80488674
Vue cli就是一个脚手架。
1.简介:
Vue是一套构建用户界面的渐进式框架。
Vue只关注视图层,采用自底向上增量开发的设计。
Vue更着重于编写数据层的处理操作,减少dom的操作 。
Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
2.Vue基础语法:
2.1 创建第一个vue实例
<div id="root">//挂载点
{{msg}} //挂载点里的内容都叫做模板内容,也可以直接将模板内容放到实例的template里面去
</div>
<script>
new vue({ //vue实例
el:"#root",
data:{
msg:"hello wold"
}
})
</script>
2.2 挂载点,模板与实例
挂载点:el属性对应的dom元素,id,class
模板:在挂载点内的所有内容,视频中div里面的内容。也可以在Vue实例中用template属性替换。
实例:在Vue实例,将挂载点el属性和模板相结合展示在页面中的内容就是最终的实例。
Vue实例只会对 相应的el属性产生作用。
<div id="root">//挂载点
{{msg}} //挂载点里的内容都叫做模板内容,也可以直接将模板内容放到实例的template里面去
</div>
<script>
new vue({ //vue实例
el:"#root",
data:{
msg:"hello wold"
}
})
</script>
// 模板写在template里面
<div id="root"> //挂载点
</div>
<script>
new vue({ //vue实例
el:"#root",
template:'{{msg}}' //将模板内容放到实例的template里面去
data:{
msg:"hello wold"
}
})
</script>
2.3 Vue实例中的数据,事件和方法
v-text = “变量”: 文本会原样输出
v-html = “变量”: 文本会被当作html解析输出
{{变量}} 插值表达式
绑定事件: v-on:click=“函数名” 或者 @click=“函数名”
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>vue入门</title>
<script src="vue.js"></script>
</head>
<body>
<div id="root">
<div @click="handleClick">{{content}}</div>
<div v-on:click="handleClick"></div>
<h1>{{content}}</h1>
<h1 v-text="number" ></h1>
<div v-html="msg">
</div>
</div>
<script>
<!-- 实例 -->
new Vue({
el:"#root",
data:{
content:"hello",
msg:"<h1>hello</h1>"
// template:"<h1>hello</h1>", 模板也可以写在这里
},
methods:{
handleClick:function(){
this.content="world" //不操作dom改变数据
}
}
})
</script>
</body>
</html>
改变页面数据不需要改变dom,直接改变this.content,vue实例对模板进行监听,页面自动改变。
牢记哈:v-text无法渲染数据中html元素,而v-html能够将数据中的html元素渲染出来。面试常问题目,拿小本本记下
2.4 Vue中的属性绑定和双向数据绑定
v-model :双向数据绑定,
v-bind: 属性绑定,之前是变量的绑定,现在是对属性进行绑定。
v-bind:属性绑定,使用这样的模板指令之后 等号后面的内容就是一个变量了,所以可以拼接字符串。
<div v-bind:title="title">属性绑定</div>
//可以缩写成:
<div :title="title">属性绑定</div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>属性绑定和双向数据绑定</title>
<script src="vue.js"></script>
</head>
<body>
<div id="root">
<div :title="title">hello world</div> //<!-- 属性绑定 v-bind: 等价于 : -->
<input v-model="content" /> //<!-- 双向数据绑定:两个地方都改变 -->
<div>{{content}}</div>
</div>
<script>
new Vue({
el:"#root",
data:{
title:"this is hello world",
content:"this is content",
}
})
</script>
</body></html>
平时是单向,单向是指数据data决定页面的数据显示,双向就是指页面的数据可以反馈给data,从而再次导致页面另一个数据改变。
2.5 Vue中计算属性和侦听器
computed:根据其他数据计算出来的新的结果,其他数据变化的时候进行计算,其他数据没有变化的时候直接读取缓存中的值.
watch:侦听某一个数据或者计算属性是否变化,一旦发生变化,我们就可以在侦听器里面去写一些业务逻辑…
侦听器:侦听器指的是监听某一个数据的变化,一旦这个数据发生了变化,就可以在watch里面做业务逻辑.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>计算属性与侦听器</title>
<script src="vue.js"></script>
</head>
<body>
<div id="root">
姓:<input v-model="firstName" />
名:<input v-model="lastName" />
<div>{{fullName}}</div>
<div>{{count}}</div>
</div>
<script>
new Vue({
el:"#root",
data:{
firstName:'',
lastName:'',
count:0
},
computed:{
// computed指的是一个属性通过其它属性计算而来的
// 它性能比较高只有当所依赖的属性发生变化时才重新计算
// 没有发生变化时就来利用之前的缓存显示
fullName:function(){ //fullName更新就执行函数
return this.firstName + ' '+ this.lastName
}
},
watch:{
// 侦听器是指数据我去监听某个数据的变化,一旦这个数据发生变换,我就可以在我的侦听器中做我的业务逻辑
firstName:function(){ //firstName更新就执行函数
this.count++
},
lastName:function(){ //lastName更新就执行函数
this.count++
}
}
})
</script>
</body></html>
2.6 v-if,v-show与v-for指令
v-if:控制DOM的存在与否(把标签从DOM树中移除,是摧毁与重建过程)
v-show:控件DOM的显示与否(改变css属性为display:none,只是视觉上的隐藏;如果显示与隐藏操作频繁,建议使用v-show)
v-for:控制一组数据,来循环显示数据
v-if:当值为false时,直接将该标签f元素从DOM元素中移除
v-show:当值为false时,将该标签元素隐藏 display:none
如果显示隐藏的频率较高的话,用v-show更好,性能高一些
v-if和v-show相似 v-show更稳定,都是隐藏和展示指令;
使用v-for时加一个key属性,提升渲染效率,key值要求每一项都不相同
如果频繁对列表进行变更时不建议使用index作为key值
<li v-for="item of list">{{item}}</li>
<li v-for="(item,index) of list" :key="index">{{item}}</li>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>v-if,v-show,v-for指令</title>
<script src="vue.js"></script>
</head>
<body>
<div id="root">
<div v-if="show">hello world</div>
<div v-show="show">hello world</div>
<!-- 使用v-if时是直接把整个<div>给删除掉,而使用v-show时是给<div>里添加 style="display:none" 当需要多次显示时用v-show性能更好,如果只需要几次显隐用v-if效果会好-->
<button @click="handleClick">点我</button>
<ul v-for="(item,index) of list" :key="index">
<li>{{item}}</li>
</ul>
<!-- v-for的作用是当你有一个数据需要做循环展示的时候,它会帮助你把这个数据循环展示成一个li 标签;
v-for="(item,index) of list" :key="index"这个意思是把数据list的值个item、下标给index、然后在把index给键值:key
“注意每个:key都是不同的”;
当然是用index作为key值也不是特别好的选择,如果需要对列表进行频繁的变更的时候... -->
</div>
<script>
new Vue({
el:"#root",
data:{
show:true,
list:[1,2,3]
},
methods:{
handleClick:function(){
this.show=!this.show;
}
}
})
</script>
</body></html>
3.Vue中的组件:
3.1 todolist功能开发
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TodoList</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="root">
<div>
<input v-model="inputValue" autofocus=true/>
<button @click="handleSubmit">提交</button>
</div>
<ul>
<li v-for="(item, index) of list" :key="index">
{{item}}
</li>
</ul>
</div>
<script>
new Vue({
el:"#root",
data:{
inputValue:'',
list:[]
},
methods:{
handleSubmit:function(){
this.list.push(this.inputValue)
this.inputValue = '' //每次提交后清空
}
}
})
</script>
</body>
</html>
3.2 todolist组件拆分
<ul>
<todo-item v-for="(item, index) of list" :key="index" :content="item">
</todo-item>
</ul>
Vue.component('todo-item',{ //定义组件 ,Vue.component为全局组件
props:['content'],
template:'<li>{{content}}</li>'
})
Vue中组件中的template如果我们是写<li>item</li>
,那么我们每次都是显示item,所以template模板里面需要是个变量,所以需要props属性。props:['content']
是将:content=''item''
里面item赋值的数据接收到组件中,然后再赋值给templatetemplate:'<li>{{content}}</li>'
,最后显示到页面中。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TodoList</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="root">
<div>
<input v-model="inputValue" autofocus=true/>
<button @click="handleSubmit">提交</button>
</div>
<ul>
<todo-item v-for="(item, index) of list"
:key="index"
:content="item"> //通过属性传参
</todo-item>
</ul>
</div>
<script>
Vue.component('todo-item',{ //定义组件 ,Vue.component为全局组件
props:['content'], //组件接收从外部传输过来的content,然后这个content再赋值给template
template:'<li>{{content}}</li>
})
var TodoItem = { //局部组件(局部组件需要new Vue()中声明)
template:'<li>item</li>'
}
new Vue({
el:"#root",
components:{ //局部组件声明
'todo-item':TodoItem
},
data:{
inputValue:'',
list:[]
},
methods:{
handleSubmit:function(){
this.list.push(this.inputValue)
this.inputValue = '' //每次提交后清空
}
}
})
</script>
</body>
</html>
3.3 组件与实例的关系
Vue中的每个组件都是vue的实例.
如果vue的实例没有模板,找到挂载点(root),把挂载点的div标签下的所有内容当做实例的模板来使用。如果不定义模板,他会使用dom标签的的内容作为实例的模板。
组件里面也可以写data、methods等等,所以组件都是实例,两者基本可以当成一个东西。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>组件与实例的关系</title>
<script src="./vue.js"></script>
</head>
<body>
<h1>vue中每一个组件都是一个实例,即vue由许多个实例组成。</h1>
<div id="root">
<div>
<input v-model="inputValue" autofocus=true/>
<button @click="handleSubmit">提交</button>
</div>
<ul>
<todo-item v-for="(item, index) of list" :key="index" :content="item">
</todo-item>
</ul>
</div>
<script>
Vue.component('todo-item',{ //定义组件 ,ver.component为全局组件
props:['content'],
template:'<li @click="handleClick">{{content}}</li>', //组件也是一个实例,因而可以写事件
methods:{
handleClick:function(){
alert('clicked')
}
}
})
// var TodoItem = { //局部组件
// template:'<li>item</li>'
// }
new Vue({
el:"#root",
// components:{ //局部组件声明
// 'todo-item':TodoItem
// },
data:{
inputValue:'',
list:[]
},
methods:{
handleSubmit:function(){
this.list.push(this.inputValue)
this.inputValue = '' //每次提交后清空
}
}
})
</script>
</body>
</html>
3.4 实现todolist的删除功能
父组件通过属性的形式向子组件传递数据
子组件通过发布与父组件相同的事件传递数据
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>实现todolist的删除功能</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="root">
<div>
<input v-model="inputValue" autofocus=true/>
<button @click="handleSubmit">提交</button>
</div>
<ul>
<todo-item
v-for="(item, index) of list"
:key="index"
:content="item" // 父组件的内容通过属性传递给子组件 content是显示内容
:index="index" // 父组件的内容通过属性传递给子组件 index是下标
@delete="handleDelete" //监听子组件向外触发的delete事件,然后触发父组件里面函数
>
</todo-item>
</ul>
</div>
<script>
Vue.component('todo-item',{ //定义组件 ,ver.component为全局组件
props:['content','index'], //父组件通过属性传递过来的值(显示内容和下标)
template:'<li @click="handleClick">{{content}}</li>', //组件也是一个实例,因而可以写事件
methods:{
handleClick:function(){
this.$emit('delete',this.index) //子组件向外($emit)触发了一个事件,delete,交给父组件
}
}
})
new Vue({
el:"#root",
data:{
inputValue:'',
list:[]
},
methods:{
handleSubmit:function(){
this.list.push(this.inputValue)
this.inputValue = '' //每次提交后清空
},
handleDelete:function(index){
this.list.splice(index,1) //删除list里面数据,index指定位置,1代表删除1项
}
}
})
</script>
</body>
</html>
子组件要想被删除掉,要把父组件里面的list[]数据删除掉,所以当我们点击子组件时候要与父组件通信,模板中定义事件和函数,然后触发子组件中事件和函数,再到父组件中的事件和函数。
4.Vue-cli的使用
4.1 vue-cli的简介和使用
Vue-cli自带了webpack的各种配置,借助该工具,可以迅速上手工程级别vue项目的开发。
vue-cli(2.x版本)创建项目:
1、npm install --global vue-cli 全局安装vue脚手架工具 vue-cli
2、vue init webpack my-project 创建一个基于webpack模版的新项目
3、cd my-project 进入到项目目录
4、npm run dev 运行项目
vue-cli配置详细可以参考:https://blog.csdn.net/wisewrong/article/details/55212684
最新版本请到官网查看使用方法:https://cli.vuejs.org/zh/guide/cli-service.html#使用命令
npm更新到最新版本:
$ npm -v
3.6.0
$ npm install npm@latest -g
....
$ npm -v
5.6.0
参考文章:https://www.imooc.com/article/15800
node更新到最新版本:windows上只能下载最新版本,然后安装时候路径替换。
参考文章:
https://www.cnblogs.com/xinjie-just/p/7061619.html
https://baijiahao.baidu.com/s?id=1609837798512513965&wfr=spider&for=pc
4.2 使用vue-cli 开发TodoList
App.vue
<template>
<div>
<div>
<input v-model='inputValue'/>
<button @click="handleSubmit">提交</button>
</div>
<todo-item
v-for="(item,index) of list"
:key="index"
:content="item"
:index="index"
@delete="handleDelete"
>
</todo-item>
<ul>
</ul>
</div>
</template>
<script>
import Todoitem from './components/Todoitem'
export default {
//组件
components:{
'todo-item':Todoitem //注册局部组件
//'vHeader':header,
//'Todo':todo,
//'vFooter':footer
},
//vue-cli中data是一个函数形式
data : function(){
return{
inputValue:'',
list:[]
}
},
methods:{
handleSubmit(){
this.list.push(this.inputValue)
this.inputValue = ''
},
handleDelete(index){
this.list.splice(index,1)
}
}
}
</script>
<style>
body{
margin: 0;
padding: 0;
}
#app{
height: 100vh;
text-align: center;
}
</style>
components/Todoitem.vue
<template>
<li @click="handleDelete">{{content}}</li>
</template>
<script>
export default {
props:['content','index'],
methods:{
handleDelete(){
//子组件通过事件函数向外传递数据
this.$emit('delete',this.index)
}
}
}
</script>
<style>
</style>
4.3 全局样式与局部样式
vue-cli的作用域,在组件的style标签中添加scoped,可以使得该样式只对这一个组件有效.
<style scoped>
</style>
4.4 课程总结