参考:https://www.cnblogs.com/xiaohuochai/p/7388866.html
效果:
html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <title>js实现vue—引入子组件props传参</title> <link rel="stylesheet" href="css/1.css"> <script type="text/javascript" src="js/jquery.js"></script> <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script> <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script> <script src="js/1.js"></script> </head> <body> <div id="app"> <keep-alive> <router-view class="child-view" v-if="$route.meta.keepAlive"></router-view> </keep-alive> <router-view class="child-view" v-if="!$route.meta.keepAlive"></router-view> </div> <script type="text/x-template" id="page1"> <div> <TopNav :show-btn="ifShow"></TopNav>, <!-- 对于props声明的属性来说,在父级HTML模板中,属性名需要使用中划线写法 --> <p class="content">页面1</p> <router-link to="/page2" tag="span" class="btnRouter">页面2</router-link> <BlankPage id="BlankPage1"></BlankPage> <!-- 多个组件引入同一组件改变显示/隐藏状态时,需绑定指定id,否则多个组件会混乱 --> </div> </script> <script type="text/x-template" id="page2"> <div> <TopNav :show-btn="ifShow"></TopNav> <p class="content">页面2</p> <BlankPage id="BlankPage2"></BlankPage> </div> </script> </body> </html>
1.js:
$(document).ready(function() { Vue.prototype.$show = function(obj) { //全局函数1 var o = $(obj); o.css('display', 'block'); }; Vue.prototype.$hide = function(obj) { //全局函数2 var o = $(obj); o.css('display', 'none'); }; Vue.use(VueRouter); // 顶部组件 start var TopNav = Vue.extend({ data() { return { showBtn: false } }, props: ['showBtn'], watch: { showBtn: function(newVal, oldVal) { this.showBtn = newVal; } }, template: "<p class='title'> " + "<span>顶部组件</span>" + "<span v-show='showBtn' class='btnBack' @click='$router.back(-1)'>返回</span>" + "</p>" }) /* 子级props属性声明时,使用小驼峰或者中划线写法都可以; 而子级模板使用从父级传来的变量时,需要使用对应的小驼峰写法 */ // 顶部组件 end // 正在加载组件 start var BlankPage = Vue.extend({ template: "<div class='BlankPage'>" + "<div class='loadingDiv'>" + "<p class='loadingIcon'>" + "<img src='img/load.gif' alt=''>" + "</p>" + "<p class='loadingTxt'>正在加载...</p>" + "</div>" + "</div>" }) // 正在加载组件 end // 页面1 start var Page1 = Vue.extend({ data() { return { ifShow: false } }, template: "#page1", // 局部注册子组件 components: { TopNav, BlankPage } }) //页面1 end //页面2 start var Page2 = Vue.extend({ data() { return { ifShow: true } }, template: "#page2", components: { TopNav, BlankPage } }) //页面2 end var router = new VueRouter({ routes: [{ path: '/', name: 'Page1', meta: { index: 0, keepAlive: true, title: '页面1' }, component: Page1 }, { path: '/page2', name: 'Page2', meta: { index: 1, keepAlive: false, title: '页面2' }, component: Page2 } ] }) router.beforeEach((to, from, next) => { var toDepth = to.meta.index; var fromDepth = from.meta.index; if (to.meta.title) { document.title = to.meta.title; } if (toDepth == 'undefined' || toDepth == undefined) { if (true) { //这个可以关闭安卓系统的手机 document.addEventListener('WeixinJSBridgeReady', function() { WeixinJSBridge.call('closeWindow'); }, false); //这个可以关闭ios系统的手机 WeixinJSBridge.call('closeWindow'); // wx.closeWindow(); } return; } else if (toDepth < fromDepth) { //返回 from.meta.keepAlive = false; to.meta.keepAlive = true; } next() }) var app = new Vue({ el: '#app', router }).$mount('#app') })
1.css:
@CHARSET "UTF-8"; body { width: 100%; height: 100%; } body, div, p { margin: 0; padding: 0; text-align: center; } .content { margin-top: 200px; } .title { position: fixed; top: 0; left: 0; width: 100%; height: 60px; padding-left: 50px; line-height: .60px; display: flex; align-items: center; color: #fff; background-color: lightseagreen; z-index: 1; } .btnBack { margin-left: 50%; } .btnRouter { width: 100px; height: 30px; line-height: 30px; margin-top: 20px; display: inline-block; background-color: lightseagreen; color: #fff; border-radius: 10px; } .NoMore { font-size: 14px; color: #888; margin-top: 30px; text-align: center } #NoMore1, #NoMore2 { display: none; } .NoMoreTxt:before { content: ""; width: 100px; height: 1px; display: inline-block; margin-bottom: 5px; margin-right: 1px; background-color: #dadada; } .NoMoreTxt:after { content: ""; width: 100px; height: 1px; display: inline-block; background-color: #dadada; margin-bottom: 5px; margin-left: 10px; } #BlankPage1, #BlankPage2 { display: none; } .BlankPage { width: 100%; height: 100%; font-size: 14px; color: #fff; background-color: #fff; -webkit-transition: all .2s ease-out; transition: all .5s ease-out; transition: all .5s ease-out; transition: all .5s ease-out; position: fixed; top: 0; z-index: 12; } .loadingDiv { position: fixed; top: 45%; left: 50%; transform: translate(-50%, -50%); width: 120px; height: 50px; } .loadingTxt { font-size: 14px; color: #666; text-align: center; } .loadingIcon { text-align: center; } .loadingIcon img { display: inline-block; width: 40%; height: 48px; }