前端最终规范


文件目录组件

<pre><code class="language-markdown">treeContainer/index &lt;template&gt; &lt;div style="border:1px solid #ccc;padding:0 20px;" v-if="show"&gt; 树形 &lt;hr /&gt; &lt;treeItem :arr="data" /&gt; &lt;/div&gt; &lt;/template&gt; &lt;script&gt; import treeItem from "./tree-item"; export default { name: "", props: { show: { type: Boolean, default: false, }, }, components: { treeItem }, watch: { show: { handler(val, oldVal) { console.log(oldVal); if (!val) { this.data = this.takeup(this.data); } }, deep: true, //true 深度监听 }, }, data() { return { data: [ { label: "一级 1", flag: false, children: [ { label: "二级 1-1", flag: false, children: [ { label: "三级 1-1-1", }, ], }, ], }, { label: "一级 2", flag: false, children: [ { label: "二级 2-1", flag: false, children: [ { label: "三级 2-1-1", }, ], }, { label: "二级 2-2", flag: false, children: [ { label: "三级 2-2-1", }, ], }, ], }, { label: "一级 3", flag: false, children: [ { label: "二级 3-1", flag: false, children: [ { label: "三级 3-1-1", }, ], }, { label: "二级 3-2", flag: false, children: [ { label: "三级 3-2-1", }, ], }, ], }, ], defaultProps: { children: "children", label: "label", }, }; }, computed: {}, created() {}, mounted() {}, beforeDestroy() {}, methods: { takeup(arr) { return arr.map((item) =&gt; { item.flag = false; if (item.children) this.takeup(item.children); return item; }); }, }, }; &lt;/script&gt; &lt;style&gt; &lt;/style&gt;</code></pre> <pre><code class="language-markdown"> treeContainer/tree-item.vue &lt;template&gt; &lt;div style="width:400px;"&gt; &lt;div v-for="(item,index) in arr" :key="index" class="tree-div"&gt; &lt;i @click="tagClick(item)" class="pointer" :class="[item.children ? (item.flag ? 'el-icon-folder-opened': 'el-icon-folder') : 'el-icon-tickets']"&gt;&lt;/i&gt;&lt;span style="margin-left:12px"&gt;{{item.label}}&lt;/span&gt; &lt;template&gt; &lt;treeItem v-if="item.children &amp;&amp; item.flag" :arr="item.children" class="subItem"/&gt; &lt;/template&gt; &lt;/div&gt; &lt;/div&gt; &lt;/template&gt; &lt;script&gt; export default { name: "treeItem", props:{ arr:{ type:Array, default:()=&gt;{ return [] } } }, computed: {}, watch: {}, created() {}, mounted() {}, beforeDestroy() {}, methods: { tagClick(item){ this.$set(item,'flag',!item.flag) } }, }; &lt;/script&gt; &lt;style&gt; .tree-div{ line-height: 30px; } span{ cursor: pointer; } .pointer{ cursor: pointer; } span + .subItem{ padding-left: 15px; } &lt;/style&gt;</code></pre> <pre><code class="language-markdown"> treeContainer/vueClickOutSize.js const clickOutside = { // 初始化指令 bind(el, binding, vnode) { console.log(vnode) function clickHandler(e) { // 这里判断点击的元素是否是本身,是本身,则返回 if (el.contains(e.target)) { return false; } console.log(binding) // 判断指令中是否绑定了函数 if (binding.expression) { // 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法 binding.value(e); } } // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听 el.__vueClickOutside__ = clickHandler; document.addEventListener("click", clickHandler); }, unbind(el, binding) { console.log(binding) // 解除事件监听 document.removeEventListener("click", el.__vueClickOutside__); delete el.__vueClickOutside__; // 删除属性 } }; export default clickOutside</code></pre> <pre><code class="language-markdown"> views/b.vue &lt;template&gt; &lt;div style="width:500px" v-clickOutside="hideTree"&gt; &lt;div style="height:30px;border:1px solid #ccc;" @click="toggerShow"&gt; {{select}} &lt;/div&gt; &lt;treeContainer :show="show"/&gt; &lt;/div&gt; &lt;/template&gt; &lt;script&gt; import treeContainer from './treeContainer' import clickOutside from "./treeContainer/vueClickOutSize"; export default { name:'', components: {treeContainer}, data(){ return { select:null, show:false } }, directives: { clickOutside }, computed: {}, watch:{}, created(){}, mounted(){}, beforeDestroy() {}, methods: { hideTree(){ this.show=false }, toggerShow(){ // this.show=!this.show; this.show=true; } } } &lt;/script&gt; &lt;style&gt; &lt;/style&gt;</code></pre>

页面列表

ITEM_HTML