文章目录
Vue 入门
Vue 框架是现在国内比较流行的前端开发框架,现在国内常用的前端开发流程大概是UI使用饿了么UI,交互使用Vue框架,使用ES6规范开发,使用Node.NPM指令,使用webpack打包,使用easy mock进行接口数据测试。
Vue 引包
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
开发包使用vue.js,该包包含了所有vue的开发环境
Vue 启动
Vue 有三个必要对象
el
el是发生行为的目的地
template
装载的模板
data
动态数据的声明
<script>
new Vue({
el:'#app',
template:'<div><h1>大家好 {{text}}</h1></div>',
data:function() {
return {
text: 'hello vue'
}
}
})
</script>
插值表达式
- {{ 表达式 }}
表达式包含:对象、字符串、判断后的布尔值、三元表达式
Vue 指令
Vue 指令都是以v-xxx的形式表示,就是html页面的属性
<div v-xxx> </div>
常用的Vue的指令
- v-text: 元素的innerHtml属性,必须是双标签
- v-html 元素的innerHtml属性
- v-if 判断是否插入元素
- v-else-if
- v-else
- v-show 隐藏元素,如果确定要隐藏,会给元素的style添加display:none样式
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el:'#app',
template:`
<!--必须要有一个根节点-->
<div>
<span v-text="myText"></span>
<hr>
<span v-html="myHtml"></span>
<hr>
<button v-if=" num == 1 ">测试v-if</button>
<button v-else-if=" num == 2 ">测试v-else-if</button>
<button v-else>测试v-else</button>
<hr>
<button v-show="isShow">测试v-show</button>
</div>
`,
data:function() {
return {
myText: '我是v-text的值',
myHtml: '<h2>我是一个链接</h2>',
num: 1,
isShow: false
}
}
})
</script>
v-bind
给元素的属性赋值,可以给已存在的属性赋值,也可以给自定义的属性赋值,单项数据流,数据是从vue到页面的单项数据流
<div v-bind:原属姓名="变量"</div>
<!-- 简写 -->
<div :原属姓名="变量"</div>
v-on
可以处理自定义原生事件,给按钮添加click并让使用变量的样式改变
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el:'#app',
template:`
<!--必须要有一个根节点-->
<div>
<span v-text="myText"></span>
<hr>
<span v-html="myHtml"></span>
<hr>
<button v-if=" num == 1 ">测试v-if</button>
<button v-else-if=" num == 2 ">测试v-else-if</button>
<button v-else>测试v-else</button>
<hr>
<button v-show="isShow">测试v-show</button>
</div>
`,
data:function() {
return {
myText: '我是v-text的值',
myHtml: '<h2>我是一个链接</h2>',
num: 1,
isShow: false
}
}
})
</script>
v-model
双向数据流绑定=》页面改变影响内存,内存改变影响页面
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
template: `
<div>
<input type="text" v-model="myValue" />
<button v-show="myValue === 'xxx'">hha</button>
</div>
`,
data: function() {
return {
myValue: 'xx'
}
}
})
</script>
v-for
遍历数组,用法类似js的for in语法,下面例子将stus数组的每个元素遍历到item中
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
template: `
<div>
<ul>
<li v-for="item in stus">
{{ item.name }}
</li>
</ul>
</div>
`,
data: function() {
return {
stus: [{name:'张三'},{name:'李四'},{name:'王五'}]
}
}
})
</script>
如果是循环数组,可以使用下面实例:
<li v-for="(key, value, index) in stus2">
key:{{key}}
value:{{value}}
index:{{index}}
</li>
this
- methods和data本身是在同一个对象中,所以在该对象中可以通过this.随意取;
- this.xxx取data中的值,this.xxxMethod调用函数
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
template: `
<div>
<h1 v-show="isShow">1</h1>
<h1 v-show="isShow">2</h1>
<h1 v-show="isShow">3</h1>
<h1 v-if="isShow">4</h1>
<button @click="changeByClick">click</button>
</div>
`,
data: function() {
return {
isShow: true
}
},
methods: {
changeByClick:function(e) {
<!-- this是data函数return的对象 -->
console.log(e.target)
console.log(this)
this.isShow = !this.isShow
}
}
});
</script>
组件渲染-父使用子组件
- 创建子组件模块
- 在父组件中声明需要使用的子组件
- 在父组件中使用子组件
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
<!-- 创建App子组件 -->
var App = {
template: '<h1>我是入口</h1>'
}
new Vue({
el: '#app',
<!-- 通过components函数声明需要使用的组件,key是组件名,value是组件对象,声明了App组件,组件名为hello -->
components: {
hello: App
},
<!-- 调用组件名为hello的子组件 -->
template: '<hello/>'
})
</script>
继承-父子组件传值(父传子)
- 父传子时通过属性传递
- 子要声明props[‘属性名’]来接收
- 接收到后就可以仍以使用(再template中直接用,再js中this.属性名调用)
- 传递常量直接用,传递变量加冒号(通过v-bind指令)
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
<!-- 创建一个Son1子组件 -->
var Son1 = {
template: `
<div>
<!-- 通过插入表达式调用父组件传递的数据 -->
接收到父组件传递的值 {{ emmm }}
</div>
`,
<!-- 通过props函数声明父组件传递的数据 -->
props:['emmm']
}
var Father1 = {
<!-- 先声明需要传值的子组件 -->
components: {
son: Son1
},
template: `
<div>
<!-- 通过子组件的标签传值 -->
<!-- 通过v-bind指令向子组件的emmm属性绑定数据 -->
<son :emmm="xxx"></son>
</div>
`,
data: function() {
return {
xxx: '我是父组件'
}
}
}
new Vue({
el: '#app',
components: {
hello: Father1
},
template: `<hello></hello>`
})
</script>
注册全局组件
- 多次使用的公共性功能组件,应该注册成全局组件,减少代码冗余
- 全局API
Vue.component('组件名', 组件对象)
事例
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
<-- 注册全局组件,之后调用组件无需再次声明 -->
Vue.component('my-btn', {
template: `<div>
<button>click</button>
</div>`
})
var one = {
template: `<div>
one
<my-btn/>
</div>`
}
var two = {
template: `<div>
two
<my-btn/>
</div>`
}
var App = {
components: {
'one1': one,
'two2': two
},
template: `
<div>
<one1/>
<two2/>
<my-btn/>
</div>
`
}
new Vue({
el: '#app',
components: {
hello: App
},
template: `<div>
<hello/>
</div>`
})
</script>
过滤器
filter :全局过滤器,所有组件共享
Vue.filter('过滤器名', 过滤方式)
先注册后使用,filter通过过滤方式return出最终数据,使用方式是通过 {{ 操作数据 | 过滤器名 }}
filters: 组件内部过滤器,组件内有效
filters{ '过滤器名', 过滤方式 }
将数据进行添油加醋的操作
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
<!-- 全局过滤器 -->
Vue.filter('myFilter', function(str2, msg) {
return msg + str2.toLowerCase()
})
var App = {
template: `<div>
<input type="text" v-model="myText" />
{{ myText | reverseStr }}
<br />
{{ myText | myFilter('全局过滤器:')}}
</div>`,
data: function() {
return {
myText: ''
}
},
<!-- 组内过滤器 -->
filters: {
reverseStr: function(str) {
<!-- 将字符串进行反转,先将字符串转换为数组,再将数组反转,最后将数组转换为字符串 -->
return str.split('').reverse().join('')
}
}
}
new Vue({
el:'#app',
components: {
hello: App
},
template: `
<div>
<hello/>
</div>
`
})
</script>
监视改动
watch
监视单个属性的改变
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var App = {
template: `<div>
<input type="text" v-model="myText" />
<button @click="stus[0].name='rose'">click</button>
</div>`,
data: function() {
return {
myText: '',
stus: [{name:'mike'}]
}
},
watch: {
<!-- watch监视的是对象的地址,当对象地址没有修改,而对象的数据修改时,watch无法监视,应该使用深度监视进行监视复杂类型的数据 -->
stus: function() {
alert('不可能出现')
},
<!-- 该方法才是正确的监听复杂类型数据的方法 -->
stus: {
deep: true,
handler: function(newV, oldV) {
alert(newV[0].name)
}
},
<!-- key是data函数的属性名,value是监视后的行为 -->
myText: function(newV, oldV) {
console.log(newV)
console.log(oldV)
if (newV == '你好') {
alert('我不好!')
};
}
}
}
new Vue({
el: '#app',
components: {
app: App
},
template: `<div>
<app/>
</div>`
})
</script>
computed
监视多个属性的改变
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var App = {
template: `<div>
\(
<input type="text" v-model="n1" />
+
<input type="text" v-model="n2" />
\) *
<input type="text" v-model="rate" />
= {{ result }}
</div>`,
data: function() {
return {
n1:0,
n2:0,
rate:0
}
},
computed: {
<!-- 包含原值不变,缓存不调函数的优化机制,result为需要监视的属性 -->
result: function() {
<!-- 监视对象写在函数内部,凡是this.相关属性的改变都会触发当前函数 -->
return ((this.n1-0) + (this.n2-0)) * this.rate
}
}
}
new Vue({
el: '#app',
components: {
app: App
},
template: `<div>
<app/>
</div>`
})
</script>
solt
solt是Vue提供的内置组件,它允许父组件向子组件传递DOM对象
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var MyLi = {
template: `<li>
<!-- solt是Vue提供的内置组件,它允许父组件向子组件传递DOM对象 -->
<slot></slot>
</li>`
}
Vue.component('my-li', MyLi)
var App = {
template: `<div>
<ul>
<my-li><input type="text" v-model="myText" /></my-li>
<my-li>2</my-li>
<my-li><input type="text" v-model="myText" /></my-li>
<my-li><input type="text" v-model="myText" /></my-li>
<my-li>5</my-li>
<my-li><input type="text" v-model="myText" /></my-li>
<my-li>7</my-li>
<my-li>8</my-li>
<my-li>9</my-li>
</ul>
</div>`
}
new Vue({
el: '#app',
components: {
app: App
},
template: `<div>
<app/>
</div>`
})
</script>
具名slot案例:
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var MySlot = {
template: `<li>
<!-- solt是Vue提供的内置组件,它允许父组件向子组件传递DOM对象 -->
这是第一个插槽
<slot name="one"></slot>
这是第二个插槽
<slot name="two"></slot>
</li>`
}
Vue.component('my-slot', MySlot)
var App = {
template: `<div>
<ul>
<my-slot>
<span slot="two">我是第一个坑</span>
<h3 slot="one">我是第二个坑</h3>
</my-slot>
</ul>
</div>`
}
new Vue({
el: '#app',
components: {
app: App
},
template: `<div>
<app/>
</div>`
})
</script>
Vue 生命周期
- 首先new一个Vue()对象
- 第一次初始化Vue事件和内部设置,无关数据,此时beforeCreate()开始执行
- 第二次初始化,注入和响应数据,此时created()开始执行
- 判断有无传el对象,如果没有,则可以通过vm.$mount(el)调用,即可以通过这个命令对指定el元素的渲染
- 如果传入了el对象,则判断是否有template对象
- 如果有,则编译template到render函数中
- 如果没有,则将el对象的outerHtml作为template编译
- 此时开始执行beforeMount()方法
- 创建vm.$el获取元素内容或者更改内容,此时执行mounted()方法
- 流程到这里时数据已经装载好了,此时如果有数据被修改,则执行beforeUpdate()方法,可以获得改变数据之前的数据
- 开始渲染新的DOM,开始执行updated()方法,可以获得新的DOM
- 当组件被销毁时,开始执行beforeDestory()方法
- Vue自动释放watch监听和子组件事件监听后,执行destoryed()方法
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var Test = {
template: `<div>
生命周期测试 {{ text }}
<button @click="text='你好世界'" >click</button>
</div>`,
data: function() {
return {
text: "hello world"
}
},
beforeDestory: function() {
// 销毁之前,结果没有打印
console.log("beforeDestory")
},
destoryed: function() {
// 销毁之后,结果没有打印
console.log("destoryed")
},
activated: function() {
// 激活组件时执行
console.log("activated")
},
deactivated: function() {
// 禁用组件时执行
console.log("deactivated")
},
beforeCreate: function() {
<!-- 组件创建之前,结果是undefined -->
console.log(this.text)
},
created: function() {
<!-- 组件创建之后,结果是hello world -->
<!-- 因为created可以更改数据,所以实现了vue到页面的影响,常用来发起ajax的请求,获得数据而改变页面 -->
console.log(this.text)
},
beforeMount: function() {
<!-- Vue 开始工作,装在数据到DOM之前,结果是<div id="app"></div>未改变,该方法只执行一次 -->
<!-- console.log(document.body.innerHTML) -->
console.log("===================================================================")
},
mounted: function() {
<!-- Vue 开始工作,装在数据到DOM之后,结果是<div id="app"></div>改成<div><div><div>生命周期测试</div></div></div>,该方法只执行一次 -->
<!-- console.log(document.body.innerHTML) -->
},
beforeUpdate: function() {
<!-- Vue 数据发生改变,且改变之前,可以获取原DOM对象,结果仍未hello world -->
console.log(document.body.innerHTML)
},
updated: function() {
<!-- Vue 数据发生改变,且改变之前,可以获取新DOM对象,结果为你好世界 -->
console.log(document.body.innerHTML)
}
}
var App = {
components: {
test: Test
},
data: function() {
return {
isShow: true
}
},
template: `<div>
// keep-alive 是Vue的内置组件,它允许组件被禁用和激活,避免组件的多次销毁和创建,实际开发应该用激活和禁用取替代创建和销毁方法
<keep-alive> <test v-if="isShow"/></keep-alive>
<button @click="isShow = !isShow">click</button>
</div>`
}
new Vue({
el: '#app',
components: {
app: App
},
template: `<div>
<app/>
</div>`
})
</script>