zTree应用于vue+cordova移动端
搭建vue+cordova开发环境
这里不做叙述,具体可查看我的文章:
vue+cordova移动端Android开发环境配置
应用zTree
安装ztree与jQuery
npm install vue-ztree -s
npm install jquery -s
打开vue项目中的package.json文件,在dependencies对象中可以看到jQuery与ztree都已安装成功:
zTree官网下载demo项目
demo项目地址:http://www.treejs.cn/v3/main.php#_zTreeInfo
点击上图图标直接下载demo项目即可(也可直接访问https://gitee.com/zTree/zTree_v3下载),demo项目目录如下:
添加zTree至项目
在vue项目中新建文件夹plugins(名字自己取),并在该文件夹下新建文件夹ztree
将demo项目中目录zTree_v3\js下的jquery.ztree.core.min.js文件与jquery.ztree.excheck.min.js文件拷贝的ztree文件夹中。
将zTree_v3\css\zTreeStyle目录下的zTreeStyle.css文件也拷贝到ztree文件夹中,如下图所示demo项目中的这些文件:
进入jQuery网站下载之前在vue项目中的package.json文件里dependencies对象中jQuery的对应版本,这里是3.4.1版本(其实用demo项目中的也可以,但是vue项目其他地方也会用到jQuery,所以还是下载较新的版本比较好)。
下载完成后将文件拷贝到plugins文件夹中。目前plugins中应该包含4个文件。
在项目src目录下的main.js文件中导入这3个js文件(这里要注意路径要正确):
修改app.vue文件(我这里是新建的Vue项目,如果你是在自己的项目中运用就不用修改,这步不用看):
<template>
<div>
<!--img src="./assets/logo.png"-->
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
body {
margin: 0;
padding: 0;
background-color: rgb(25,125,177) ;
}
</style>
新建tree.vue文件,该模块完整代码如下(如果是在已有项目中可直接引用该文件或添加路由):
<template>
<div class="area">
<div class="title-text">zTree树形控件测试</div>
<div class="flash">
<a href="#" style="text-decoration:none;color: #ffffff;">刷新<img src="../assets/refresh.png"
style="line-height:0.5rem;width: 0.4rem;height: 0.4rem;color: #ffffff;display: inherit;padding-left: 0.1rem"
@click="freshArea"/></a>
</div>
<div class="main-box">
<ul id="treeDemo" class="ztree"></ul>
</div>
</div>
</template>
<script>
// 下面的是单个Vue组件引用的外部静态文件,也可以在main.js文件中引用
import $ from "jquery"
export default {
name: 'areaTree',
components: {},
data: function () {
return {
newurl: '',
setting: {
check: {
enable: false, //设置不显示checkbox
nocheckInherit: false, //新加入子节点时,不继承父节点 nocheck 的属性
//chkboxType: { "Y": "p", "N": "s" }
},
data: {
//简单格式数据
simpleData: {
enable: true,
idKey: "id",
pIdKey: "pId",
}
},
view: {
dblClickExpand: false, //关闭双击展开
expandSpeed: "fast", //展开速度:"slow", "normal", or "fast"
showIcon: true, //显示节点图标
showLine: true, //显示节点间的连线
selectedMulti: false, //是否允许同时选中多个节点
nameIsHTML: true, //设置name属性支持HTML脚本
fontCss: this.setFontCSS, //设置节点个性化
},
callback: {
beforeAsync: false, //是否允许异步加载
//beforeClick: this.beforeClick,
onClick: this.zTreeOnClick, //点击事件
//onCheck: this.zTreeOnCheck,
}
},
zNodes: [
//从根节点开始
{
id: 1,
pid: 0,
"name": "<div class=\"item-content-home\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">网站选择</span>\n" +
" </div>",
open: true,
nocheck: false,
children: [
{
id: 11,
pid: 1,
"name": "<div class=\"item-content1\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">搜索</span>\n" +
" </div>",
open: false,
children: [
{
id: 111,
pid: 11,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">百度</span>\n" +
" </div>"
},
{
id: 112,
pid: 11,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">搜狗</span>\n" +
" </div>"
}
]
},
{
id: 12,
pid: 1,
"name": "<div class=\"item-content1\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">购物</span>\n" +
" </div>",
open: false,
children: [
{
id: 121,
pid: 12,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">淘宝</span>\n" +
" </div>"
},
{
id: 122,
pid: 12,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">京东</span>\n" +
" </div>"
},
{
id: 1211,
pid: 12,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">苏宁易购</span>\n" +
" </div>"
}
]
},
{
id: 13,
pid: 1,
"name": "<div class=\"item-content1\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">社区学习</span>\n" +
" </div>",
open: false,
children: [
{
id: 131,
pid: 13,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">CSDN</span>\n" +
" </div>"
},
{
id: 132,
pid: 13,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">简书</span>\n" +
" </div>"
},
{
id: 1314,
pid: 13,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">博客园</span>\n" +
" </div>"
}
]
},
{
id: 14,
pid: 1,
"name": "<div class=\"item-content1\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">新闻</span>\n" +
" </div>",
open: false,
children: [
{
id: 141,
pid: 14,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">新浪微博</span>\n" +
" </div>"
},
{
id: 142,
pid: 14,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">腾讯新闻</span>\n" +
" </div>"
},
{
id: 145,
pid: 14,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">网易新闻</span>\n" +
" </div>"
}
]
},
{
id: 15,
pid: 1,
"name": "<div class=\"item-content1\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">音乐</span>\n" +
" </div>",
open: false,
children: [
{
id: 1517,
pid: 15,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">QQ音乐</span>\n" +
" </div>"
},
{
id: 1518,
pid: 15,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">网易云音乐</span>\n" +
" </div>"
},
{
id: 1519,
pid: 15,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">酷狗音乐</span>\n" +
" </div>"
}
]
},
{
id: 16,
pid: 1,
"name": "<div class=\"item-content1\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">电影</span>\n" +
" </div>",
open: false,
children: [
{
id: 165,
pid: 16,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">腾讯视频</span>\n" +
" </div>"
},
{
id: 166,
pid: 16,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">优酷土豆</span>\n" +
" </div>"
}
]
},
{
id: 16,
pid: 1,
"name": "<div class=\"item-content1\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">游戏</span>\n" +
" </div>",
open: false,
children: [
{
id: 165,
pid: 16,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">英雄联盟</span>\n" +
" </div>"
},
{
id: 166,
pid: 16,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">穿越火线</span>\n" +
" </div>"
},
{
id: 166,
pid: 16,
"name": "<div class=\"item-content2\"><span style=\"color: white;display: block;padding-left: 0.3rem;padding-top: 0.09rem;\">地下城与勇士</span>\n" +
" </div>"
}
]
}
]
}
]
}
},
methods: {
//刷新树结构
freshArea: function () {
$.fn.zTree.init($("#treeDemo"), this.setting, this.zNodes);
},
//点击树节点时展开其子节点
zTreeOnClick: function (event, treeId, treeNode) {
let zTree = $.fn.zTree.getZTreeObj("treeDemo");
if (treeNode.name == "百度") {
this.newurl = "https://www.baidu.com"
//this.openBrowser();
} else if (treeNode.name == "搜狗") {
this.newurl = "https://www.sogou.com/"
// this.openBrowser();
} else if (treeNode.name == "淘宝") {
this.newurl = "https://www.taobao.com/"
//this.openBrowser();
} else if (treeNode.name == "京东") {
this.newurl = "https://www.jd.com/"
// this.openBrowser();
} else if (treeNode.name == "苏宁易购") {
this.newurl = "https://www.suning.com/"
//this.openBrowser();
} else if (treeNode.name == "CSDN") {
this.newurl = "https://www.csdn.net/"
//this.openBrowser();
} else if (treeNode.name == "简书") {
this.newurl = "https://www.jianshu.com/"
//this.openBrowser();
} else if (treeNode.name == "博客园") {
this.newurl = "https://www.cnblogs.com/"
//this.openBrowser();
} else if (treeNode.name == "新浪微博") {
this.newurl = "https://weibo.com/"
//this.openBrowser();
} else if (treeNode.name == "腾讯新闻") {
this.newurl = "https://news.qq.com/"
//this.openBrowser();
} else if (treeNode.name == "网易新闻") {
this.newurl = "https://news.163.com/"
//this.openBrowser();
} else if (treeNode.name == "QQ音乐") {
this.newurl = "https://y.qq.com/"
// this.openBrowser();
} else if (treeNode.name == "网易云音乐") {
this.newurl = "https://music.163.com/"
//this.openBrowser();
} else if (treeNode.name == "酷狗音乐") {
this.newurl = "http://www.kugou.com/"
//this.openBrowser();
} else if (treeNode.name == "腾讯视频") {
this.newurl = "https://v.qq.com/"
//this.openBrowser();
} else if (treeNode.name == "优酷土豆") {
this.newurl = "https://www.youku.com/"
//this.openBrowser();
} else {
zTree.expandNode(treeNode);
}
//alert(treeId);
//alert(treeNode.tId + ", " + treeNode.name);
},
zTreeOnCheck: function (event, treeId, treeNode) {
console.log(treeNode.tId + ", " + treeNode.name + "," + treeNode.checked);
let zTree = $.fn.zTree.getZTreeObj("treeDemo"),
checkCount = zTree.getCheckedNodes(true).length,//选中
nocheckCount = zTree.getCheckedNodes(false).length,//未选中
changeCount = zTree.getChangeCheckedNodes().length;//获取输入框勾选状态被改变的节点集合(与原始数据 checkedOld 对比)
let checkedNames = [], checkedIds = [];
for (let i = 0; i <= zTree.getCheckedNodes(true).length - 1; i++) {
checkedIds.push(zTree.getCheckedNodes(true)[i].id);
checkedNames.push(zTree.getCheckedNodes(true)[i].name);
}
;
console.log(checkedIds);
console.log(checkedNames);
},
beforeClick: function (treeId, treeNode) {
let zTree = $.fn.zTree.getZTreeObj("treeDemo");
// zTree.checkNode(treeNode, !treeNode.checked, null, true);
zTree.checkNode(treeNode, !treeNode.checked, true, true); //第二个参数!treeNode.checked和"",省略此参数效果等同,则根据对此节点的勾选状态进行 toggle 切换,第三个参数设置为true时候进行父子节点的勾选联动操作 ,第四个参数true 表示执行此方法时触发 beforeCheck & onCheck 事件回调函数;false 表示执行此方法时不触发事件回调函数
return false;
},
setFontCSS: function () {
if (this.zNodes[0].pid == 0)
return {color: "white", "font-size": "20px"};
},
openBrowser: function () {
let target = '_blank';
let options = "location=yes"
let ref = cordova.InAppBrowser.open(this.newurl, target, options);
ref.addEventListener('loadstart', loadstartCallback);
ref.addEventListener('loadstop', loadstopCallback);
ref.addEventListener('loadloaderror', loaderrorCallback);
ref.addEventListener('exit', exitCallback);
function loadstartCallback(event) {
console.log('Loading started: ' + event.url)
}
function loadstopCallback(event) {
console.log('Loading finished: ' + event.url)
}
function loaderrorCallback(error) {
console.log('Loading error: ' + error.message)
}
function exitCallback() {
console.log('Browser is closed...')
}
},
},
mounted() {
$.fn.zTree.init($("#treeDemo"), this.setting, this.zNodes).expandAll(true);
}
}
</script>
<style type="text/css">
/*@import '../../plugins/zTreeStyle.css';*/
.area {
margin-top: 0;
}
.title-text {
/*将该标签固定在屏幕顶部*/
position: fixed;
top: 0;
text-align: center;
font-size: 0.6rem;
display: block;
width: 100%;
line-height: 0.8rem;
background: rgb(25, 125, 177);
color: #ffffff;
border-bottom: 1px solid #e5e5e5;
}
.main-box {
/*position: relative;
//top: 0.4rem;*/
margin-top: -1rem;
border: 0;
padding: 0;
/*position: absolute;*/
overflow-y: auto;
}
.item-content-home {
/*height: 0.7rem;
line-height: 0.7rem;
padding-left: 0.52rem;*/
background: url(../assets/1_open.png) no-repeat left center;
}
.item-content1 {
/*height: 0.7rem;
line-height: 0.7rem;
padding-left: 0.52rem;*/
background: url(../assets/6.png) no-repeat left center;
}
.item-content2 {
/*height: 0.7rem;
line-height: 0.7rem;
padding-left: 0.52rem;*/
background: url(../assets/8.png) no-repeat left center;
}
.flash {
color: #ffffff;
margin-top: 0.8rem;
margin-bottom: 0;
font-size: 0.3rem;
line-height: 0.6rem;
height: 0.6rem;
display: block;
/*margin-left: 0.3rem;*/
/*position:relative;
top: 0.8rem;*/
}
/*设置ztree所有字体*/
.ztree * {
padding: 0;
margin: 0;
font-size: 0.3rem;
font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif
}
.ztree li {
padding: 0 0 0 0;
margin: 0.1rem;
list-style: none;
line-height: 0.26rem;
text-align: left;
white-space: nowrap;
outline: 0
}
.ztree ul {
margin: 0;
padding: 0 0 0 0
}
.ztree li a {
padding: 0 0 0 0;
margin: 0;
cursor: pointer;
height: 0.26rem;
color: #333;
background-color: transparent;
text-decoration: none;
vertical-align: top;
display: inline-block
}
.ztree li a.curSelectedNode {
padding-top: 0px;
background-color: #1E90FF;
color: black;
height: 0.4rem;
width: 100%;
opacity: 0.8;
}
</style>
最后面的CSS设置使用了自己的配置,所以没有导入zTreeStyle.css文件,需要的话按照路径在style标签最开始导入:
@import '../../plugins/zTreeStyle.css';
同时,使用的单位是rem,因为做移动端涉及到屏幕适配,这个以后再讲。
里面有些函数用不到就给注释掉了,代码有点冗余,openBrowser()是cordova的浏览器插件中的函数,设置的点击之后转到指定网页,这里也给注释掉了,需要使用的话放开即可,不过需要先安装内置浏览器插件。
给模块添加路由,修改router文件夹里面index.js:
import Vue from 'vue'
import Router from 'vue-router'
import zTree from '@/components/zTree'
Vue.use(Router)
export default new Router({
//路由表
routes: [
{ path: '/',
name: 'zTree',
component: zTree,
}
]
})
然后运行vue+cordova项目即可,这里放上一张手机效果图: