vue各种示例展示
注意:以下所有示例基于vue 2.x、Vuex 2.x、vm.$mount()-挂载[html] view plain copy<body> <div id="a"> </div> </body> <script>
·
注意:以下所有示例基于vue 2.x、Vuex 2.x、
vm.$mount()-挂载
- <body>
- <div id="a">
- </div>
- </body>
- <script>
- var A = Vue.extend({
- template: '<p>123</p>'
- });
- /*// 自动挂载
- new A({
- el: '#a'
- });*/
- var a = new A();
- a.$mount('#a')// 手动挂载
- </script>
组件示例(component):
a. 不使用template标签
- <body>
- <div id="a">
- <aaa m="a++" bgcolor="red"></aaa>
- <aaa m="b--" bgcolor="blue"></aaa>
- </div>
- </body>
- <script>
- Vue.component('aaa', {
- template: '<div><p>{{ m }}</p><p @click="add" :style="style">点这里-> a:{{a}} b:{{b}}</p></div>',
- data: function() {
- return {
- a: 0,
- b: 0,
- style: {
- fontSize: '30px',
- background: this.bgcolor
- }
- }
- },
- props: ['m', 'bgcolor'],
- methods: {
- add: function() {
- this.a++;
- this.b--;
- }
- }
- });
- new Vue({
- el: '#a'
- })
- </script>
b. 使用template标签
- <body>
- <div id="a">
- <aaa m="a++" bgcolor="red"></aaa>
- <aaa m="b--" bgcolor="blue"></aaa>
- </div>
- <template id="b">
- <div>
- <p>{{ m }}</p>
- <p @click="add" :style="style">点这里-> a:{{a}} b:{{b}}</p>
- </div>
- </template>
- </body>
- <script>
- Vue.component('aaa', {
- template: '#b',
- data: function() {
- return {
- a: 0,
- b: 0,
- style: {
- fontSize: '30px',
- background: this.bgcolor
- }
- }
- },
- props: ['m', 'bgcolor'],
- methods: {
- add: function() {
- this.a++;
- this.b--;
- }
- }
- });
- new Vue({
- el: '#a'
- })
- </script>
c. 局部注册
- <body>
- <div id="a">
- <my-b></my-b>
- <my-c></my-c>
- <my-d></my-d>
- </div>
- <template id="b">
- <p>bbb</p>
- </template>
- </body>
- <script>
- var myD = Vue.component('myD', {
- template: '<p>ddd</p>'
- });
- new Vue({
- el: '#a',
- components: {
- 'myB': {
- template: '#b'
- },
- 'myC': {
- template: '<p>ccc</p>'
- },
- 'myD': myD
- }
- });
- </script>
d. 动态组件
- <body>
- <div id="a">
- <button @click="change">{{ cur }}</button>
- <component :is="cur"></component>
- </div>
- <template id="b">
- <p>bbb</p>
- </template>
- </body>
- <script>
- new Vue({
- el: '#a',
- data: {
- cur: {// 直接绑定到组件对象上
- template: '<p>aaa</p>'
- }
- },
- methods: {
- change: function() {
- this.cur = this.cur=='myB'?'myC':'myB';
- }
- },
- components: {// 多个组件使用同一挂载点,动态切换
- 'myB': {
- template: '#b'
- },
- 'myC': {
- template: '<p>ccc</p>'
- }
- }
- });
- </script>
e. 父子组件通信
- <body>
- <div id="a">
- 父:<input v-model="msg" />
- <aaa :msg="msg" @notick="notickEvent"></aaa>
- </div>
- <template id="b">
- <div>
- 子:<input v-model="msgChild" />
- </div>
- </template>
- </body>
- <script>
- // 子组件
- Vue.component('aaa', {
- template: '#b',
- props: ['msg'],// 使子组件接受到父组件的msg属性
- data: function() {
- return {
- msgChild: ''// 子组件msg的替代品(vue2中禁止子组件直接改变父组件状态,只能通过替代)
- }
- },
- watch: {
- msg: function(newVal, oldVal) {
- this.msgChild = newVal;
- },
- msgChild: function(newVal, oldVal) {
- this.$emit('notick', newVal);// 子组件msgChild改变时,触发notick事件
- }
- }
- })
- // 父组件
- new Vue({
- el: '#a',
- data: {
- msg: ''
- },
- methods: {
- notickEvent: function(val) {
- this.msg = val;
- }
- }
- })
- </script>
- <body>
- <div id="a">
- <aaa></aaa>
- <bbb></bbb>
- </div>
- <template id="b">
- <button @click="add">点击:{{ num }}</button>
- </template>
- </body>
- <script>
- var bus = new Vue();// 简单场景下可以使用bus
- // 子组件aaa
- Vue.component('aaa', {
- template: '#b',
- data: function() {
- return {
- num: 0
- }
- },
- methods: {
- add: function() {
- bus.$emit('addEvent', ++this.num);
- }
- },
- mounted: function() {
- var This = this;
- bus.$on('addEvent', function(val) {
- This.num = val;
- })
- }
- })
- // 子组件bbb
- Vue.component('bbb', {
- template: '#b',
- data: function() {
- return {
- num: 0
- }
- },
- methods: {
- add: function() {
- bus.$emit('addEvent', ++this.num);
- }
- },
- mounted: function() {
- var This = this;
- bus.$on('addEvent', function(val) {
- This.num = val;
- })
- }
- })
- new Vue({
- el: '#a'
- })
- </script>
g. 异步组件
- <body>
- <div id="a">
- <component :is='btn'></component>
- <button @click="change">{{ btn }}</button>
- </div>
- </body>
- <script>
- new Vue({
- el: '#a',
- data: {
- btn: 'aA'
- },
- methods: {
- change: function() {
- this.btn = this.btn=='aA'?'bB':'aA';
- }
- },
- components: {
- aA: function(resolve) {
- setTimeout(function() {
- resolve({
- template: '<p>{{ btn }}</p>',
- data: function() {
- return {
- btn: this.$root.btn
- }
- }
- });
- }, 1000);
- },
- bB: {
- template: '<p>bb...</p>'
- }
- }
- });
- </script>
计算示例(computed):
- <body>
- <div id="a">
- <p>{{ intro }}</p>
- <input type="text" v-model="name">
- <input type="text" v-model="age">
- </div>
- <script>
- new Vue({
- el: '#a',
- data: {
- name: 'hvb',
- age: 20
- },
- computed: {
- intro: function() {
- return this.name +':'+ this.age;
- }
- }
- });
- </script>
- </body>
自定义指令实现"点击按钮使文本框获取焦点"示例(directive):
- <body>
- <div id="a">
- <input v-focus="isFocus" />
- <button @click="change">点击切换输入框选中状态</button>
- </div>
- </body>
- <script>
- // 注册一个全局自定义指令 v-focus
- Vue.directive('focus', {
- // 被绑定元素插入父节点时调用
- inserted: function (el, binding) {
- if(binding.value) {
- el.focus();
- }else {
- el.blur();
- }
- },
- // 被绑定元素所在模板完成一次更新周期时调用
- componentUpdated: function (el, binding) {
- if(binding.value) {
- el.focus();
- }else {
- el.blur();
- }
- }
- })
- new Vue({
- el: '#a',
- data: {
- isFocus: true
- },
- methods: {
- change: function(e) {
- this.isFocus = !this.isFocus;
- }
- }
- })
- </script>
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <script src="vue.js"></script>
- <style>
- * {
- margin: 0;
- padding: 0;
- }
- body, html {
- width: 100%;
- height: 100%;
- }
- .line {
- text-decoration: line-through;
- }
- </style>
- </head>
- <body>
- <div id="a">
- <aaa :list="tasks"></aaa><!-- 注意:list的冒号 -->
- <hr>
- <aaa :list="[{a: 'a', b: 'b', line: true}, {a: 'aa', b: 'bb', line: false}]"></aaa><!-- 组件复用 -->
- </div>
- <template id="b">
- <div>
- <input v-model="dd" @keyup.enter="cc" type="text" placeholder="enter添加">
- <p v-show="remain">剩余{{ remain }}条未完成</p>
- <div v-for="(key, index) in list">
- <span @click="aa(key)" :class="{line: key.line}">{{ key.a }}---{{ key.b }}</span>
- <strong @click="bb(index)">×</strong>
- </div>
- </div>
- </template>
- </body>
- <script>
- Vue.component('aaa', {
- template: '#b',
- data: function() {
- return {
- dd: ''
- }
- },
- watch: {
- list: {
- handler: function(keys) {
- console.log(keys);
- },
- deep: true//keys中的每个值变化都会触发handler
- }
- },
- props: ['list'],
- methods: {
- aa: function(key) {
- key.line = !key.line;
- console.log(2);
- },
- bb: function(index) {
- this.list.splice(index, 1);
- },
- cc: function() {
- this.list.push({
- a: this.dd,
- b: '无',
- line: false
- });
- this.dd = '';
- }
- },
- computed: {
- remain: function() {
- return this.list.filter(function(a) {
- return !a.line;
- }).length;
- }
- }
- });
- new Vue({
- el: '#a',
- data: {
- tasks: [
- {a: 1, b: 2, line: true},
- {a: 11, b: 22, line: false},
- {a: 111, b: 222, line: false}
- ]
- },
- methods: {
- aa: function(key) {
- key.line = !key.line;
- console.log(1);
- }
- }
- });
- </script>
- </html>
使用jquery调用接口数据:
- <body>
- <div id="a">
- <p>{{ list }}</p>
- </div>
- </body>
- <script>
- new Vue({
- el: '#a',
- data: {
- list: ''
- },
- created: function() {
- var This = this;
- $.ajax({
- url: 'http://v3.faqrobot.org/servlet/AQ?s=p&sysNum=14464304598886414&&sourceId=0×tamp=1473514741278&dataType=json',
- dataType: 'jsonp',
- success: function(data) {
- This.list = data.webConfig.helloWord;
- }
- });
- },
- });
- </script>
使用vue-resource调用接口数据:(Vue2推荐使用axios代替vue-resource)
- <body>
- <div id="a">
- <p v-show="a">加载中...</p>
- <p>{{ list }}</p>
- </div>
- </body>
- <script>
- Vue.http.interceptors.push(function(request, next) {
- this.a = !this.a;
- next(function(response) {
- this.a = !this.a;
- return response;
- });
- });
- new Vue({
- el: '#a',
- data: {
- a: false,
- list: ''
- },
- created: function() {
- this.$http.jsonp('http://v3.faqrobot.org/servlet/AQ?s=p&sysNum=14464304598886414&&sourceId=0×tamp=1473514741278&dataType=json').then(function(data) {
- this.list = data.body.webConfig.helloWord;
- });
- },
- });
- </script>
slot示例:
- <body>
- <div id="a">
- <my-b>
- <p>匿名slot1</p>
- <p>匿名slot2</p>
- <p slot="a">具名slot1</p>
- <my-c></my-c>
- </my-b>
- </div>
- <template id="b">
- <slot></slot>
- <slot></slot>
- <slot name="a"></slot>
- <p>bbb</p>
- </template>
- <template id="c">
- <p>ccc</p>
- </template>
- </body>
- <script>
- Vue.component('myB', {
- template: '#b'
- });
- Vue.component('myC', {
- template: '#c'
- });
- p = new Vue({
- el: '#a'
- });
- </script>
- <body>
- <div id="a">
- <component :is='btn'></component>
- <button @click="change">{{ btn }}</button>
- </div>
- </body>
- <script>
- new Vue({
- el: '#a',
- data: {
- btn: 'aA'
- },
- methods: {
- change: function() {
- this.btn = this.btn=='aA'?'bB':'aA';
- }
- },
- components: {
- aA: {
- template: '<p>aa</p>',
- activate: function(done) {// 加载前的回调
- setTimeout(function() {
- console.log(2);
- done();
- }, 1000);
- console.log(1);
- },
- },
- bB: {
- template: '<p>bb</p>',
- ready: function() {// 作用等同于ready
- console.log(3)
- }
- },
- }
- });
- </script>
vuex示例:
a. 简单计数
- <body>
- <div id="a">
- <p>{{ num }}</p>
- <button @click="add">add</button>
- <button @click="reduce">reduce</button>
- </div>
- </body>
- <script>
- var store = new Vuex.Store({
- state: {
- num: 0
- },
- mutations: {
- add: function(state) {
- state.num++;
- },
- reduce: function(state) {
- state.num--
- }
- }
- })
- new Vue({
- el: '#a',
- computed: {
- num: function() {
- return store.state.num;
- }
- },
- methods: {
- add: function() {
- store.commit('add');
- },
- reduce: function() {
- store.commit('reduce');
- },
- }
- })
- </script>
b. 子组件获取Vuex状态
- <body>
- <div id="a">
- 父:<span>{{ num }}</span>
- <aaa></aaa>
- </div>
- </body>
- <script>
- var store = new Vuex.Store({
- state: {
- num: 0
- }
- })
- new Vue({
- el: '#a',
- store: store,// 把store实例注入所有的子组件
- computed: {
- num: function() {
- return this.$store.state.num;// 使用this.$store即可引用
- }
- },
- components: {// 子组件
- 'aaa': {
- template: '<div>子:<span>{{ num }}</span></div>',
- computed: {
- num: function() {
- return this.$store.state.num;// 使用this.$store即可引用
- }
- }
- }
- }
- })
- </script>
c. 拓展状态Getters
- <body>
- <div id="a">
- <p @click="change">转换后:{{ num }},长度:{{ len }},点击换一换</p>
- </div>
- </body>
- <script>
- var store = new Vuex.Store({
- state: {// 原状态
- num: 'abc'
- },
- getters: {// 通过原状态拓展出来的状态 (state变化时,getters也会变化,state永远是主动方)
- numUpper: function(state) {// 转大写
- return state.num.toUpperCase();
- },
- numUpperLen: function(state, getters) {// 转大写后的字符长度(直接传getters参数可引用拓展状态中的其他状态)
- return getters.numUpper.length;
- }
- },
- mutations: {
- change: function(state) {
- state.num = 'defhi';
- }
- }
- })
- new Vue({
- el: '#a',
- computed: {
- num: function() {
- return store.getters.numUpper;
- },
- len: function() {
- return store.getters.numUpperLen;
- }
- },
- methods: {
- change: function() {
- store.commit('change');
- }
- }
- })
- </script>
- <body>
- <div id="a">
- <p @click="add1">Time Travel状态正常{{ num }}</p>
- <p @click="add2">Time Travel状态不正常{{ num }}</p>
- </div>
- </body>
- <script>
- var store = new Vuex.Store({
- state: {
- num: 0
- },
- mutations: {
- add1: function(state) {
- return state.num++;
- },
- add2: function(state) {
- setTimeout(function() {// mutations中进行异步调用,导致vue devtools记录不到此状态,Time Travel时状态不对
- return state.num++;
- }, 1000);
- }
- },
- actions: {
- add1: function(context) {
- setTimeout(function() {// actions中进行异步调用,vue devtools正确记录此状态,Time Travel时状态也正常
- context.commit('add1');
- }, 1000);
- }
- }
- })
- new Vue({
- el: '#a',
- computed: {
- num: function() {
- return store.state.num;
- }
- },
- methods: {
- add1: function() {
- return store.dispatch('add1');
- },
- add2: function() {
- return store.commit('add2');
- },
- }
- })
- </script>
- <body>
- <div id="a">
- <p @click="add">{{ num }}</p>
- </div>
- </body>
- <script>
- var store = new Vuex.Store({
- state: {
- num: 0
- },
- mutations: {
- add: function(state) {
- return state.num++;
- }
- },
- actions: {
- add: function(context) {
- return new Promise(function(resolve, reject) {
- setTimeout(function() {
- context.commit('add');
- console.log(1)
- resolve();
- }, 1000);
- })
- }
- }
- })
- new Vue({
- el: '#a',
- computed: {
- num: function() {
- return store.state.num;
- }
- },
- methods: {
- add: function() {
- return store.dispatch('add').then(function() {// 不使用Promise打印2 1,使用Promise打印1 2
- console.log(2);
- });
- }
- }
- })
- </script>
- <body>
- <div id="a">
- <p @click="add">{{ num }}</p>
- </div>
- </body>
- <script>
- var moduleA = {
- state: {
- num: 0// moduleA节点状态
- },
- mutations: {
- ['a.add']: function(state) {// a.add为命名空间
- return state.num++;
- }
- },
- actions: {
- ['a.add']: function(context) {
- context.rootState.num++;// 根节点状态改变
- return context.commit('a.add');// moduleA节点状态改变
- }
- }
- }
- var store = new Vuex.Store({
- state: {
- num: 0// 根节点状态
- },
- modules: {
- modA: moduleA
- }
- })
- new Vue({
- el: '#a',
- computed: {
- num: function() {
- return store.state.num + store.state.modA.num;// 根节点和moduleA节点状态叠加
- }
- },
- methods: {
- add: function() {
- return store.dispatch('a.add');// 触发a.add
- }
- }
- })
- </script>
- export default {
- data() {
- return {
- SC_outer_style: {
- },
- SC_inner_style: {
- height: '50px',
- background: 'red'
- }
- }
- },
- computed: {
- SC_outer_style() {
- return {
- }
- }
- },
- mounted() {
- },
- methods: {
- init() {
- }
- },
- directives: {
- handle: {
- inserted: function(el, binding, vnode) {
- if(Tool.getStyle(el, 'position') == 'static') {
- vnode.context.SC_outer_style = {
- position: 'relative'
- }
- }
- },
- }
- }
- }
vue-router示例:
a. 简单的单页应用
- <body>
- <div id="app">
- <a v-link="{path: '/home'}">home</a>
- <a v-link="{path: '/about'}">about</a>
- <router-view></router-view>
- </div>
- </body>
- <script>
- window.onload = function() {
- var Home = Vue.extend({
- template: '<p>home content</p>'
- });
- var About = Vue.extend({
- template: '<p>about content</p>'
- });
- var App = Vue.extend();
- var router = new VueRouter();
- router.map({
- '/home': {component: Home},
- '/about': {component: About}
- });
- router.redirect({// 首先展示此页面
- '/': '/about'
- })
- router.start(App, '#app');
- }
- </script>
- <body>
- <div id="app">
- <a v-link="{path: '/home'}">home</a>
- <a v-link="{path: '/about'}">about</a>
- <router-view></router-view>
- </div>
- <template id="home">
- <p>home-content</p>
- <a v-link="{path: '/home/new'}">new</a>
- <a v-link="{path: '/home/old'}">old</a>
- <router-view></router-view>
- </template>
- <template id="new">
- <p>new-content</p>
- </template>
- <template id="old">
- <p>old-content</p>
- </template>
- <template id="about">
- <p>about-content</p>
- </template>
- </body>
- <script>
- window.onload = function() {
- var Home = Vue.extend({
- template: '#home'
- });
- var New = Vue.extend({
- template: '#new'
- });
- var Old = Vue.extend({
- template: '#old'
- });
- var About = Vue.extend({
- template: '#about'
- });
- var App = Vue.extend();
- var router = new VueRouter();
- router.map({
- '/home': {
- component: Home,
- subRoutes: {// 子路由
- '/new': {component: New},
- '/old': {component: Old}
- }
- },
- '/about': {
- component: About
- }
- });
- router.redirect({// 首先展示此页面
- '/': 'about'
- })
- router.start(App, '#app');
- }
- </script>
b. 路由进阶
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>index</title>
- <style>
- * {
- margin: 0;
- padding: 0;
- }
- .v-link-active {/* 处于当前页面的含有 v-link 属性的元素自动加上 v-link-active 的 class */
- background: red;
- }
- .customClass {/* 自定义选中时的 class */
- background: blue;
- }
- </style>
- <script src="js/vue.js"></script>
- <script src="js/vue-router.js"></script>
- </head>
- <body>
- <div id="app">
- <a v-link="{path: '/home', activeClass: 'customClass'}">home</a>
- <a v-link="{path: '/about'}">about</a>
- <router-view></router-view>
- </div>
- <template id="home">
- <p @click="say">home-content(点击输出 route 对象)</p>
- <p>route 对象:{{ $route | json }}</p>
- <a v-link="{path: '/home/new'}">new</a>
- <a v-link="{path: '/home/old'}">old</a>
- <router-view></router-view>
- </template>
- <template id="new">
- <p>new-content</p>
- </template>
- <template id="old">
- <p>old-content</p>
- </template>
- <template id="about">
- <p>about-content</p>
- </template>
- </body>
- <script>
- window.onload = function() {
- var Home = Vue.extend({
- template: '#home',
- methods: {
- say: function() {
- console.log(this.$route)
- }
- },
- route: {
- data: function(transition) {// 此组件链接改变时的钩子
- console.log(transition.from.path?'从'+ transition.from.path +'到'+ transition.to.path:'初始化');
- transition.next({
- currentPath: '/about'
- })
- }
- }
- });
- var New = Vue.extend({
- template: '#new'
- });
- var Old = Vue.extend({
- template: '#old'
- });
- var About = Vue.extend({
- template: '#about'
- });
- var App = Vue.extend({
- data: function() {
- return {
- }
- }
- });
- var router = new VueRouter();
- router.map({// 映射路由
- '/home': {
- component: Home,
- subRoutes: {// 子路由
- '/new': {component: New},
- '/old': {component: Old}
- }
- },
- '/about': {
- component: About
- }
- });
- router.redirect({// 首先展示此页面
- '/': 'about'
- });
- router.beforeEach(function() {// 全局钩子
- console.log('切换前');
- });
- router.afterEach(function() {// 全局钩子
- console.log('切换后');
- });
- router.start(App, '#app');
- }
- </script>
- </html>
编写插件示例:(配合es6语法,待更新)
a. 自调用
myPlugin.js:
- import Vue from 'vue';
- ;(function () {
- var MyPlugin = {};
- MyPlugin.install = function (Vue, options) {
- Vue.directive('mySex', {
- inserted(el, binding) {
- console.log(binding.value)
- }
- })
- Vue.prototype.$sex = options.sex;
- Vue.prototype.$say = function() {
- console.log(this.$sex)
- };
- };
- Vue.use(MyPlugin, {sex: 'male'});// 这里调用后,引用该文件无需再调用
- })();
- import Vue from 'vue';
- import MyPlugin from 'js/myPlugin.js';
myPlugin.js:
- import Vue from 'vue';
- export default {
- install(Vue, options) {
- Vue.directive('mySex', {
- inserted(el, binding) {
- console.log(binding.value)
- }
- })
- Vue.prototype.$sex = 'female';
- Vue.prototype.$say = function() {
- console.log(this.$sex)
- };
- }
- }
- import Vue from 'vue';
- import MyPlugin from 'js/myPlugin.js';
- Vue.use(MyPlugin, {sex: 'male'});// 这里需要调用一次
myPlugin.vue:
- <template>
- <div class="sexClass" @click="say"><slot name="ctn">{{ sex }}</slot></div>
- </template>
- <script>
- import Vue from 'vue';
- export default {
- data: function() {
- return {
- sex: 'male'
- }
- },
- methods: {
- say: function() {
- console.log(this.sex);
- }
- }
- }
- </script>
- <style>
- .sexClass {
- background: red;
- }
- </style>
- import Vue from 'vue';
- import MyPlugin from 'components/myPlugin.vue';
- new Vue({
- el: '#app',
- components: {
- 'my-plugin': MyPlugin
- }
- })
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <title>demo</title>
- </head>
- <body>
- <div id="app">
- <my-plugin><div slot="ctn"><button>点击这里</button></div></my-plugin><!-- 在这里使用组件 -->
- </div>
- </body>
- </html>
更多推荐
已为社区贡献8条内容
所有评论(0)