基础语法
- v-bind(缩写是冒号)
<div id="app">
<span v-bind:title="msg">666</span>
</div>
<script>
new Vue({
el: "#app",
data: {
msg: "hello"
}
})
</script>
- v-if、v-else
<div id="app">
<p v-if="flag">if</p>
<p v-else>else</p>
</div>
<script>
new Vue({
el: "#app",
data: {
msg: "hello",
flag: true
}
})
</script>
一般来说,v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好;
- v-for
<div id="app">
<p v-for="x in msg">{{x.name}}</p>
</div>
<script>
new Vue({
el: "#app",
data: {
msg:[{name: "Yummer"},{name: "Kakoo"},{name: "Puppy"}]
}
})
</script>
- v-on(缩写是@)
<div id="app">
<button v-on:click="click"></button>
</div>
<script>
new Vue({
el: "#app",
data: {},
methods: {
click: function(){
alert("666");
}
}
})
</script>
- v-model(根据表单控件类型实现双向绑定)
<div id="app">
<!-- 单个复选框以boolean值回显,多个则以数组回显 -->
<input type="checkbox" v-model="value" value="checkbox1">{{value[0]}}
<input type="checkbox" v-model="value" value="checkbox2">{{value[1]}}
<input type="checkbox" v-model="value" value="checkbox3">{{value[2]}}
<br>
value1:<input type="text" v-model="value[0]">
value2:<input type="text" v-model="value[1]">
value3:<input type="text" v-model="value[2]">
<br>
{{value}}
</div>
<script>
new Vue({
el: "#app",
data: {
value: ["1","2","3"]
}
})
</script>
组件化开发
- 声明组件:Vue.component(‘tagName’,{props: [组件属性数组], template: ‘< tag >< tag/>’}
- 使用组件:< tag prop1=“” prop2=“”>< tag/>
- 只能在根实例“#app”下应用预设组件
- prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来
- 注意props数组元素需要加异引号,意为引用的父附组件属性变量名
<div id="app">
<!-- 双向绑定实时改变value数组的值 -->
value:<input type="text" v-model="value">{{value}}
<br>
<!-- 从value数组中取出元素item,并赋予到test属性当中,由于其已被bind绑定,在item元素改变时test属性也会跟着改变 -->
<gec v-for="item in value" v-bind:test="item"></gec>
</div>
<script>
Vue.component('gec',{
//子组件只能通过props数组声明的属性获取父组件传递的参数
//此处由于test已在props中声明,所以template中的test才是父组件传递过来的值
props: ['test'],
template: '<h1>{{this.test}}<h1/>'
});
new Vue({
el: "#app",
data: {
value: ["1","2","3"]
}
})
</script>
网络通信
Vue高度关注Soc原则,所以异步请求需要依赖通信工具,其中Axios提供了完善的Ajax封装以及与Vue实例语法较好的结合,推荐使用;
<div id="app">
<h1>info:</h1>
<p><b>{{info}}</b></p>
<br>
</div>
<script>
new Vue({
el: "#app",
data: {
info: {}
},
created(){
axios.get("../data.json").then(resp=>{this.info = resp});
}
})
</script>
计算属性
methods vs. computed,效果上两个都是一样的,methods调用需要加(),但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值,例如函数内调用的变量发生改变;而使用 methods ,在重新渲染的时候,函数总会重新调用执行,computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。
自定义事件
- 利用emit绑定组件属性,完成子组件向父组件传递参数;
<div id="app">
<!-- emit会从事件中心获取回调函数,也就是showChildData,再依次调用,达成子组件向上通信的目的 -->
<gec :parentdata="parentData" @data-transfer="showChildData"></gec>
</div>
<script>
Vue.component('gec', {
template: ` <div>
<p>Parent's data: {{this.parentdata}}</p>
<hr>
<p>Child's data: {{this.childData}}</p>
<!-- 调用子组件的alterData改变childData的值 -->
<button @click="alterData">Click to alter!</button>
</div>
`,
props: ['parentdata'],
//data必须是一个函数,且必须返回独立对象,不能是引用,会影响其他组件实例
data: function () {
return {
//函数形式声明childData
childData: 'This is a data from child component!'
}
},
methods: {
alterData: function () {
this.childData = "Child's data changed!";
//调用emit函数自定义data-transfer事件,携带childData参数,传递给父组件
this.$emit('data-transfer', this.childData);
}
}
});
new Vue({
el: "#app",
data: {
parentData: 'This is a data from parent component!'
},
methods: {
//父组件用函数参数形式接受子组件的传递值
showChildData: function (childData) {
alert("Child's component data is: " + childData);
this.parentData = childData;
}
}
})
</script>
- 其中HTML会优化所有的驼峰命名属性,使大写字符小写,所以对于标签的属性参数尽量使用‘-’来划分单词;
- template参数只允许有一个父标签!
Vue Router
- 目录结构
- components为跳转的demo组件
- 组件style标签可以加scoped属性使其样式局部化
<template>
<div>
<h1>This is component demo1</h1>
</div>
</template>
<script>
export default{
name: "demo1"
}
</script>
- router.js为路由配置,注意VueRouter和routes不要拼错,同时export导出的是VueRouter对象
- routes对象可以增加children属性,内部添加二级路由,即在组件下的路由跳转;
import VueRouter from 'vue-router'
import demo1 from '../components/demo1'
import demo2 from '../components/demo2'
const routes = [
{
path: '/demo1',
component: demo1
},
{
path: '/demo2',
component: demo2
},
{
path: '*',
component: xxx //配置404默认路由
}
];
export default new VueRouter({
mode: 'histroy',//设置路由跳转可不带‘#’
props: true, //配置
routes //为routes: routes的缩写
})
- App.vue为入口组件
- 利用router-link代替a标签进行组件跳转实现页面局部刷新,组件在router-view里面完成替换
- router-link还可通过active-class以及exact-active-class来声明激活样式,区别时前者模糊匹配路由,例如path设置的是/demo,但是/demo/x也可以激活样式,后者是仅在/demo路由下才会激活样式
<template>
<div id="app">
<h1>Main entry</h1>
<router-link to="/demo1">To demo1</router-link>
<router-link to="/demo2">To demo2</router-link>
<router-view>View show</router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
- main.js则为主配置js,进行Vue实例化等
import Vue from 'vue'
import App from './App'
import VueRouter from 'vue-router'
import router from './router/router'
//Vue开启使用路由
Vue.use(VueRouter)
new Vue({
el: '#app',
router,//配置导入的路由对象
components: { App },
template: '<App/>'
})
- 组件路由参数传递
– query方式:
<router-link :to="{ name:'login',query:{id:1} }">登录</router-link>
//通过query配置的路径显示如下:.html#/login?id=1
--params方式
<router-link :to="{ name:'register',params:{'name':'San'} }">注册</router-link>
//通过params配置的路径显示如下:.html#/register/San
此种方式需要在routes:[…]路由配置时候提前占位
- 注意事项:
- to标签需要v-bind绑定;
- 获取参数使用this.routes.params或者this.routes.query;
- routes是只读对象,router是只写对象,用来操作路由信息,例如:router.push({…});
总结
- 传参可以用query形式和params形式,两者又各有两种不同的写法,但要么是在to属性的path中追加参数, 要么就在其中声明对象;
- to加冒号是为了不让后面的参数字符化,以及params使用需要路由配置占位;
- 同时在包装多个属性时可以用props来传递,params需要在路由配置props为true;
- 最后params用对象方式传参是只能用name传参,name就是path的引用,两者不能同时出现…
- 显然总结的很勉强,贴个链接,路由传参总结的很到位!