Vue入门
Vue官方文档
Vue开源项目汇总
Vue.js中文社区
Vue安装
直接下载源码然后通过路径引入
在线cdn引入的方式
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
采用 npm 安装的方式,现状: 都会采用npm的方式来进行正式项目开发
npm install vue
基础使用
// Vue所管理的视图div #app
<div id="app">
// 在视图里使用Vue实例中data里面的list数据
<p>{{list}}</p>
</div>
// 引入vue.js
<script src="./vue.js"></script>
<script>
// 实例化Vue对象
new Vue({
// 设置Vue实例的选项:
el: '#app',
data: {
list: '我是模拟发起ajax请求后从服务端返回的数据'
}
}
)
</script>
实例选项-el
new Vue({
// el: '#app' , id选择器
// el: '.app', class选择器
el: document.getElementById("#app") // dom对象
})
实例选项-data
let vm = new Vue({
el: "#app",
data: {
msg: 'abc',
count: 100 ,
list: [1, 2, 3]
}
})
vm.msg = 200
console.log(vm)
console.log(vm.msg)
console.log(vm.$data.msg)
实例选项-methods
插值表达式
// 错误写法
<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,使用三元表达式 -->
{{ if (ok) { return message } }}
// 正确写法
<!-- js表达式 -->
<p>{{ 1 + 2 + 3 }}</p>
<p>{{ 1 > 2 }}</p>
<!-- name为data中的数据 -->
<p>{{ name + ':消息' }}</p>
<!-- count 为data中的数据 -->
<p>{{ count === 1 }}</p>
<!-- count 为data中的数据 -->
<p>{{ count === 1 ? "成立" : "不成立" }}</p>
<!-- 方法调用 -->
<!-- fn为methods中的方法 -->
<p>{{ fn() }}</p>
指令
<p v-text="name">内容</p>
系统指令-v-text和v-html
<div id="app">
<!-- v-text指令的值会替换标签内容 -->
<p>{{str}}</p>
<p v-text="str"></p>
<p v-text="str">我是p标签中的内容</p>
<p v-text="strhtml">我是p标签中的内容</p>
<!-- v-html指令的值(包括标签字符串)会替换掉标签的内容 -->
<p v-html="str"></p>
<p v-html="strhtml">我是p标签中的内容</p>
</div>
<script src="./vue.js"></script> <script>
new Vue({
el: '#app',
data: {
str: 'abc',
strhtml: '<span>content</span>'
}
});
</script>
系统指令-v-if 和 v-show
系统指令-v-on绑定事件
// v-on:xx事件名='当触发xx事件时执行的语句'
<button v-on:click="fn">按钮</button>
// v-on的简写方法
<button @click="fn">按钮</button>
// v-on修饰符 如 once: 只执行一次
<button @click.once="fn">只执行一次</button>
// v-on修饰符 如 prevent: 阻止默认事件
<button @contextmenu.prevent="fn">阻止默认事件</button>
系统指令-v-for
// 第一种用法:
<ul>
<li v-for="item in items"> {{ item.name }} </li>
</ul>
// data中的数组
data: {
items: [
{ name: '大娃' },
{ name: '二娃' } ]
}
// 第二种用法: v-for 还支持一个可选的第二个参数,即当前项的索引
<ul>
<li v-for="(item, index) in items"> {{ index }} {{ item.name }} </li></ul>
// items 为对象 item为当前遍历属性对象的值
v-for="item in items"
//item为当前遍历属性对象的值 key为当前属性名 index为当前索引的值
v-for="(item, key, index) in items"
// key属性的值 要求是每个元素的唯一值 (唯一索引值)
// 好处:vue渲染页面标签 速度快
// 数组
<li v-for="(v,i) in arr" :key="i">{{v}}</li>
// 对象 <li v-for="(v,k,i) in json" :key="i">{{v}}-{{k}}</li>
系统指令-v-bind
**作用: 绑定标签上的任何属性
场景: 当标签上的属性是变量/动态/需要改变的 **
// ID为数据对象中的变量值
<p v-bind:id="ID"></p>
// 简写
<p :id="ID"></p>
bind绑定class(对象)
<p class="obox" :class="{obox:isBn}">内容</p> // isBn为 data选项中的属性
绑定class和原生class会进行合并(但是不会合并重复的)
绑定class(数组)
<p :class="[a,b]">内容</p>
data:{
a:'obox',
b:'left'
}
绑定style(对象)
<p :style="{color:a,fontSize:b}"></p>
//a、b为data属性的key
data: {
a: 'red',
b: '30px'
},
** css属性名 例如 font-size要写成 fontSize 以此类推 原有的style会覆盖**
绑定style(数组)
// 语法:
<div :style="[a,b]"></div>
// a,b 为data的属性
data: {
a: { color: "red" },
b: { fontSize: "30px" }
}
注意 对象可以是多个属性的 集合 同样里面的css属性需要遵从小驼峰命名的规则
系统指令-v-model
// 表单中设置value值没用 v-model会忽略
<input type="text" v-model="msg" value="zhang">
<p>{{msg}}</p>
// 在data中设置msg
data: {
msg: 'zhangsan'
}
v-model-原理及实现
表单元素绑定的数据改变 => data数据发生改变=> 页面数据变化
<p>{{msg}}</p>
<input type="text" :value="msg" @input="fn($event)">
data: {
msg: 'abc'
},methods: {
fn(e) {
//msg=最新的value
this.msg = e.target.value
}
}
系统指令-v-cloak
解决页面初次渲染时 页面模板闪屏现象
注意: 避免多次写入标签 可以一次性 将v-cloak引用在实例视图上
<style>
[v-cloak] {
display: none;
}
</style>
<div id="app" v-cloak> {{msg}}
</div>
系统指令-v-once
指令所在元素只渲染一次
<p v-once>{{msg}}</p>
<input type="text" v-model="msg">
自定义指令
全局自定义指令
// 1.注册一个自定义指令
Vue.directive( '指令名称' , {
inserted(参数){ //参数为使用指令的DOM
//操作
}
})
// 2.使用自定义指令
<input type="text" v-指令名称>
// 示例(全局自动聚焦的自定义指令)
Vue.directive("focus", {
inserted(dom) {
dom.focus();
}
});
// 使用自定义指令
<input type="text" v-focus>
局部自定义指令
//局部指令在vue实例内部定义
directives: {
"focus": {
inserted(dom) {
dom.focus();
}
}
}
// 调用
<input type="text" v-focus>
过滤器
** 格式化data数据(日期格式/货币格式/大小写等)**
局部过滤器
// 组件的选项中定义本地的过滤器
filters: {
过滤器名字:function (value) {
return ....
}
}
全局过滤器
// 如何注册一个全局过滤器
Vue.filter("过滤器名字", function(value) {
return ......
});
使用过滤器
// 过滤器应该被添加在尾部 每个过滤器用管道符分隔
// 第一种用法在双花括号中
{{ 数据 | 过滤器名字 }}
// 第二种用法在 v-bind 中
<div v-bind:id="数据 |过滤器名字 "></div>
过滤器-传参数和串联使用
// 多个过滤器用 | 分割
<p>{{count|a('元')|b}}</p>
// 定义过滤器
filters:{
// 第一个参数永远是前面传递过来的过滤值
a:function(val,y){
// val 是count值
// y 是‘元’
return val+y;//count元
},
b:function(val){
//val 是count元
return val+"人民币";
}
}
使用过滤器完成日期格式处理
** 引入第三方格式化日期插件 moment.js**
// 全局过滤器代码
Vue.filter("fmtDate", function (v) {
return moment(v).format('YYYY-MM-DD h:mm:ss a')
})
ref属性
给元素定义ref属性, 然后通过$refs.名称 来获取dom对象
<input type="text" ref="txt">// 定义ref
// 获取DOM的value值
methods: {
getVal() {
//获取dom
console.log(this.$refs.txt)
}}
实例选项
计算属性
:当表达式过于复杂的情况下 可以采用计算属性 对于任何复杂逻辑都可以采用计算属性
在Vue实例选项中 定义 computed:{ 计算属性名: 带返回值 的函数 }
``
data: {
message: 'hello'
},
computed: {
reverseMessage: function () {
// this指向 vm 实例
return this.message.split('').reverse().join('')
}
}
// computed里的函数直接用 不加() 但是必须得return
{{ message }}
{{ reversedMessage }}
发送网络请求
axios
axios基本使用
// 基本用法
axios.get(url).then((res) => {
// 请求成功 会来到这 res响应体
}).catch((err) => {
// 请求失败 会来到这 处理err对象
})
watch-基本使用
监听data数据变化时 自动触发函数
// 基本用法
data: {
msg: 'abc'
},
watch: {
// data中的属性msg发生改变时 自动触发该函数
msg(newV, oldV) {
console.log(newV, oldV)
}
}
组件
重复的页面结构,数据,逻辑 都可以抽提成一个组件
全局组件
// 注册组件名称 推荐 小写字母 加横向的结构
Vue.component("content-a", {
template: `<div> {{count}} </div>`,
data() {
return { count: 1 };
}
);
<content-a></content-a>
// 注意 data中必须为一个返回对象的函数
// template必须有且只有一个根元素
局部组件
// 1.实例选项compoents中定义局部组件名字
components: {
// 2.在组件名字相对应的对象中定义选项(template、data()、.....)
"z-j": {
template: `<div>我是z-j组件--{{msg}}</div>`,
data() {
return { msg: "abc" }
}
}
}
// 3.在实例视图中使用组件
<div id="app"> <z-j></z-j> </div>
组件嵌套
全局组件 嵌套 全局组件
局部组件 嵌套 全局组件
Vue.component('child-a', {
template: "<div>我是child-a组件</div>"
})
Vue.component('child-b', { t
emplate: "<div>我是child-b组件</div>"
})
// 全局嵌套全局(此时 child-a和child-b 是parent-a的子组件)
Vue.component('parent-a', {
template: `<div><child-a></child-a> <child-b></child-b> </div>` }
)
// 局部嵌套全局 (此时 child-a和child-b 是com-a的子组件)
components: {
"com-a": {
template: ` <div><child-a></child-a> <child-b><child-b> </div> ` }
}
}
组件通信
父子组件传值-props属性
// 调用组件
<div id="app">
<child-a :msg="msgParent"></child-a>
</div>
// 子组件
Vue.component("child-a", {
template: ` <div> 我是子组件 {{count}}是自己的data中的数据count {{msg}}是来源于外部组件的数据</div> </div>`,
data() {
return { count: 100 }
},p
rops: ["msg"]
}
)
// 父组件(根组件)
new Vue({
el:'#app',
data: {
msgParent: "我是父组件"
}
})
组件和模块的区别
路由
单页应用(简称SPA)
单页应用 SPA-实现原理
<body>
<ul>
<li><a href="#/aaa">aaa</a></li>
<li><a href="#/bbb">bbb</a></li>
<li><a href="#/ccc">ccc</a></li>
<li><a href="#/ddd">ddd</a></li>
</ul>
<!-- 容器 -->
<div id="main"></div>
<script>
// 根据不同内容渲染不同的标识
let oBox = document.getElementById('main')
window.onhashchange = function () {
// 获取hash值
let hash = location.hash
console.log(hash)
hash = hash.replace('#/', '')
switch (hash) {
case "aaa":
oBox.innerText = 'AAA'
break
case "bbb":
oBox.innerText = 'BBB'
break
case "ccc":
oBox.innerText = 'CCC'
break
case "ddd":
oBox.innerText = 'DDD'
break
default:
break
}
}
</script>
</body>
vue-router的基本用法
路由下载
<script src="./vue.js"></script>
<script src="./vue-router.js"></script>
本地文件引入vue-router ,一定要先引入vue.js,再引入vue-router
<!-- router-link 最终会被渲染成a标签,to指定路由的跳转地址 -->
<router-link to="/users">用户管理</router-link>
<router-link to="/home">首页展示</router-link>
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
//配置路由规则
var router = new VueRouter({
routes: [
{ path: '/home', component: Home }
{ path: '/users', component: Users }
]
});
//创建组件
let Home = {
template: '<div>这是Home内容</div>'
};
let Users = {
template: '<div>这是用户管理内容</div>'
}
//把router实例挂载到vue实例上
var vm = new Vue({
el: '#app',
router
});
vue-router-动态路由
<router-link to="/item/8">小米电视</router-link>
<router-link to="/item/9">华为电视</router-link>
<router-view> </router-view>
//配置路由规则
var router = new VueRouter({
routes: [
{ path: '/item/:id', component: Items }
]
});
//创建组件
let Items = {
template: '<div>我是商品详情页 {{ $route.params.id }}</div>',
mounted: {
//实例被挂载后调用
console.log(this.$route.params.id);
}
}
//把router实例挂载到vue实例上
var vm = new Vue({
el: '#app',
router
});
vue-router-to 属性赋值
<!-- 常规跳转 -->
<!-- <router-link to="/aaa">aaa</router-link> -->
<!-- 使用data中定义的变量 bbb 作为路径 -->
<!-- <router-link :to="bbb">bbb</router-link> -->
<!-- 根据对象name跳转 --> (注意:name值是字符串)
<!-- <router-link :to="{name:'ccc'}">ccc</router-link> -->
<!-- 根据对象path跳转 -->(注意:必须得加上/ 不然容易错乱)
<!-- <router-link :to="{path:'/ddd'}">ddd</router-link> -->
<!-- 带参数的跳转 --> (注意获取参数route 不要写成router)
<!--<router-link :to="{name:'eee',params:{id:1}}">体育</router-link> --> <router-view></router-view>
vue-router-重定向
当希望某个页面被强制中转时 可采用redirect 进行路由重定向设置
var router = new VueRouter({
routes: [
{
path: "/bj",
redirect: "/sh", // 强制跳转上海
component: {
template: `<div>体育</div>`
}
}
]
});
vue-router-编程式导航
点击的时候路由实现跳转
methods: {
goPage() {
// 跳转到新闻页面
this.$router.push({
path: "/news"
});
}
}
路由的激活样式
<a href="#/bj" class="router-link-exact-active router-link-active">北京</a>
设置激活class样式即可
vue-router-嵌套路由
var router = new VueRouter({
routes: [
{
path: "/music",
component: {
template: `<div>music</div>`
},
children: [
{ path: 'lx', component: Lx }
]
}
]
});
过度动画
<transition name="fade">
<div v-show="isShow" class="box"></div>
</transition>