MVVM源自于经典的MVC (ModI-View-Controller) 模式。MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用
。
1、国内的镜像
<script src="https://cdn.staticfile.org/vue/3.0.5/vue.global.js">script>
2、国外的镜像
<script src="https://unpkg.com/vue@next">script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.5/vue.global.js">script>
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vuetitle>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js">script>
head>
<body>
<div id="vue_det">
<h1>site : {{site}}h1>
<h1>url : {{details()}}h1>
<h1>{{mk()}}h1>
div>
<script type="text/javascript">
var vm = new Vue({
el: '#vue_det',
data: {
site: "倩倩",
url: "www.taobao.com",
alexa: "10000"
},
methods: {
details: function() {
return this.site + "第一个Vue程序";
},
mk:function (){
return "www.baidu.com";
}
},
})
script>
body>
html>
var vm = new Vue({})
el
元素节点,为Vue对象绑定了根DOM元素。Vue 构造器中有一个el 参数,它是 DOM 元素中的 id方式一:new Vue时直接指定el的值
var vm = new Vue({
el: '#vue_det',
data: {
site: "倩倩",
url: "www.taobao.com",
alexa: 1
}
)};
方式二:先new Vue,后期通过vm.$mount(el)指定el的值
var vm = new Vue({
data: {
site: "倩倩",
url: "www.taobao.com",
alexa: 1
}
)};
vm.$mount('#vue_det')
data
数据集合,data 用于定义属性当一个 Vue 实例被创建时,它将 data 对象中的所有的属性加入到 Vue的响应式系统中。当这些属性的值发生改变时,视图将会产生“响应”,更新为最新的值。
但是要注意的是必须是在实例创建的时候就已经存在于data中的属性才是响应式的,如果是在创建实例后追加的属性值,那么他将得不到响应式的更新。
如果你需要在创建实例后才用到某些属性值,那么可以在创建实例的开始就为他赋值为空或者其他的一个初始值。
方式一:data是一个对象
var vm = new Vue({
el: '#vue_det',
data: {
site: "倩倩",
url: "www.taobao.com",
alexa: 1
}
)};
方式二:data是一个函数
var vm = new Vue({
el: '#app',
data() {
return {
title:"王倩老师",
todoItems:['qianqian',"倩倩","王倩倩"]
};
}
});
methods
方法必须定义Vue的Method对象中,用于定义的函数,可以通过 return 来返回函数值template
:用来设置模板,会替换页面元素,包括占位符conputed
:用来计算vender
:创建真正的Virtual Domwatch
:监听data中数据的变化vm.$watch( expOrFn, callback, [options] )
1、第一个参数为表达式或计算属性函数,也可以是一个属性。
2、第二个参数为,触发的回调函数
3、第三个参数为,可添加的选项
{{...}}(双大括号)
的文本插值v-html
指令用于输出 html 代码v-bind
指令v-text
改变指定元素的文本值v-show
是否显示该元素(实质改变display)v-model
指令用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。<div id="app">
<div v-if="type === 'A'">
A
div>
<div v-else-if="type === 'B'">
B
div>
<div v-else-if="type === 'C'">
C
div>
<div v-else>
Not A/B/C
div>
div>
<script>
new Vue({
el: '#app',
data: {
type: 'C'
}
})
script>
这里是引用
<body>
<div id="for_div">
<ol>
<li v-for="s in str">
{{s.name}}
li>
ol>
div>
<script type="text/javascript">
var vm=new Vue({
el:'#for_div',
data:{
str:[
{name:'宝宝'},
{name:'倩倩'},
{name:'好可爱'}
]
}
});
script>
body>
<body>
<div id="for_div">
<ol>
<li v-for="value in object">
{{value}}
li>
ol>
div>
<script type="text/javascript">
var vm=new Vue({
el:'#for_div',
data:{
object:{
name:'倩倩',
age:18,
sex:"女"
}
}
});
script>
body>
<body>
<div id="for_div">
<ol>
<li v-for="(value,key,index) in object">
{{index}}---{{key}}---{{value}}
li>
ol>
div>
<script type="text/javascript">
var vm=new Vue({
el:'#for_div',
data:{
object:{
name:'倩倩',
age:18,
sex:"女"
}
}
});
script>
body>
<div id="for_div">
<ol>
<li v-for="num in 50">
{{num}}
li>
ol>
div>
v-on
:<body>
<div id="app">
<button v-on:click="greet">Greetbutton>
div>
<script>
var app = new Vue({
el: '#app',
data: {
name: 'Vue.js'
},
// 在 `methods` 对象中定义方法
methods: {
greet: function (event) {
// `this` 在方法里指当前 Vue 实例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
}
}
})
script>
body>
<a v-on:click.stop="doThis">a>
<form v-on:submit.prevent="onSubmit">form>
<a v-on:click.stop.prevent="doThat">a>
<form v-on:submit.prevent>form>
<div v-on:click.capture="doThis">...div>
<div v-on:click.self="doThat">...div>
<a v-on:click.once="doThis">a>
注意:v-model其实是一个语法糖,他的背后本质上包含两个操作,v-model相当于v-bind(语法糖为 :)绑定一个value属性,可以实时获取value属性的值和v-on(语法糖为 @)指令给当前元素绑定input事件的结合
$event
获取原生DOM事件的事件对象
v-model
指令在表单控件元素上创建双向数据绑定。<body>
<div id="app">
<p>input 元素:p>
<input v-model="message" placeholder="编辑我……">
<p>消息是: {{ message }}p>
<p>textarea 元素:p>
<p style="white-space: pre">{{ message2 }}p>
<textarea v-model="message2" placeholder="多行文本输入……">textarea>
div>
<script>
new Vue({
el: '#app',
data: {
message: '你好呀!倩倩',
message2: '两个人相互辉映,光芒胜过夜晚繁星'
}
})
script>
body>
label的作用:在有选择框时,如果没有label必须选择选择框才能进行选择,而直接选择文字不可以,反之,label的作用就是在点击文字的同时可以选中选择框,但是要注意的是一般情况下一个label绑定一个input
<body>
<div id="app">
<p>单选框p>
<input type="radio" id="boy" name="sex" value="男" v-model="message">
<label for="boy">男label>
<input type="radio" id="girl" name="sex" value="女" v-model="message">
<label for="girl">女label><br>
<span>您当前选中的内容为:{{message}}span>
<p>复选框p>
<p>单个复选框:p>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}label>
<p>多个复选框:p>
<input type="checkbox" id="baidu" value="baidu" v-model="checkedNames">
<label for="baidu">baidulabel>
<input type="checkbox" id="google" value="Google" v-model="checkedNames">
<label for="google">Googlelabel>
<input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">
<label for="taobao">taobaolabel>
<br>
<span>选择的值为: {{ checkedNames }}span>
div>
<script>
new Vue({
el: '#app',
data: {
message: '',
checked:'',
checkedNames:[]
}
})
script>
body>
<body>
<div id="app">
<select v-model="selected" name="fruit">
<option value="">选择一个网站option>
<option value="www.baidu.com">Baiduoption>
<option value="www.google.com">Googleoption>
select>
<div id="output">
选择的网站是: {{selected}}
div>
div>
<script>
new Vue({
el: '#app',
data: {
selected: ''
}
})
script>
body>
组件可以扩展 HTML 元素,封装可重用的代码,
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树
Vue.component(tagName, options)
tagName 为组件名,options 为配置选项。注册后,我们可以使用以下方式来调用组件:
<body>
<div id="app">
<box>box>
div>
<script>
Vue.component("box",{
template:"自定义组件
"
});
new Vue({
el: '#app',
data: {
message:["qianqian","xiangni","xixi"]
}
})
script>
body>
<body>
<div id="app">
<box>box>只可以在父模块中使用
div>
<box>box>这个标签则不可以使用
<script>
var Child = {
template: '自定义组件!
'
}
// 创建根实例
new Vue({
el: '#app',
components: {
// 将只在父模板可用,只能在他对应的el中使用
'box': Child
}
})
script>
body>
为什么组件中的data的属性必须是一个函数呢
父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明
“prop”:<body>
<div id="app">
<child message="hello!">child>
div>
<script>
// 注册
Vue.component('child', {
// 声明 props
props: ['message'],
// 同样也可以在 vm 实例中像 “this.message” 这样使用
template: '{{ message }}'
})
// 创建根实例
new Vue({
el: '#app'
})
script>
body>
<body>
<div id="app">
<div>
<input v-model="parentMsg">
<br>
<child v-bind:message="parentMsg">child>
div>
div>
<script>
// 注册
Vue.component('child', {
// 声明 props
props: ['message'],
// 同样也可以在 vm 实例中像 “this.message” 这样使用
template: '{{ message }}'
})
// 创建根实例
new Vue({
el: '#app',
data: {
parentMsg: '父组件内容'
}
})
script>
body>
<body>
<div id="app">
<box v-for="person in qianqian " v-bind:str="person">box>
div>
<script>
Vue.component("box",{
props:["str"],
template:"{{str}} "
});
new Vue({
el:"#app",
data:{
qianqian:{
name:"倩倩",
age:18,
sex:"仙女"
}
}
});
script>
body>
注意:父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!
$on(eventName)
监听事件,监听当前实例上的自定义事件。事件可以由 vm.$ emit触发。回调函数会接收所有传入事件触发函数的额外参数$emit(eventName)
触发事件,Vue子组件向父组件传值<body>
<div id="app">
<div id="counter-event-example">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
</div>
<script>
Vue.component('button-counter', {
template: '',
data: function () {
return {
counter: 0
}
},
methods: {
incrementHandler: function () {
this.counter += 1
this.$emit('increment')
}
},
})
new Vue({
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})
</script>
</body>
<body>
<div id="app">
<cpn @item-click="cpnClick">cpn>
div>
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnClick(item)">{{item.name}}button><br/>
div>
template>
<script type="text/javascript">
//创建子组件
const sonCpn={
//关联字符串模板
template:'#cpn',
//子组件的data必须是函数function而不能是对象
data(){
return {
categories:[
{id:'aa',name:'热门推荐'},
{id:'bb',name:'手机数码'},
{id:'cc',name:'家用电器'},
{id:'dd',name:'电脑显卡'},
]
}
},
methods:{
//创建子组件向父组件传值的事件响应函数
btnClick(item){
//向父组件传值,定义一个子组件发出的自定义事件(itemClick)
//第一个参数是自定义事件名
//第二个参数是发射出去的信息,传给父组件的监听函数
this.$emit('item-click',item)
}
}
}
var app=new Vue({
el:"#app",
data:{
},
methods:{
//创建父组件的监听函数,item是子组件$emit()传递过来的值
cpnClick(item){
console.log(item.name);
}
},
components:{
'cpn':sonCpn//这里也可以直接按es6的写法,写为cpn
}
}
);
script>
body>
第一步:子组件通过自定义事件获取到要传递给父组件的数据
第二步:子组件通过this.$emit(‘item-click’,item)将数据发出
第三步:父组件通过@item-click="cpnClick"接收数据
第四步:父组件使用自己的方法cpnClick进行数据处理
突出在属性
两个字上(属性是名词),首先它是个属性,其次这个属性有计算的能力
(计算是动词),这里的计算就是个函数
,简单的说,他就是一个能够将计算结果缓冲起来的属性(将行为转化成了静态的属性)。<body>
<div id="app">
<p>原始字符串: {{ message }}p>
<p>计算后反转字符串: {{ reversedMessage }}p>
div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: '123456789'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
});
script>
body>
computed 是基于它的依赖缓存
,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行
。computed属性:
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
methods属性:
methods: {
reversedMessage2: function () {
return this.message.split('').reverse().join('')
}
}
vm.$watch( expOrFn, callback, [options] )
1、第一个参数为表达式或计算属性函数,也可以是一个属性。
2、第二个参数为,触发的回调函数
3、第三个参数为,可添加的选项
<body>
<div id="app">
<p>原始字符串: {{ message }}p>
<p>计算后反转字符串: {{ reversedMessage }}p>
div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: '123456789'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
},
});
vm.$watch("message",function (newVal,oldVal) {
alert("message的值由"+oldVal+"变为"+newVal);
});
script>
body>
<body>
<div id="app">
<p>原始字符串: {{ message }}p>
<p>计算后反转字符串: {{ reversedMessage }}p>
div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: '123456789'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
},
watch:{
message:{
handler:function (newVal,oldVal) {
alert("message的值由"+oldVal+"变为"+newVal);
}
}
}
});
script>
body>
<body>
<div id = "computed_props">
千米 : <input type = "text" v-model = "kilometers">
米 : <input type = "text" v-model = "meters">
div>
<p id="info">p>
<script type = "text/javascript">
var vm = new Vue({
el: '#computed_props',
data: {
kilometers : 0,
meters:0
},
methods: {
},
computed :{
},
watch : {
kilometers:function(val) {
this.kilometers = val;
this.meters = this.kilometers * 1000
},
meters : function (val) {
this.kilometers = val/ 1000;
this.meters = val;
}
}
});
// $watch 是一个实例方法
vm.$watch('kilometers', function (newValue, oldValue) {
// 这个回调将在 vm.kilometers 改变后调用
document.getElementById ("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
})
script>
body>
class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性。
Vue.js v-bind 在处理 class 和 style 时, 专门增强了它。表达式的结果类型除了字符串之外,还可以是对象或数组。
我们可以为 v-bind:class
设置一个对象,从而动态的切换 class:
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
style>
<body>
<div id="app">
<div v-bind:class="{ 'active': isActive }">div>
div>
<script>
new Vue({
el: '#app',
data: {
isActive: true
}
})
script>
body>
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
.text-danger {
background: red;
}
style>
head>
<body>
<div id="app">
<div class="static"
v-bind:class="{ 'active': isActive, 'text-danger': hasError }">
div>
div>
<script>
new Vue({
el: '#app',
data: {
isActive: true,
hasError: true
}
})
script>
body>
我们也可以在这里绑定返回对象的计算属性。这是一个常用且强大的模式
我们可以把一个数组传给 v-bind:class
<body>
<div id="app">
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鸟教程div>
div>
<script>
new Vue({
el: '#app',
data: {
activeColor: 'green',
fontSize: 30
}
})
script>
body>
插槽就是子组件中的提供给父组件使用的一个占位符,用
表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的
标签。
<body>
<div id="app">
<input v-size>
</div>
<script type="text/javascript">
//注册一个全局指令
Vue.directive('size',{
// 当绑定元素插入到 DOM 中。
inserted:function (el) {
el.focus()
}
});
new Vue({
el:'#app'
});
</script>
</body>
<body>
<div id="app">
<p>页面载入时,input 元素自动获取焦点:</p>
</div>
<input v-focus>此时这里不可以使用指令
<script>
// 创建根实例
new Vue({
el: '#app',
directives: {
// 注册一个局部的自定义指令 v-focus
focus: {
// 指令的定义
inserted: function (el) {
// 聚焦元素
el.focus()
}
}
}
})
</script>
</body>
bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
unbind: 只调用一次, 指令与元素解绑时调用。
1、el: 指令所绑定的元素,可以用来直接操作 DOM 。
2、binding: 一个对象,包含以下属性:
name: 指令名,不包括 v- 前缀。
value: 指令的绑定值, 例如: v-my-directive="1 + 1", value 的值是 2。
oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression: 绑定值的表达式或变量名。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"。
arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 "foo"。
modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
3、vnode: Vue 编译生成的虚拟节点。
4、oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
<div id="app" v-runoob:hello.a.b="message">
</div>
<script>
Vue.directive('runoob', {
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '
' +
'value: ' + s(binding.value) + '
' +
'expression: ' + s(binding.expression) + '
' +
'argument: ' + s(binding.arg) + '
' +
'modifiers: ' + s(binding.modifiers) + '
' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#app',
data: {
message: '菜鸟教程!'
}
})
</script>
1、vue-cli 官方提供的一个脚手架,用于快速生成一个 vue 的项目模板;
2、预先定义好的目录结构及基础代码,就好比咱们在创建 Maven 项目时可以选择创建一个骨架项目,这个骨架项目就是脚手架,我们的开发更加的快速;
2、安装淘宝镜像:npm install cnpm -g
cd myvue
npm install 初始化项目
npm run dev
npm install -g @vue/cli
npm run serve
vue ui
管理配置文件1、本质上,webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler)。当webpack处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle.
2、Webpack是当下最热门的前端资源模块化管理和打包工具,它可以将许多松散耦合的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分离,等到实际需要时再异步加载。通过loader转换,任何形式的资源都可以当做模块,比如CommonsJS、AMD、ES6、 CSS、JSON、CoffeeScript、LESS等;
3、伴随着移动互联网的大潮,当今越来越多的网站已经从网页模式进化到了WebApp模式。它们运行在现代浏览器里,使用HTML5、CSS3、ES6 等新的技术来开发丰富的功能,网页已经不仅仅是完成浏览器的基本需求; WebApp通常是一个SPA (单页面应用) ,每一个视图通过异步的方式加载,这导致页面初始化和使用过程中会加载越来越多的JS代码,这给前端的开发流程和资源组织带来了巨大挑战。
4、前端开发和其他开发工作的主要区别,首先是前端基于多语言、多层次的编码和组织工作,其次前端产品的交付是基于浏览器的,这些资源是通过增量加载的方式运行到浏览器端,如何在开发环境组织好这些碎片化的代码和资源,并且保证他们在浏览器端快速、优雅的加载和更新,就需要一个模块化系统,这个理想中的模块化系统是前端工程师多年来一直探索的难题。
npm install webpack -g
npm install webpack-cli -g
//暴露模块
exports.sayHi=function () {
document.write("王倩倩
")
}
//引入模块
var hello=require("./hello");
hello.sayHi();
module.exports={
entry:'./modules/main.js',
output:{
filename:"./js/bundle.js"
}
};
注意
1、如果是 v4.0.0 以上版本的 webpack,可以不使用配置文件配置 webpack ,使用官网推荐的使用 ./src/index.js 作为入口点
2、官方中明确说明,如果使用配置文件使用 webpack 打包项目,则文件名是 webpack.config.js 。
3、检查 webpack.config.js 的路径是否出错,webpack.config.js 必须是放在根目录下
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="dist/js/bundle.js">script>
head>
<body>
body>
html>
模块化开发
块的内部数据与实现是私有的
, 只是向外部暴露一些接口(方法)
与外部其它模块通信Vue.js 路由允许我们通过不同的 URL 访问不同的内容。
< router-link>
是一个组件,该组件用于设置一个导航链接,切换不同 HTML 内容。 to 属性为目标地址, 即要显示的内容,< router-link> 默认会被渲染成一个 标签
< router-view>
路由匹配到的组件将渲染在这里
npm install vue-router --save-dev
import Vue from 'vue'
import VueRouter from 'vue-router'
//导入自己所需的组件
import Content from "../components/Content";
import Main from "../components/Main";
//安装路由
Vue.use(VueRouter);
//配置导出路由
export default new VueRouter({
routes:[{
//路由的路径
path:'/content',
name:'content',
//跳转的组件
component:Content
},
{
path:'/main',
name:'content',
//跳转的组件
component:Main
}
]
});
注意:router必须放到components: { App },的前边
import Vue from 'vue'
import App from './App'
import router from './router'//自动扫描里面的路由配置
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
//配置路由
router,
components: { App },
template: ' '
})
< template>:所有的元素必须在根节点下
实际应用界面,通常由多层嵌套的组件组合而成。children属性
比如,我们 “首页”组件中,还嵌套着 “登录”和 “注册”组件,那么URL对应就是/home/login和/home/reg。
<template>
<h1>个人信息</h1>
</template>
<script>
export default {
name: "UserProfile"
}
</script>
<style scoped>
</style>
<template>
<h1>用户列表</h1>
</template>
<script>
export default {
name: "UserList"
}
</script>
<style scoped>
</style>
<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>
</el-menu-item>
<el-menu-item index="1-2">
<!--插入的地方-->
<router-link to="/user/list">用户列表</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-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>
</el-header>
<el-main>
<!--在这里展示视图-->
<router-view />
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped lang="scss">
.el-header {
background-color: #B3C0D1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
//导入vue
import Vue from 'vue';
import VueRouter from 'vue-router';
//导入组件
import Main from "../views/Main";
import Login from "../views/Login";
//导入子模块
import UserList from "../views/user/List";
import UserProfile from "../views/user/Profile";
//使用
Vue.use(VueRouter);
//导出
export default new VueRouter({
routes: [
{
//登录页
path: '/main',
component: Main,
// 写入子模块
children: [
{
path: '/user/profile',
component: UserProfile,
}, {
path: '/user/list',
component: UserList,
},
]
},
//首页
{
path: '/login',
component: Login
},
]
})
< template>:所有的元素必须在根节点下
{
path: '/user/profile/:id',
name:'UserProfile',
component: UserProfile
}
<!--name是组件的名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定-->
<router-link :to="{name:'UserProfile',params:{id:1}}">个人信息</router-link>
<template>
<!-- 所有的元素必须在根节点下-->
<div>
<h1>个人信息</h1>
{{$route.params.id}}
</div>
</template>
{
path: '/user/profile/:id',
name:'UserProfile',
component: UserProfile,
props: true
}
<!--name是组件的名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定-->
<router-link :to="{name:'UserProfile',params:{id:1}}">个人信息</router-link>
<template>
<div>
个人信息
{{ id }}
</div>
</template>
<script>
export default {
props: ['id'],
name: "UserProfile"
}
</script>
<style scoped>
</style>
重定向的意思大家都明白,但 Vue 中的重定向是作用在路径不同但组件相同的情况下
{
path: '/main',
name: 'Main',
component: Main
},
{
path: '/goHome',
redirect: '/main'
}
说明:这里定义了两个路径,一个是 /main ,一个是 /goHome,其中 /goHome 重定向到了 /main 路径,由此可以看出重定向不需要定义组件;
<el-menu-item index="1-3">
<router-link to="/goHome">回到首页</router-link>
</el-menu-item>
路由模式有两种
注意:默认为hash,若是要使用history需要mode: 'history'
<template>
<div>
<h1>404,你的页面走丢了</h1>
</div>
</template>
<script>
export default {
name: "NotFound"
}
</script>
<style scoped>
</style>
import NotFound from '../views/NotFound'
{
path: '*',
component: NotFound
}
beforeRouteEnter:在进入路由前执行
beforeRouteLeave:在离开路由前执行
export default {
name: "UserProfile",
beforeRouteEnter: (to, from, next) => {
console.log("准备进入个人信息页");
next();
},
beforeRouteLeave: (to, from, next) => {
console.log("准备离开个人信息页");
next();
}
}
参数说明:
to:路由将要跳转的路径信息
from:路径跳转前的路径信息
next:路由的控制参数
next() 跳入下一个页面
next(’/path’) 改变路由的跳转方向,使其跳到另一个路由
next(false) 返回原来的页面
next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例
Axios是一个开源的可以用在浏览器端和NodeJS 的异步通信框架,她的主要作用就是实现AJAX异步通信
JS中链式编程
]由于Vue.js是一个视图层框架且作者(尤雨溪) 严格准守SoC (关注度分离原则),所以Vue.js并不包含AJAX的通信功能,为了解决通信问题,作者单独开发了一个名为vue-resource的插件,不过在进入2.0 版本以后停止
了对该插件的维护并推荐了Axios 框架。少用jQuery,因为它操作Dom太频繁!
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js">script>
<script src="node_modules/axios/dist/axios.js">script>
head>
<body>
<div id="app">
{{info.name}}
div>
<script type="text/javascript">
var vm=new Vue({
el:'#app',
data(){
//请求的返回参数必须和json字符串一样
return {
info:{
name:null,
url:null,
address:{
street:null,
city:null
}
}
}
},
mounted(){
axios.get('/myWebpack/modules/data.json').then(response=>(this.info=response.data))
}
});
script>
body>
html>