Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层(HTML+CSS+JS),不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。(官方介绍)
Vue是中国人尤雨溪开发的
前端除了视图层还有网络通信(一般用axios),还有页面跳转(vue-router),状态管理(vuex)
Vue官网
相关原则:
MVVM:
Model-View-ViewModel —— 事件驱动编程方式(主要目的是分离视图和模型)
ViewModel双向绑定层 :ViewModel所封装出来的数据模型包括视图的状态和行为两部分,model层数据模型只包含状态。
一般直接在html中引入Vue就可以直接使用了
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script><!--或者下面的也行-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
使用基本html格式,代码只有
部分<body>
<!--view层 模板-->
<div id="app">
{{message}}//从data中取数据
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm=new Vue({
el:"#app",
//Model:数据
data:{
message:"hello,vue!"
}
});
</script>
<!--view层 模板-->
<div id="app">
<span v-bind:title="message">
鼠标悬停查看动态绑定的信息
</span>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm=new Vue({
el:"#app",
//Model:数据
data:{
message:"hello,vue!"
}
});
</script>
判断:
<!--view层 模板-->
<div id="app">
<h1 v-if="ok">True</h1>
<h1 v-else>No</h1>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm=new Vue({
el:"#app",
//Model:数据
data:{
ok:true
}
});
</script>
循环:
<!--view层 模板-->
<div id="app">
<h1 v-if="type==='A'">A</h1>
<h1 v-else-if="type==='B'">B</h1>
<h1 v-else-if="type==='C'">C</h1>
<h1 v-else>D</h1>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm=new Vue({
el:"#app",
//Model:数据
data:{
type:'A'
}
});
</script>
<!--view层 模板-->
<div id="app">
<button v-on:click="sayHi">click here</button>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm=new Vue({
el:"#app",
//Model:数据
data: {
message:"大海"
},
methods:{//
//方法必须定义在Vue的Method对象种
sayHi:function (){
alert(this.message)
}
}
});
</script>
这里给两个例子
<!--view层 模板-->
<div id="app">
性别:
<input type="radio" name="sex" value="男" v-model="person" />男
<input type="radio" name="sex" value="女" v-model="person" />女
<p>
选中了:{{person}}
</p>
<br />
输入的文本:<textarea v-model="message" ></textarea>{{message}}
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm=new Vue({
el:"#app",
//Model:数据
data:{
message:"",
person:''
}
});
</script>
下拉框的双向绑定:
<!--view层 模板-->
<div id="app">
下拉框:
<select name="" id="" v-model="selected">
<option value="" disabled>---请选择---</option>
<option>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
</select>
<span>value:{{selected}}</span>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm=new Vue({
el:"#app",
//Model:数据
data:{
selected:''
}
});
</script>
组件是可复用的Vue实例,(可重复使用的模板)
<!--
“绑定item的值”也是一个变量,命名为item_bind什么的也行,这里只是方便区别
-->
<!--view层 模板-->
<div id="app">
<!--组件:传递给组件中的值:props-->
<person v-for="item in items" v-bind:绑定item的值="item"></person>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
//定义一个Vue组件component
Vue.component("person",{
props:["绑定item的值"],
template:'{{绑定item的值}} '
});
var vm=new Vue({
el:"#app",
//Model:数据
data:{
items:["java","linux","mac"]
}
});
</script>
Axios 是一个开源的可以用在浏览器端和 NodeJS 的异步通信框架,她的主要作用就是实现 AJAX 异步通信。
需要引入script:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
新建data.json文件
{
"name": "java",
"url": "https://www.baidu.com/",
"page": 1,
"isNonProfit": true,
"address": {
"street": "含光门",
"city": "陕西西安",
"country": "中国"
},
"links": [
{
"name": "B站",
"url": "https://www.bilibili.com/"
},
{
"name": "csdn",
"url": "https://www.csdn.net/"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
demo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<!--view层 模板-->
<!--
ps:这里打开网页会闪烁: {{message.name}}------------》java 加载
手动解决:
<style>
[v-cloak]{
display: none;
}
</style>
打开网页 白屏------------》java 加载
-->
<div id="vue" v-cloak>
<div>{{message.name}}</div>
<div>{{message.address.city}}</div>
<a v-bind:href="message.url">百度</a>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var vm=new Vue({
el:"#vue",
data(){
return{
message:{/*这里直接 message:'' 不写也可以 */
name:null,
city:null,
address:{
street:null,
city:null,
country:null
}
}
}
},
mounted(){//钩子函数 链式编程
axios.get('./data.json').then(response=>(this.message=response.data));
}
});
</script>
</body>
</html>
<!--view层 模板-->
<div id="app">
<!--
currentTime1():是方法,在网页中console.log中调用 vm.currentTime1() 会显示不同的值
currentTime2:是属性 在网页中console.log中调用 vm.currentTime2() 会报错,因为它不是方法,重复调用vm.currentTime2值不会变化
因为currentTime2是属性,计算出来后保存到了内存中 ,和缓存类似,如果 currentTime2内属性值变化 例如:在网页控制台中输入:vm.message="3", currentTime2
会重新计算
-->
<!--
计算属性的主要特征就是为了将不经常变化的计算结果进行缓存,以节约我们的习题开销
-->
<P>currentTime1:{{currentTime1()}}</P>
<P>currentTime2:{{currentTime2}}</P>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm=new Vue({
el:"#app",
data:{
message:"hello,world"
},
methods:{
currentTime1:function (){
return Date.now(); //返回当前一个时间戳
}
},
computed:{// 计算属性: methods. computed 方法不能重名 vm.currentTime2 is not a function currentTime2是属性
currentTime2:function (){
this.message;
return Date.now(); //返回当前一个时间戳
}
}
});
</script>
<!--view层 模板-->
<div id="app">
<!--
网页输出:
<p>列表数据</p>
<ul>
<li>鲁迅</li>
<li>周树人</li>
<li>狂人</li>
</ul>
-->
<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="item in names" :item="item"></todo-items>
</todo>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
//slot:插槽
Vue.component("todo",{
template:
'' +
' ' +
''
+
' ' +
'' +
''
});
Vue.component("todo-title",{
props:['title'],
template: '{{title}}'
});
Vue.component("todo-items",{
props:['item'],
template: '{{item}} '
});
var vm=new Vue({ //Vue有先后顺序,这个要放到最后,不然会报错
el:"#app",
//Model:数据
data:{
title:"列表",
names:['鲁迅','周树人','狂人']
}
});
</script>
<!--view层 模板-->
<div id="app">
<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="(item,index) in names" :item="item"
v-bind:绑定index的值="index" v-on:绑定remove方法="removeItems(index)"></todo-items>
</todo>
</div>
<!--1.导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
//slot:插槽
Vue.component("todo",{
template:
'' +
' ' +
''
+
' ' +
'' +
''
});
Vue.component("todo-title",{
props:['title'],
template: '{{title}}'
});
Vue.component("todo-items",{
props:['item','绑定index的值'],
//只能绑定当前组件的方法
template: '{{绑定index的值}}--{{item}} ',
methods:{
remove:function (绑定index的值){
//this.$emit() 自定义事件分发
this.$emit('绑定remove方法',绑定index的值)
}
}
});
var vm=new Vue({ //据说Vue又先后顺序,这个要放到最后,不然会报错?? 未验证
el:"#app",
//Model:数据
data:{
title:"列表",
names:['鲁迅','周树人','狂人']
},
methods: {
removeItems:function (index){
this.names.splice(index,1); //一次删除下标为index的一个元素
}
}
});
</script>
Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统
全局安装vue-cli:
npm install -g vue-cli
不行用cnpm install -g vue-cli
查看版本:vue -V
新建空文件夹,空文件夹位置打开cmd输入:
vue init webpack myvue
不行的需要用管理员打开cmd
细节:
vue init webpack myvue(文件名)
加载后cmd会显示项目基本信息,选项依次可填:默认 默认 作者名 第一个选项(standalone) no no no no no,i
然后就会生成一个myvue的项目,cmd切换到/myvue文件夹内
终端输入:
npm run dev
网页打开 http://localhost:8080,空的vue-cli运行成功
这里可以用idea开发Vue,直接下载Vue.js插件即可。
如果下载后,新建中没有component选项的解决方案:
Vue Router 是Vue.js(opens new window)官方的路由管理器。
这里简单说一下代码是什么实例:
有很多网站大框架不变,按按钮时只是一块主显示区域刷新,我们用vue-router路由就是想达到相同的效果。
在空的vue-cli项目中:
下载vue-router路由:
npm install vue-router --save-dev
1.在空的vue-cli文件的src/main.js中配置路由
import Vue from 'vue'
import App from './App'
import router from './router' //自动扫描里面的路由配置
Vue.config.productionTip = false // 阻止启动生产消息,默认的
new Vue({
el: '#app',
//配置路由
router,
components: { App },
template: ' '
})
我们现在有三个页面和一个主页面,我们想在主页面中可以通过按钮切换显示其它三个页面
2.三个页面(组件):
Content.vue:
<template>
<h1>一些乱七八糟的内容</h1>
</template>
<script>
export default {
name: "Content"
}
</script>
<style scoped> /* scoped 当前页面起效 */
</style>
Person.vue:
<template>
<h2>person</h2>
</template>
<script>
export default {
name: "person"
}
</script>
<style scoped>
</style>
Main.vue:
<template>
<h1>首页</h1>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>
3.配置导出路由
在 src/ 下新建文件router/index.js
import Vue from "vue";
import VueRouter from "vue-router";
import Content from '../components/Content';
import Main from '../components/Main';
import Person from '../components/Person';
//安装路由
Vue.use(VueRouter);
//配置导出路由
export default new VueRouter({
routes:[
{
//路由路径
path:'/main',
name:'content',
//跳转的组件
component:Main
},
{
//路由路径
path:'/content',
name:'content',
//跳转的组件
component:Content
},
{
//路由路径
path:'/person',
//name可以不用
//跳转的组件
component:Person
}
]
});
4.主页:
<template>
<div id="app">
<h1>Vue-Router</h1>
<router-link to="/main">首页</router-link>
<router-link to="/content">内容页</router-link>
<router-link to="/person">个人页</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {/*默认的主页css,删掉也行*/
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
然后直接在终端(要切到当前根目录)输入:
npm run dev
运行项目(默认: http://localhost:8080)
8080端口被占会顺移端口
ElementUI:适合于Vue的UI框架
官网组件
在src/下新建router,views文件夹
在router/ 下新建index.js文件
在views/ 下新建Main.vue,Login.vue文件
这里先给出完整项目,在介绍相关代码
提前安装一下axios,终端输入:cnpm install --save axios vue-axios
{
"name":"person",
"url": "https://www.baidu.com/",
"page": 1,
"isNonProfit":true,
"address": {
"street": "含光门",
"city":"陕西西安",
"country": "中国"
},
"links": [
{
"name": "B站",
"url": "https://www.bilibili.com/"
},
{
"name": "4399",
"url": "https://www.4399.com/"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
import Vue from 'vue'
import App from './App'
import router from './router'
//导入element-ui和css文件
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios,axios);
Vue.use(router);
Vue.use(ElementUI);
new Vue({
el: '#app',
router,
render:h=>h(App) //ElementUI
})
Main.vue:
<template>
<div>
<el-container>
<el-aside width="200px">
<el-menu :default-openeds="['1']">
<el-submenu index="1">
<template slot="title"><i class="el-icon-caret-right"></i>用户管理</template>
<el-menu-item-group>
<el-menu-item index="1-1">
<!--插入的地方-->
<!-- <router-link to="/user/profile">个人信息</router-link> -->
<!-- name-传组件名 params传递参数,需要对象:v-bind (:to) -->
<router-link :to="{name: 'UserProfile',params: {id: 1}}">个人信息</router-link>
</el-menu-item>
<el-menu-item index="1-2">
<!--插入的地方-->
<router-link to="/user/list">用户列表</router-link>
</el-menu-item>
<el-menu-item index="1-3">
<router-link to="/goHome">回到首页</router-link>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="2">
<template slot="title"><i class="el-icon-caret-right"></i>内容管理</template>
<el-menu-item-group>
<el-menu-item index="2-1">分类管理</el-menu-item>
<el-menu-item index="2-2">内容列表</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="3">
<template slot="title"><i class="el-icon-caret-right"></i>系统管理</template>
<el-menu-item-group>
<el-menu-item index="3-1">用户设置</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header style="text-align: right; font-size: 12px">
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item>退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<!-- <span>{{name}}</span>-->
</el-header>
<el-main>
<!--在这里展示视图-->
<router-view />
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
// props:['name'],
name: "Main"
}
</script>
<style scoped > /*