专门用于发ajax请求的库, 本身与vue并没有关系,在其他没有使用vue的项目同样可以使用
-
常规发请求的写法
axios({ url: '/question', method: 'get', // get/post parms:{}, // method为'get'时使用这个写参数! data:{} // method为'post'是使用这个写参数 }).then
-
get请求简写1
axios.get('/question?id=998') .then(function (response) { // 请求成功的回调函数 console.log(response); }) .catch(function (error) { // 请求失败的回调函数 console.log(error); });
-
get请求简写2
// 发送get请求时,也可以将url中的参数,以key,value的形式写在params属性中 // axios在发出请求之前,会自动将参数拼接到请求地址上去 axios.get('/question', { params: { id: 12345 } }) .then(function (response) { console.log(response) }) .catch(function (error) { console.log(error) })
-
post请求简写
axios.post('/question', { age: 18, name: '小明' }) .then(function (response) { console.log(response) }) .catch(function (error) { console.log(error) })
详情见
01.data-bind
文件夹中代码!
- v-model
- v-text
Object.defineProperty 方法,是es6(ECMAScript 2015) 中定义的的方法, 作用是为指定的对象定义一个新的属性. 以前我们给一个对象添加一个属性直接
obj.xx = yy
这样就可以了,这样很灵活,xx
可以被随意的修改或者删除,但是有时候我并不希望这样。 通过Object.defineProperty方法定义的属性的值默认是【不可以】被修改的!,强调是【不可以】,【不可以】,【不可以】 Object.defineProperty 需要开发者提供一个get,和set方法, 假如
Object.defineProperty(对象, 属性名, 描述)
方法的参数1: 是我们想要为其添加属性的对象
方法的参数2: 是我们想要添加的属性
方法的参数3: 也是一个对象,开发者可以给该对象指定一个get方法和set方法,称之为getter,setter。
我们先往下看,慢慢的了解这个get和set方法有什么作用
var vm = {}
Object.defineProperty(vm, 'name', {}) // 给vm对象添加了一个属性name, 它的值为undefined
// 尝试着修改vm.name 的值
vm.name = 18
console.log(vm.name) // undefined 输出的还是undefined,也就是说上一句的赋值操作并没有生效
我们给第三个参数添加get,set 方法
var vm = {}
Object.defineProperty(vm, 'name', {
get: function () {
console.log('get方法执行了')
},
set: function (val) {
console.log(val)
console.log('set方法执行了')
}
})
vm.name = 18
console.log(vm.name) // undefined 输出的还是undefined
// 但是执行 `vm.name = 18`时set方法执行了,且参数val就是18
// 执行console.log(vm.name)时 get方法执行了,输入的值是undefined, 这个undefined其实是get方法的返回值(没有return 则返回undefined)
在get 方法中 随便 return 一个值
var vm = {}
Object.defineProperty(vm, 'name', {
get: function () {
console.log('get方法执行了')
return '输出的是这里return的值'
},
set: function (val) {
console.log(val)
console.log('set方法执行了')
}
})
vm.name = 18
console.log(vm.name) // '输出的是这里return的值'
可以将js中的数据自动呈现到dom, 并且当我们修改了js中的数据之后,页面的数据也会跟着自动变化, 这种现象叫做单向数据绑定(与具体的实现技术无关,只是给这个现象起了个名字)
不仅仅,可以将js中的数据自动呈现到dom, 并且当我们修改了js中的数据之后,页面的数据也会跟着自动变化, 这种现象叫做单向数据绑定,
而且,如果页面中的数据改变了,js中的数据也自动改变了,这种现象,称之为双向数据绑定(双边数据绑定)
详情 demo/02.getter-setter/c.getter-setter-data-bind
中的代码
定义:
如果有一个变量name,我们把这个name的值渲染到input中,如果通过写代码能够达到如下效果,则称之为双向数据绑定:
当修改name的值时(如: name = 18), input中的的值自动更新为name的最新值(也能变为18)。
并且, 当我们通过鼠标或者键盘修改input的中的值时(如修改为 99), name变量的值也能自动变为 99。
使用前准备步骤:
- 新建一个html文件
- 引入vue.js文件(引入后会有个全局变量Vue,是个构造函数)
- 创建Vue的实例
var vm = new Vue({})
, 参数是个对象,暂时先传递一个空对象 - 将实例作用于指定的dom
vm.$mount('选择器')
vue中对html中特定的属性做了专门的处理,使得这些属性可以方便开发都书写项目,这些特殊的属性,我们称之为指令! 补充: vue 的指令中除了直接写固定值外,还可以书写js表达式
在Vue的指定中可以直接书写js表达式
, 普通属性中写js表达式是无效的
作用: 将数据渲染到html中(注意: 以下指令无法将数据渲染到标签的属性中)
详见03.v-text,v-html,{{}}
文件夹中参考代码
- v-text指令
- v-html指令
- {{}}指令
指令中也可以调用方法,但是方法必需申明在methods中!
v-text
与{{}}
及v-html
的区别:v-text
是写在标签的属性上的,v-text
指定的表达式的值会被赋值标签的innerText{{}}
是写在非标签的属性位置,{{}}
指定的表达式的值会替换 {{}} 本身!v-html
也是写在标签的属性上的,v-html
指定的表达式的值会被赋值给标签的innerHTML
v-text, v-html, {{}}
的能力确实很强大!, 但是他们只能将数据渲染到标签之间位置!
只能将指定的数据赋值给标签的innerText或者 innerHTML, 但是如果我想给标签的某个属性赋值呢?
如果需要给标签的某个属性赋值就需要使用v-bind指令了! 作用: 将js表达式的结果赋值给指定的标签的属性
- v-bind
语法:
<div v-bind:要设置的属性名="js表达式"></div>
<div id="app">
<!--未使用v-bind时 -->
<h1 tmp="dataA" id="dataB" test="dataC"></h1>
<img src="dataD">
<hr>
<!--使用v-bind时 -->
<h1 v-bind:tmp="dataA" v-bind:id="dataB" v-bind:test="dataC"></h1>
<img v-bind:src="dataD">
<!--v-bind简写,简写就是把v-bind去除,只保留一个冒号 -->
<h1 :tmp="dataA" :id="dataB" :test="dataC"></h1>
<img :src="dataD">
</div>
var vm = new Vue({
data: function () {
return {
dataA: 18,
dataB: 19,
dataC: '嘻嘻',
dataD: './three-lifetimes.jpeg'
}
}
})
vm.$mount('#app')
当v-bind用来给class属性赋值时,使用方式有些特殊,这是需要注意的!
示例代码如下: 详见04.v-bind/b.class.v-bind.html
<div id="app">
<!--将 'red' 值追加给 class属性 -->
<h3 v-bind:class=" 'red' ">我是中国人,我爱自己的祖国!</h3>
<!--注意空格 -->
<!--将 'red' + ' active'的值追加给class属性: 'red active' -->
<h3 v-bind:class=" 'red' + ' active'">我是中国人,我爱自己的祖国!(注意空格)</h3>
<!-- 将dataC的值,追加给class, 也就是将'red'追加给class -->
<h3 v-bind:class="dataA">我是中国人,我爱自己的祖国!</h3>
<hr>
<!--接下来是高级用法了 -->
<!--Vue内部会找到obj对象, 遍历obj, 如果属性的值为true, Vue就会将属性名(注意,这里说的是属性名),追回给class属性 -->
<div v-bind:class="obj">我是中国人,我爱自己的祖国</div>
<!--或者这样写也可以 -->
<div v-bind:class="{red: true, active: true, hello: false}">我是中国人, 我爱自己的祖国</div>
</div>
var vm = new Vue({
data: function () {
return {
dataA: 'red',
obj: {red: true, active: true, hello: false}
}
}
})
vm.$mount('#app')
这是vue提供的一种,更轻松的让dom元素显示或者隐藏的方式
- v-show
- v-if/v-else v-else所在标签的前一个兄弟标签,必需要有v-if
根据数据自动生成多个标签标签
比如: 可以根据数组[1,2,3,4] 自动生成四个标签
- v-for
- 数组
- 整数
将数据与表单控件进行绑定(如input,select)
- v-model
Vue允许开发者使用
v-on
属性来快捷的注册事件
v-on
- 语法:
<div v-on:事件名="js表达式"></div>
, 当事件被触发时,这里的js表达式才会被执行
这里以注册点击事件为例:详见
04.v-one/a.event.html
<div id="app">
{{count}} <br>
<!--属性值依然写js表达式,点击按钮时,这个表达式就会执行 -->
<button v-on:click="count = count + 1">值+1</button>
<!--当点击按钮时就会执行helloA方法, -->
<!--如果调用方法时,如果不需要传递参数给该方法,就可以省略括号 -->
<button v-on:click="helloA">点击事件</button>
<!--如果调用方法时,需要传递参数给该方法时,就不能省略括号 -->
<button v-on:click="helloB(99, '小明', {a:1,b:2}, count)">点击事件</button>
<button v-on:click="helloC">查看事件回调函数中的this</button>
<!--注册事件时,v-on指令可以简写,就是把 v-on: 简写为一个 @ 符号, 其他地址不变 -->
<button @click="helloB(99, '小明', {a:1,b:2}, count)">简写</button>
</div>
var vm = new Vue({
// 数据放在data中
data: function () {
return {
count: 1
}
},
// 方法放在methods中
methods: {
helloA: function () {
window.alert('hello word!')
},
helloB: function (argA, argB, argC, argD) {
console.log(argA, argB, argC, argD)
},
helloC: function () {
console.log(this)
// Vue会将每一个通过v-on注册的事件回调函数中的this更改为Vue的实例,也就是这里的vm
console.log(this === vm) // true
this.count = 99
}
}
})
vm.$mount('#app')
将上述代码添加到html中, 然后点击不同的按钮查看效果!
示例: 点击值 +1, 大于10时,隐藏某个元素, 点击值 -1, 小于10时,显示某个元素
- .stop :event.stopPropagation()阻止单击事件冒泡
- .prevent :调用 event.preventDefault()
- .capture :添加事件侦听器时使用 capture(捕获) 模式
- .self :只当事件在该元素本身(而不是子元素)触发时触发回调
- .once :只在指定按键上触发回调
- 修饰符串联写法 :v-on:click.stop.prevent
- 只有修饰符 :
按方向键移动飞机
- .enter(按回车键捕获)
- .tab(按tab键捕获)
- .esc(按esc键捕获)
- .space(按空格键捕获)
- .up(按↑键捕获)
- .down(按↓键捕获)
- .left(按←键捕获)
- .right(按→键捕获)
- .ctrl(按ctrl键捕获)
- .alt(按alt键捕获)
- .shift(按shift键捕获)
- .字母(1.0.8+: 支持单字母按键别名)
- 1.0.17+: 可以自定义按键别名:写法:Vue.directive('on').keyCodes.f1 = 112
作用: 在数据被渲染之前,可以对其进行进一步处理,比如将字符反转,或者将小写统一转换为大写等!
过滤器本身就是一个方法
示例1: 在消息展示之前将其反转!
<div id="app">
<p>
<!-- 这里的意思是调用 filters中的 reverse方法,并将msg传递过去: reverse(msg)-->
{{msg | reverse}
</p>
</div>
var vm = new Vue({
data: function () {
return {msg: 'WoShiZhongGuoRen'}
},
// 过滤器函数都定义在filters属性中,一个属性(方法)就是一个过滤器
filters: {
reverse: function (val) {
// 反转val字符串
return val.split('').reverse().join('')
}
}
})
渲染后的结果
<div id="app">
<p>
enRouGgnohZihSoW
</p>
</div>
示例2: 将字母转换为大写
就是在数据展示之前,将数据改成别的形式展示(不会影响原数据)
ABC => ccc
123.998 => 124.0
如果想精确的控制一个数据的变化, 并在变化时做一些操作,则可以使用计算属性! 比如,想要在用户输入用户名时,实时的判断用户名是否符合要求
// 定义计算属性
var vm = new Vue({
data: function () {
// 用户名
username: ''
}
computed: {
// 属性也是一个对象,这个对象有两个属性,
// get和set方法中的this就是vm
// 如果只用一个get,可以可以设置myname为一个函数,这个函数就是get
// 使用时,就把这当作data中的属性去用就可以了
myname: {
get: function () {
return this.username // 这里this就是vm
},
set: function (val) {
this.username = val
}
}
}
})
//myname: function () {} 这个就相当于下面的写法
myname: {
get: function () {}
}
$refs
$el
$emit
和$on
Vue中的代码在从开始执行,到执行结束,期间,它会不断的调用一些特定的方法, 这个过程叫做生命周期!
Vue中这个过程中调用的方法我们叫做生命周期函数(生命周期钩子函数)
mounted, created
-
beforeCreated () {}
Vue在代理data及methods, computed中属性之前会先调用一下beforeCreated 方法, 此时Vue的实例虽然已经创建完成,但是由于还没有代理data中的属性,所以也就无法通过
this.xx
使用data中数据了var vm = new Vue({ el: '#app', data: function () { return {name: '小明'} }, beforeCreate: function () { this.name = '小红' // 这句话执行之后,仅仅是让this.name属性值为小红, 并没有对 data中的name产生影响 } })
-
created () {}
Vue在代理了data及methods,computed中的属性之后会调用created方法,此时可以通过
this.xx
来使用data中的属性了var vm = new Vue({ el: '#app', data: function () { return {name: '小明'} }, created: function () { // 此时由于 vm 已经代理了data中的数据, this.name='小红'执行之后,data中的name也会变成小红 this.name = '小红' } })
-
beforeMount () {}
Vue在将模板插入到dom中之前会先调用一下, beforeMount方法
-
mounted () {}
当vue会在自己所操作的dom部分解析完成之后, 自动调用mounted 方法
如果些方法,没有执行,则说明dom树没有渲染完成!
假设我们想在页面加载完成就上input获取焦点,可以这么做:
<div id="app"> <input id="ipt"> </div>
var vm = new Vue({ el: '#app', created: function () { // 这个方法里不可以操作#app 之内的dom,因为此时dom树还没有创建完成! //var oIpt = document.getElementById('ipt') }, mounted: function () { // 此时可以操作dom了 var oIpt = document.getElemnetById('ipt') oIpt.focus() // 获取焦点 } })
-
beforeUpdate () {}
当我们修改data中的数据之后,Vue就会立即将修改后的数据更新到dom中,但是在更新之前它会调用一下beforeUpdate 方法。
也就是说在这个beforeUpdate方法执行时,页面中的数据与data中的数据并不是完全一致的!
-
updated () {}
当我们修改data中的数据之后,Vue就会立即将修改后的数据更新到dom中, 在更新好dom之后,它就会立即调用updated方法,此时页面中的数据与data中的数据是100%一致的
-
beforeDestroy () {}
当我们调用
this.$destroy
方法,Vue就会自动调用beforeDestroy方法,该方法执行之后Vue会将通过Vue注册的事件取消,所有的通过Vue实现的数据绑定与事件将不再生效 -
destroyed () {}
Vue在取消了数据绑定及dom和取消事件监听之后就会调用这个destroyed方法
它是一种开发思想, 是一种新的开发时的思维方式!
通过Vue.component('组件名', {
template: ''
})创建的组件叫作全局组件!
全局组件可以在任何组件的模板中直接使用
包含了template的对象就称之为局部组件
局部组件只能在引入这个组件的组件的模板中使用(也要配置别名)
本质上是局部组件,只是换了一种写法!
通过props可以让子组件在被其他组件使用时,接收到到其他组件写在子组件标签上的属性值!
// Father.vue
<template>
<div>
<h1>
假设这是Father组件
</h1>
<!-- 下面准备使用子组件,并随意添加一些属性,可以直接像给普通html添加属性的方式一样添加属性
也可以通过 v-bind 指令添加属性,或者通过v-bind的简写方式 : 冒号来添加属性 -->
<!-- 这些属性在【特定的情况】下将被赋值给这个Son组件的实例对象的同名属性(即Son实例.sex === '测试sex' ...)-->
<Son sex="测试sex" v-bind:sexa=" '1' + 1" :sexb=" '测试sexb' " :sexc=" '测试c' " :name="name" :others="others" othersb="{a:1,b:2}"></Son>
</div>
</template>
<script>
import Son from './Son.vue'
export default {
components: {
Son: Son
},
data: function () {
return {
name: '小明你好',
age: 18,
others: { girFriend: '小红', boyFriend: '小天'}
}
}
}
</script>
// Son.vue
<template>
<h1>
假设这是Son组件
</h1>
</template>
<script>
export default {
// <Son sex="测试sex" v-bind:sex2=" '1' + 1" :sex3=" '测试sex3' " :sex4=" '测试4' " :name="name" :others="others"></Son>
// 这个有这个props属性就是上面的特定情况, <Son sex="测试sex"></Son> 标签中的属性名如果被包含在这个props数组中, 那么Vue内部就会将这个属性的值赋值给这个Son组件实例的【同名属性】
// 例: Son标签中有个sex属性,值为'测试sex',由于sex被包含在了props中,则它会被赋值给Son实例的的sex属性: 即
// Son实例.sex = '测试sex'
props: ['sex', 'sexa', 'sexb', 'name', 'others', 'othersb'],
created: function () {
console.log(this.sex) // '测试sex'
console.log(this.sexa) // '11'
console.log(this.sexb) // '测试sexb'
console.log(this.sexc) // undefined
console.log(this.name) // '小明你好'
console.log(this.others) // { girFriend: '小红', boyFriend: '小天'}
console.log(this.othersb) // {a:1,b:2}
}
}
</script>
什么是自定义事件?
也提供一个事件名,和一个事件的回调函数!, 通过代码来让事件触发
自定义事件的本质就是让一个名字和方法关联起来了
var obj = {
// 自定义了一个事件叫test
test: function () {
console.log('你好')
}
}
// 封装一个用于定义事件的函数
// 事件要用名字和函数
function on(eventName, callback) {
//obj.eventName
obj[eventName] = callback
}
// obj.test() // 触发了一个事件
// 封装一个触发事件的方法
function emit(eventName) {
//obj[]//
var fn = obj[eventName]
fn()
}
on('chifan', function () {aler(1)})
// 触发事件
emit('chifan')
什么是事件? 发生的事情 v-on:click @click @xxxx
通过自定义事件,也可以实现两个组件之间数据的传递, 可以通过
v-on:
指令来给某个组件自定义事件
// Father.vue
<template>
<div>
<h1>
这是Father组件
</h1>
<!-- 使用v-on:指定可以给Son组件添加自定义事件, 只要事件名不要和html原本的事件一样就可以-->
<!-- 例如: 咱们这里自定义一个名为test的事件(如果不想用test,自己换个别的名字就可以了)-->
<!-- 疑问: 如果是注册的click,我们是通过点击该元素来触发的, 那么这个自定义事件test何时才会触发呢?
回答: 如果要触发Son标签上写的这个v-on:test事件,需要在Son组件的js代码中调用Son组件实例的 $emit方法,
只要这个 Son实例的$emit方法一调用,这个test事件就会被触发, 触发之后,test事件的回调函数testHandler也就会被执行了!
-->
<!-- v-on: 可以用 @ 来代替-->
<Son @test="testHandler" @test2="testHandler2"></Son>
</div>
</template>
<script>
import Son from './Son.vue'
export default {
components: {
Son: Son
},
data: function () {
return {}
},
methods: {
testHandler: function (arg) {
console.log(arg)
},
testHandler2: function (arg) {
console.log(arg)
}
}
}
</script>
// Son.vue
<template>
<div>
<h1>
这是Son组件
</h1>
<button @click="clickHandler">演示用的按钮</button>
</div>
</template>
<script>
export default {
created: function () {
// 调用Son组件的实例来触发test事件,调用一次就会触发一次,调用两就会触发两次!
// $emit方法参数:
// 参数1: String, 值是要触发的事件名
// 参数2: Any, 值会被作为参数传递给test事件的回调函数!
this.$emit('test', 998) // 这里的 998 就会被传递给Father.vue中的testHandler 方法
this.$emit('test', {a:1, b:2}) // 这里的 {a:1, b:2} 就会被传递给Father.vue中的testHandler 方法
},
methods: {
clickHandler: function () {
// 触发事件,并传递一个随机数!
this.$emit('test', Math.random())
}
}
}
</script>
子组件实例.xxx = 998 传给子组件
console.log(子组件实例.name) // 从子组件中获取数据
子组件实例.hello('你了吗') // 即是传给子组件,也是获取数据, 传的是参数,获取的是方法的返回值!
// Father.vue
<template>
<div>
<h1>
这是Father组件
</h1>
<!-- ref属性如果写在普通标签中, 则Vue会自动获取这个标签的对应的dom,并赋值给$refs 对应的属性-->
<button ref="btn">测试按钮</button>
<!-- 【但是】,如果将ref写在了组件对应的标签上(例如下面的Son标签),值为myson, 则Vue会将Son标签对应的组件的实例赋值给这里 Father.vue组件实例的.$refs.myson
这样一来,就可以在这个Father.vue组件中访问Son.vue组件实例的属性了 -->
<Son ref="myson"></Son>
</div>
</template>
<script>
import Son from './Son.vue'
export default {
components: {
Son: Son
},
created: function () {},
// 当mounted执行前,是得到到子组件的实例的!!!
mounted: function () {
// 这里的this.$refs.myson就是Son.vue组件的实例
console.log(this.$refs.myson)
// 如果Son.vue组件中有xxx这个属性的话,则这里就可以访问
console.log(this.$refs.myson.xxx)
// 如果Son.vue组件中有这个yyy方法的话,则也可以调用,就和调用普通方式一样。
console.log(this.$refs.myson.yyy('数据')) // 998 ,如果yyy返回值是998,则这里就会输出998
}
}
</script>
// Son.vue
<template>
<div>
<h1>
这是Son组件
</h1>
</div>
</template>
<script>
export default {
data: function () {
return {
xxx: '我是韩梅梅'
}
},
methods: {
yyy: function (arg) {
console.log(arg) // '数据'
return 998
}
}
}
</script>
Vue new 出的实例有两个特殊的方法, 一个是
$on
,一个是$emit
var bus = new Vue()
// $on的参数是一个String, 和function
// 这个字符串test ,和函数会被Vue内部保存起来, 通过test就可以找到这个函数
// 这里相当于注册了一个自定义事件test, 第一个参数就是这个事件的回调函数
bus.$on('test', function () {})
// 也可以多次调用$on, 来创建多对字符串+函数的组合
bus.$on('test2', function () {})
// $emit方法也有两个参数, String, Any
// $emit第一个参数是, 通过$on方法注册的事件名, 执行之后,就会调用test事件对应的回调函数,并将$emit的第二个参数传递给这个事件的回调函数!
bus.$emit('test', '任意类型的数据')
<a href="#vuex"“>到里这里看
只有一个页面的应用程序!: single page application 这个做来的网站只有一个页面!
在Vue中路由的作用是根据浏览器【地址栏中的地址】的不同,将不同的Vue组件呈现到页面的指定位置
疑问: 但是,地址栏地址如果不同的话,页面不就跳转了吗? 一跳转不就不是原来的页面了吗, 还怎么将组件呈现到原来的页面???
回答: 有没有想过什么情况下,地址栏地址变了之后,页面即不会刷新,也不会跳转。如果只修改地址栏中的锚点名字的话,页面是不会跳转的!!
-
下载并引用vue-router这个包
<script src="....vue-router.js"></script>
或者import VueRouter from 'vue-router'
-
使用
Vue.use(VueRouter)
如果是使用的webpack打包的方式使用的Vue,就需要在引入vue-router之后加上一行代码:
Vue.use(VueRouter)
-
配置规则
规则的作用是用来告诉vue-router,当页面地址栏是什么内容时,就会将某个组件的模板解析后插入到页面【特定的位置】
// 在项目中添加一个js文件,添加如下代码,并引入到main.js, 或者直接将如下代码写到main.js中
import A from './A.vue' import B from './B.vue' var vr = new VueRouter({ // 规则就写在这个routes数组中 // 数组中的一个元素就是一条规则 // 每个规则至少有两个属性,一个是path:用于指定地址栏的地址,一个是component:用于指定组件对象 // path属性通常以/开头,可以包含多个/, 注意component指定的组件一定要引入进来,才能使用 routes: [ // 这个规则表示,当页面地址栏中的锚点值为 '#/home' 时,就会将 组件A 中的模板解析后插入到页面【特定的位置】 {path: '/home', component: A}, // 这个规则表示,当页面地址栏中的锚点值为 '#/user/xiaoming' 时,就会将 组件B 中的模板解析后插入到页面【特定的位置】 {path: '/user/xiaoming', component: B} ] })
-
在new Vue({}) 时添加一个名为router的属性,值为3中的vr这个实例对象。
new Vue({ ... router:vr // Vue将vr对象的一些属性和方法赋值给各个组件的实例 }).$mount('#app')
-
指定组件插入的位置
在页面上想要显示A组件或者B组件对应的代码中写上
<router-view></router-view>
标签, 这个router-view
标签也是一个组件,是引入的vue-router 这个包中声明的全局组件, 这个组件内部会根据3.中的规则去动态的展示相应的组件!
在上面路由基本使用中:当前锚点值为'#/user/xiaoming', 就会显示B组件。如果值变为其他内容时,B组件就会消失,
如果现在有这样的需求: 我希望无论锚点值是'#/user/xiaoming', 还是 '#/user/honghong' 时,都能够显示B组件,也就是说,希望锚点值以'#/user/' 开头,时都会显示B组件。
这时就需要使用动态路由匹配来达到目的了
要达到上面的需求,只需要将原来的:
{path: '/user/xiaoming'}
修改为{path: '/user/:name'}
, 这里的:
号,有点像正则中通配符的意思, 通过表示任意字符,: 后面的name 没有什么特殊语义,只是一个普通字符,换成任意一个字符都可以。: 冒号后的name暂且我们叫它为路由参数!
var vr = new VueRouter({
routes: [
// 这个规则表示,当页面地址栏中的锚点值为 '#/home' 时,就会将 组件A 中的模板解析后插入到页面【特定的位置】
{path: '/home', component: A},
// 这个规则表示,当页面地址栏中的锚点值以 '#/user/' 开头时,就会将 组件B 中的模板解析后插入到页面【特定的位置】
// 注意观察: 如果锚点值从'#/user/xiaoming' 变为 '#/user/xiaohong'时 组件B的created,和mounted等钩子函数有没有重新执行
{path: '/user/:name', component: B}
]
})
// B.vue 组件
<template></template>
<script>
export default {
watch: {
'$route' (to, from) {
// to 表示路由变化之后是什么
// from 表示路由变化之前是什么
// 对路由变化作出响应...
}
}
}
</script>
看示例demo!
可以使用一个router-link标签来代替a标签进行导航, router-link其实是vue-router这个包提供的全局组件,
router-link组件内部会根据 to属性的值生成对应的a标签,a标签的href什是由 这里的to属性决定的。
<router-link to="/xx">导航到/xx</router-link>
也可以通过v-bind来指定to属性!
<router-link :to=" '/xx' ">导航到/xx</router-link>
除了使用router-link来进行导航之外,还可以通过vue-router提供的方法来进行导航
参数中的path属性名是固定的
this.$router.push({path: '/xx/yy'})
// 调用后地址栏的锚点值变为了 '#/xx/yy'
也可以再添加个query属性(也是固定的,也可以不添加, 有没有这个属性对象天导航的效果没有实质的影响)
query属性的值需要是个对象
query属性的就是可以在进行导航时,在要导航到的组件中,可以通过
this.$routes.query
来得到这个query属性值也是组件之间传递数据的方式之一
this.$router.push({path: '/xx/yy', query: {a: 1, b: 2} })
// 调用后地址栏地址变为了 '#/xx/yy?a=1&b=2'
与前面路由没有太大区别,仅仅是,在写路由时,多添加一个name属性
var vr = new VueRouter({
routes: [
// 这里的name的值,可以随便写个英文就可以,但是多个name的值不要相同。
{name: 'myhome', path: '/home', component: XX},
{name: 'myxiao', path: '/user/xiaoxiao', component: YY}
]
})
那么这个多家的name属性有什么作用呢? 初学习者,可能会觉得麻烦。但是对于复杂的项目是有利的!
有了name属性之后,声明式导航可以这么写:
<router-link :to="{name: 'myhome'}">导航</router-link>
等价于<router-link :to="/myhome">导航</router-link
页面上有多个router-link时,并且 name的值一致的话:
const router = new VueRouter({
routes: [
// redirect属性的作用是: 如果用户想跳转到/a时,会自动跳转到b
{ path: '/a', redirect: '/b' }
]
})
const router = new VueRouter({
routes: [
// 如果用户想跳转到/a时,会自动跳转到名为foo的路由
{ path: '/a', redirect: { name: 'foo' }}
]
})
-
页面结构
-
在子组件中通过props限制一下,让父组件传什么数据过来
-
在父组件中进行数据的传递
3.1 在父组件中使用子组件
import Show from './Show.vue' //引入
export default {
components: {
Show: Show // 别名
}
}
3.2 把父组件中的某个数据通过标签的属性传递给子组件
-
在父组件中把添加的数据保存到tmpLIst中,每次添加后要把文本框清空
只是组件的另一种写法, 本质和前面的还是一样的!, 这种写法在页面内容较多时,是比较方便的!
node package manager
npm 是一款专门用来下载各种前端或者node开发中需要使用的包的命令行工具!
npm install jquery
这样就能将jquery下载下来了!
-
在需要下载包的文件中打开命令行: 注意命令行中的路径
-
执行命令:
npm init
这个命令会生成一个为名package.json
的配置文件, 一个文件夹中只要一个就可以了注意, 初始化时,输入的name 值不能和将要下载的包的名字相同
-
去下载所需要的种包就可以:
npm install 包的名字
, 示例:npm install jquery
,npm install bootstrap
-
可以使用简写命令:
npm i 包的名字
下载包时加-g参数与不带-g参数的区别:
npm install -g jquery
带上-g参数时下载的包会被自动下载到一个固定的目录中: 可以在cmd中输入:
npm get prefix
来查看这个路径
webpack是一款模块化的打包工具,其本身的作用是将多个js文件打包成一个单独的js文件。
通过配合它的插件(plugins)和加载器(loaders) 还可以做一些语法转换以及将其他类型的文件打包到js文件中。
-
包引用顺序的问题
-
全局变量污染的问题
webpack本身是和Vue没有关系的,只是Vue中可以用webpack这个工具。
-
webpack打包时并不是直接将多个个文件合并,而是根据【依赖关系】进行打包的
例如: a.js 文件如果依赖于b.js , 则使用webpack在打包a.js时,会自动将b.js与a.js合并到一个新的文件中.
例如: a.js不依赖于b.js, 则打包a.js时,b.js不会与a.js合并到新文件
-
webpack使得我们不需要在html通过script标签引入js的顺序来表明js的依赖关系
// 一些包
npm i webpack css-loader style-loader url-loader file-loader vue-loader vue-template-compiler html-webpack-plugin -S
"css-loader" // 用于处理css文件之间的依赖关系
"style-loader" // 用于生成将css插入到dom中的js代码
"url-loader" // 用于处理css中使用到的的图片文件
"file-loader" // 用于处理其他loader无法处理的文件, 仅仅是项目中使用到的其他文件复制指定的目录中
"vue-loader" // 用于处理Vue的单文件组件,即 *.vue后缀的文件
"vue-template-compiler" // 这是vue-loader依赖包,
"html-webpack-plugin" // 用于根据一个html复制出别一个html文件,并自动引入通过webpack打包后的js文件!
"webpack" // 这就是webpack这个包本身
webpack在打包时解决了变量污染问题!, 一个文件中就做自己的事情就可以, 如果希望提供一些方法(变量)给别的文件调用,就需要把这个变量: export default obj ,这里的obj其他文件就可以使用了, 其他文件要想使用这里的obj,需要: import myobj from './xx.js'
- 使用webpack时,电脑中要安装有node,仅此而已
假如有个项目文件夹: webpack-start
vue数据绑定原理 什么是双向数据绑定! vue指令一些指令(可能不包含v-for)(事件修饰符也看情况) 事件! axios 问卷案例绑定!
实例的属
提前安装node(第三天需要使用, 提前安装vue-cli, 第三天需要使用)
vue 中的组件 vue 中的组件的生命周期 vue 组件之前相互传值 单文件组件 cli,怎么引入样式什么的! 用微信页面练习组件!
vue中的路由 vue路由的基本使用 vue路由动态匹配(Dynamic Routes Matching) vue嵌套路由(Nested Routes) vue命名路由
跳转和别名 微信页面做路由练习!
项目 1 > 结构搭建,登陆 2 > 退出登陆! 2 > 展示用户信息 3 > 导航菜单交互
讲师管理!
项目
自己配置webpack打包项目
vm代理了data中的数据
- $refs
- $mount
- bus : $emit和$on
- $nextTick